smallify the compose yaml

This commit is contained in:
legop3
2026-09-15 13:14:42 -04:00
parent 55ee6e05bb
commit 3b585b06b4
+6 -46
View File
@@ -1,12 +1,7 @@
# MultiRover production deployment # MultiRover production deployment
#
# The public application and private lifecycle controller reuse one published
# image. Only the lifecycle service receives Docker control; the application
# retains the narrower hardware access it needs at runtime.
name: multirover name: multirover
# This is the deployment's single image selector. Production leaves it on # Change this one line to use a development branch image.
# latest; a development deployment can change this one line to its branch tag.
x-multirover-image: &multirover-image ghcr.io/legop3/multiroombarover:latest x-multirover-image: &multirover-image ghcr.io/legop3/multiroombarover:latest
services: services:
@@ -14,84 +9,49 @@ services:
image: *multirover-image image: *multirover-image
container_name: multirover container_name: multirover
# Host networking preserves the server's existing LAN behavior and avoids
# maintaining a second list of TCP, UDP, RTSP, and WebRTC port mappings.
network_mode: host network_mode: host
restart: unless-stopped restart: unless-stopped
stop_grace_period: 20s stop_grace_period: 20s
# SELinux cannot safely relabel the host's system D-Bus socket, and the
# hardware services also need host-owned USB device nodes. Disable Docker's
# per-container SELinux label while retaining its namespace, capability,
# non-root-user, and seccomp isolation. This is narrower than privileged
# mode and avoids changing labels on shared host resources.
security_opt: security_opt:
- label=disable - label=disable
volumes: volumes:
# Docker owns the volume and initializes it from the image's non-root # All persistent application data is stored in this volume.
# /data directory. This avoids coupling container permissions to a host
# account's numeric UID while keeping every persistent file together.
- data:/data - data:/data
# The application can ask the private controller for one of its fixed
# lifecycle operations, but it never receives the Docker socket itself.
- lifecycle-socket:/run/multirover - lifecycle-socket:/run/multirover
# Required for Bluetooth hardware such as the Balance Board.
# bluetoothctl talks to the host Bluetooth daemon over this socket. The
# socket is read-only as a filesystem mount; D-Bus method calls still flow
# through it normally without exposing the rest of the host D-Bus tree.
- /run/dbus/system_bus_socket:/run/dbus/system_bus_socket:ro - /run/dbus/system_bus_socket:/run/dbus/system_bus_socket:ro
# Kinect USB node numbers change when it reconnects, so expose the bus # Required for Kinect USB access.
# directory rather than one temporary device path. The existing host udev
# rule remains responsible for granting the non-root container user access.
devices: devices:
- /dev/bus/usb:/dev/bus/usb - /dev/bus/usb:/dev/bus/usb
# Only the Balance Board worker receives this capability through its file
# capabilities. The Node process remains non-root and the container is not
# privileged.
cap_add: cap_add:
- NET_ADMIN - NET_ADMIN
lifecycle: lifecycle:
# Reuse the application image and override only its command. This keeps
# GHCR publishing and host deployment limited to one image and one Compose
# file while the Docker-authorized process remains isolated from the app.
image: *multirover-image image: *multirover-image
container_name: multirover-lifecycle container_name: multirover-lifecycle
command: ["node", "src/services/serverControlService/controller.js"] command: ["node", "src/services/serverControlService/controller.js"]
user: root user: root
network_mode: none network_mode: none
restart: unless-stopped restart: unless-stopped
# The shared image's health check targets the application HTTP server. This
# controller intentionally has no TCP listener, so it must not inherit it.
healthcheck: healthcheck:
disable: true disable: true
security_opt: security_opt:
- label=disable - label=disable
environment: environment:
# Requests cannot override this deployment-owned target. Reusing the
# anchor guarantees the controller pulls the image used by the server.
MULTIROVER_TARGET_IMAGE: *multirover-image MULTIROVER_TARGET_IMAGE: *multirover-image
volumes: volumes:
# Status survives replacement of the application and is kept under its
# existing single data boundary. The transient socket has its own volume
# so special filesystem entries never enter full-data backups.
- data:/data - data:/data
- lifecycle-socket:/run/multirover - lifecycle-socket:/run/multirover
# Do not add this Docker socket mount to the server service.
# This is host-root-equivalent access and therefore exists only here,
# never in the public-facing application container.
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
volumes: volumes:
# Use an explicit name so the same data volume survives Compose project moves # `docker compose down -v` permanently deletes these volumes.
# or directory renames. Ordinary `docker compose down` does not remove it.
data: data:
name: multirover-data name: multirover-data
# This volume carries only the private Unix socket and contains no durable
# application state. Docker creates it automatically with the deployment.
lifecycle-socket: lifecycle-socket:
name: multirover-lifecycle-socket name: multirover-lifecycle-socket