Files
geointel/deploy/unraid
Codex dacdcfe64d
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled
Allow long AI QA proxy requests
2026-07-09 14:09:40 +02:00
..
2026-07-06 20:59:03 +02:00

GeoIntel Unraid all-in-one container

GeoIntel can run on Unraid as one DockerMan-native container.

Inside that single container:

  • embedded PostGIS stores the application database
  • Alembic migrations run at startup
  • FastAPI runs on internal 127.0.0.1:8000
  • nginx serves the React/MapLibre frontend on container port 80
  • nginx proxies /api and /health to the internal backend

The browser entrypoint is:

http://<unraid-ip>:${GEOINTEL_FRONTEND_PORT}

The app icons are served from the same container:

http://<unraid-ip>:${GEOINTEL_FRONTEND_PORT}/geointel-icon.svg
http://<unraid-ip>:${GEOINTEL_FRONTEND_PORT}/geointel-icon.png

Files

  • docker-compose.unraid.yml: config validation reference for the all-in-one image.
  • deploy/unraid/Dockerfile.all-in-one: builds the single container.
  • deploy/unraid/all-in-one-start.sh: starts embedded PostGIS, backend and nginx.
  • deploy/unraid/run-dockerman-container.sh: starts/replaces the running container with DockerMan labels and editable Unraid metadata.
  • deploy/unraid/nginx-all-in-one.conf: frontend and API proxy config for one container.
  • deploy/unraid/geointel.env.example: copy to .env and edit ports/paths.
  • deploy/unraid/geointel-unraid-template.xml: Unraid/DockerMan metadata for editable fields.
  • deploy/unraid/geointel-icon.svg: frontend favicon source.
  • deploy/unraid/geointel-icon.png: DockerMan/Unraid icon source.
  • frontend/public/geointel-icon.svg: frontend-served SVG icon.
  • frontend/public/geointel-icon.png: frontend-served PNG icon.

The Tower deploy scripts also copy the editable DockerMan template to:

/boot/config/plugins/dockerMan/templates-user/my-geointel.xml

and copy the PNG icon to:

/boot/config/plugins/dockerMan/images/geointel-icon.png

The template name is geointel so it matches the running all-in-one container name. If the Unraid Docker page was already open, refresh it after deploy so DockerMan reloads the template/icon metadata.

docker-compose.unraid.yml also applies DockerMan labels to the running container:

net.unraid.docker.managed=dockerman
net.unraid.docker.webui=http://[IP]:[PORT:80]/
net.unraid.docker.icon=/boot/config/plugins/dockerMan/images/geointel-icon.png

These labels are required because a plain Compose container can run correctly while still missing the normal Unraid edit/icon controls.

First setup from the repo

From the Unraid shell:

cd /mnt/user/appdata
git clone gitea-widefrog:NuklearRabbit/geointel.git geointel
cd /mnt/user/appdata/geointel
cp deploy/unraid/geointel.env.example .env
nano .env
docker compose -f docker-compose.unraid.yml config
docker build --build-arg GEOINTEL_INSTALL_AI=${GEOINTEL_INSTALL_AI:-false} -f deploy/unraid/Dockerfile.all-in-one -t geointel-all-in-one:latest .
bash deploy/unraid/run-dockerman-container.sh

The repository deploy scripts run the same flow automatically. They validate the Compose reference, build the image with the GEOINTEL_INSTALL_AI build arg, install the DockerMan template/icon, remove any old Compose-owned geointel container, preserve/migrate the PostGIS data path and start the final container with DockerMan labels.

Database credentials are runtime configuration, not image metadata. The all-in-one image does not bake GEOINTEL_POSTGRES_PASSWORD into the Dockerfile; set it through .env, the Unraid template or docker run -e.

AI dependencies are opt-in. Leave GEOINTEL_INSTALL_AI=false for the default GIS-only image. Set GEOINTEL_INSTALL_AI=true, mount models through GEOINTEL_MODELS_PATH and configure YOLO_ENABLED=true plus YOLO_MODELS_DIR=/app/models and YOLO_MODEL_PATH=/app/models/<model>.pt only when you have a local model file. The AI-enabled image installs PyTorch/Ultralytics plus the native OpenCV runtime libraries needed for Ultralytics imports; it still never downloads model weights. YOLO_CONFIG_DIR defaults to /app/storage/ultralytics, a writable persistent path, so Ultralytics settings do not fall back to root user config directories.

