fix(release): make deployment backup and rollback immutable
This commit is contained in:
+30
-22
@@ -106,27 +106,25 @@ customer or operational data. Deploy a separate demo container and storage
|
||||
root for public or recruiter-facing access.
|
||||
|
||||
The repository deploy scripts run the same flow automatically. They validate
|
||||
the Compose reference, preserve the current image as
|
||||
`geointel-all-in-one:previous`, build an immutable `<commit-sha>-ai` or
|
||||
`<commit-sha>-gis` tag plus `latest`, install the DockerMan metadata and start
|
||||
the immutable image. An existing matching tag is reused, never rebuilt. A
|
||||
failed start, live migration smoke or browser/API smoke automatically attempts
|
||||
the previous image without changing the configured PostGIS or storage paths.
|
||||
the Compose reference, preserve the current image under a unique
|
||||
backup-specific `rollback-predeploy-*` tag, build the immutable production
|
||||
`<commit-sha>-ai` tag plus `latest`, attest its exact local image ID, generate
|
||||
an SBOM and enforce the Trivy policy before starting that same ID. An existing
|
||||
matching tag is reused, never rebuilt. A failed start, live migration smoke or
|
||||
browser/API smoke automatically attempts the previous image without changing
|
||||
the configured PostGIS or storage paths.
|
||||
|
||||
`scripts/deploy_tower.sh` and `scripts/deploy_tower.ps1` source the remote
|
||||
`.env` before building the image. That means `GEOINTEL_INSTALL_AI=true` in
|
||||
`/mnt/user/appdata/geointel/.env` is enough for the automatic deploy to build
|
||||
the AI-enabled image. Set `GEOINTEL_INSTALL_AI` in the local shell or pass
|
||||
`-InstallAi true/false` to the PowerShell wrapper only when you intentionally
|
||||
want to override the remote `.env` for that deploy.
|
||||
`.env` before building the image. Production deployment requires
|
||||
`GEOINTEL_INSTALL_AI=true`; an explicit false value fails closed before the
|
||||
image or running container is replaced.
|
||||
|
||||
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
|
||||
Production images always include the pinned AI dependencies. 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
|
||||
@@ -264,7 +262,8 @@ git reset --hard origin/main
|
||||
bash deploy/unraid/deploy-release.sh
|
||||
```
|
||||
|
||||
The equivalent low-level build remains available for debugging:
|
||||
The equivalent low-level GIS-only build remains available only for local
|
||||
debugging; it is not a production deployment path:
|
||||
|
||||
```bash
|
||||
docker build --build-arg GEOINTEL_INSTALL_AI=${GEOINTEL_INSTALL_AI:-false} -f deploy/unraid/Dockerfile.all-in-one -t geointel-all-in-one:latest .
|
||||
@@ -305,20 +304,27 @@ bash scripts/verify_release_upgrade_smoke.sh \
|
||||
Return to the image that was active immediately before the latest deployment:
|
||||
|
||||
```bash
|
||||
bash deploy/unraid/rollback-dockerman-container.sh
|
||||
bash deploy/unraid/rollback-dockerman-container.sh \
|
||||
--backup-dir /mnt/user/appdata/geointel/backups/<predeploy-release-id> \
|
||||
--confirm-production-database-restore
|
||||
```
|
||||
|
||||
For an older retained commit, select its immutable tag explicitly:
|
||||
|
||||
```bash
|
||||
GEOINTEL_ROLLBACK_IMAGE=geointel-all-in-one:<commit-sha>-ai \
|
||||
bash deploy/unraid/rollback-dockerman-container.sh
|
||||
bash deploy/unraid/rollback-dockerman-container.sh \
|
||||
--backup-dir /mnt/user/appdata/geointel/backups/<matching-predeploy-release-id> \
|
||||
--confirm-production-database-restore
|
||||
```
|
||||
|
||||
Rollback reuses the configured PostGIS and storage mounts and never runs an
|
||||
Alembic downgrade. If a future release has a backward-incompatible migration,
|
||||
restore its verified pre-release backup instead of forcing an older app
|
||||
against a newer schema.
|
||||
Rollback restores and verifies the selected dump in an isolated proof database
|
||||
before any production replacement. It then swaps database names, retains the
|
||||
pre-restore production database for operator recovery, reuses the configured
|
||||
storage mount and never runs an Alembic downgrade or an older app against an
|
||||
unknown newer schema. Remove the retained recovery database and old backup
|
||||
directories only in a separately reviewed operator retention step; deployment
|
||||
never deletes them automatically.
|
||||
|
||||
The configured upload limit is shared by FastAPI and the generated nginx
|
||||
runtime configuration. Values outside `1..2048` MiB are rejected before the
|
||||
@@ -339,7 +345,9 @@ docker exec geointel python /app/scripts/cleanup_storage_artifacts.py
|
||||
```
|
||||
|
||||
The full backup, confirmation, candidate-limit and apply sequence is in
|
||||
`docs/DATA_OPERATIONS_RUNBOOK.md`. GeoIntel installs no automatic cleanup
|
||||
`docs/DATA_OPERATIONS_RUNBOOK.md`. Apply moves bytes to protected,
|
||||
checksum-bound quarantine rather than deleting them; a separate confirmed
|
||||
restore command reverses the move. GeoIntel installs no automatic cleanup
|
||||
schedule.
|
||||
|
||||
## Safe cleanup
|
||||
|
||||
Reference in New Issue
Block a user