get lifecycle out of data

This commit is contained in:
legop3
2026-09-15 15:00:22 -04:00
parent 7539898f98
commit 8b5d7372f9
3 changed files with 6 additions and 3 deletions
-1
View File
@@ -44,7 +44,6 @@ services:
environment:
MULTIROVER_TARGET_IMAGE: *multirover-image
volumes:
- data:/data
- lifecycle-socket:/run/multirover
# Do not add this Docker socket mount to the server service.
- /var/run/docker.sock:/var/run/docker.sock
+1 -1
View File
@@ -695,7 +695,7 @@ Implemented on 2026-09-15:
- Reused the single published application image for the lifecycle service with a controller-only command. This avoids a second Dockerfile, image name, GHCR workflow, and release lifecycle while the two containers still run separate processes with separate privileges.
- Mounted `/var/run/docker.sock` only in the network-disabled lifecycle container. The application communicates through a dedicated Unix-socket volume and cannot submit an image name, container name, command, or Docker option; the controller operates only on the fixed `multirover` container and the deployment-selected MultiRover image.
- Added fixed status, update-check, restart, and update operations. Update checks pull the configured moving image and compare Docker image IDs. Updates retain the previous image ID, recreate the application with its existing Compose host contract, wait for the image health check, and restore the previous image when replacement health fails.
- Persisted the current operation and result under `data/runtime/container-lifecycle`. This survives ordinary application replacement and browser reconnection but remains excluded from full backups as disposable controller state.
- Persisted the current operation and result in the private lifecycle Unix-socket volume. This survives ordinary application replacement and browser reconnection without mounting the root lifecycle controller into the application's `/data` volume, leaving all application runtime paths owned by the non-root server.
- Connected the existing lockdown-administrator password confirmation and audit history to the lifecycle operations. The Administration overview polls persisted progress, reports update and rollback results, and keeps the legacy process-level restart only when no controller socket exists.
- Defined the deployment image once through a Compose YAML anchor. Both services and the controller target reuse that exact value, so production stays on `ghcr.io/legop3/multiroombarover:latest` and development requires changing only the single visible selector line to a branch tag.
@@ -10,7 +10,11 @@ const docker = new Docker({ socketPath: '/var/run/docker.sock' });
const TARGET_CONTAINER_NAME = 'multirover';
const TARGET_IMAGE = process.env.MULTIROVER_TARGET_IMAGE || 'ghcr.io/legop3/multiroombarover:latest';
const SOCKET_PATH = process.env.MULTIROVER_LIFECYCLE_SOCKET || '/run/multirover/lifecycle.sock';
const STATUS_PATH = process.env.MULTIROVER_LIFECYCLE_STATUS || '/data/runtime/container-lifecycle/status.json';
// Status belongs beside the controller's private socket instead of in the
// application's data volume. The controller runs as root for Docker access;
// keeping it out of /data prevents it from creating directories that the
// non-root application cannot later use for replay and audio runtime work.
const STATUS_PATH = process.env.MULTIROVER_LIFECYCLE_STATUS || '/run/multirover/status.json';
const HEALTH_TIMEOUT_MS = 2 * 60 * 1000;
const HEALTH_POLL_MS = 1000;