To safely configure an existing local YOLO model on Tower, place one supported model file (.pt, .onnx or .engine) under:

/mnt/user/appdata/geointel/models

Then run a dry-run first:

cd /mnt/user/appdata/geointel
python scripts/configure_yolo_model.py \
  --models-dir /mnt/user/appdata/geointel/models \
  --env-file .env

Apply only after the selected host and container paths are correct:

python scripts/configure_yolo_model.py \
  --models-dir /mnt/user/appdata/geointel/models \
  --env-file .env \
  --apply
bash deploy/unraid/run-dockerman-container.sh

If multiple model files are present, add --model-file /mnt/user/appdata/geointel/models/<name>.pt. The helper does not download weights, does not load a model and does not run inference; it only updates the env file for the mounted local model.

Validate:

curl -fsS "http://192.168.10.150:${GEOINTEL_FRONTEND_PORT:-1202}/health"
curl -fsS "http://192.168.10.150:${GEOINTEL_FRONTEND_PORT:-1202}/api/v1/projects"
curl -I "http://192.168.10.150:${GEOINTEL_FRONTEND_PORT:-1202}/geointel-icon.svg"
curl -I "http://192.168.10.150:${GEOINTEL_FRONTEND_PORT:-1202}/geointel-icon.png"

The live migration smoke also checks PostgreSQL database collation metadata. When reusing a PostGIS volume created by an older Debian/glibc runtime, it may print COLLATION_VERSION_MISMATCH. This is a maintenance warning, not an app startup failure. Review backups first, then acknowledge the new runtime collation version inside the running container:

docker exec -it geointel psql -U "${GEOINTEL_POSTGRES_USER:-geointel}" -d "${GEOINTEL_POSTGRES_DB:-geointel}"
ALTER DATABASE "geointel" REFRESH COLLATION VERSION;

If you rely on text indexes with locale-specific ordering, plan a maintenance window and rebuild the affected indexes before acknowledging the version. The current GeoIntel V1 spatial workflows primarily use UUIDs, JSON metadata and PostGIS geometry indexes, but the warning should still be tracked explicitly.

Change the browser port

Edit .env:

GEOINTEL_FRONTEND_PORT=1203
GEOINTEL_CORS_ORIGINS=http://localhost:1203,http://127.0.0.1:1203,http://192.168.10.150:1203

Apply:

docker build --build-arg GEOINTEL_INSTALL_AI=${GEOINTEL_INSTALL_AI:-false} -f deploy/unraid/Dockerfile.all-in-one -t geointel-all-in-one:latest .
bash deploy/unraid/run-dockerman-container.sh

Persistent paths

Recommended Unraid paths:

GEOINTEL_STORAGE_PATH=/mnt/user/appdata/geointel/storage
GEOINTEL_POSTGIS_DATA_PATH=/mnt/user/appdata/geointel/postgres-data

GEOINTEL_STORAGE_PATH contains uploads, tiles, masks, reports and exports.

GEOINTEL_POSTGIS_DATA_PATH contains the embedded PostGIS database files.

Update from Gitea

cd /mnt/user/appdata/geointel
git fetch origin main
git reset --hard origin/main
docker build --build-arg GEOINTEL_INSTALL_AI=${GEOINTEL_INSTALL_AI:-false} -f deploy/unraid/Dockerfile.all-in-one -t geointel-all-in-one:latest .
bash deploy/unraid/run-dockerman-container.sh

Safe cleanup

Safe cache cleanup if Docker build cache fills the Unraid Docker image:

docker builder prune -af

Avoid broad volume pruning unless you explicitly intend to remove persisted PostGIS data or GeoIntel artifacts.

Multi-container development stack

The root docker-compose.yml remains available for development and CI-like validation with separate db, backend and frontend services. For Unraid app-style operation, prefer docker-compose.unraid.yml.