# DECT relay agent — data-center deployment. # # This compose file assumes the image has already been loaded from # the shipped tarball (see install.sh: `docker load < image.tar.gz`). # It does NOT build — build happens on the dev machine via bundle.sh # so no npm-registry or Alpine-CDN traffic is needed inside the DC. # # Usage in the DC: # 1. cp .env.example .env && $EDITOR .env # 2. ./install.sh # (or manually: docker load < image.tar.gz && docker compose up -d) # 3. docker compose logs -f dect-relay-agent # # The IMAGE_TAG env var lets install.sh pin whatever tag the bundle # ships (the bundle writes it into .env on install). Falls back to # the current default so `docker compose up` still works standalone. services: dect-relay-agent: # Tag comes from the image tarball shipped in the bundle; install.sh # sets IMAGE_TAG in .env to whatever was baked in. Never falls back # to :latest — that would silently swap in whatever's cached on the # DC host if the tarball didn't load correctly. image: ${IMAGE_TAG:-collabsupport/dect-relay-agent:0.1.0} container_name: dect-relay-agent # Read all config (bot URL, shared bearer, DBS-210 admin creds) # from the operator's .env in this same directory. Compose does # NOT auto-load .env into the container by default — env_file # is the explicit opt-in. env_file: - .env # Restart on crash or reboot. `unless-stopped` respects an # operator `docker compose stop` (so it doesn't come back until # they say so) while surviving host reboots. restart: unless-stopped # Host networking so the agent can reach 10.x/8 without needing # docker userland proxy translation. The agent doesn't LISTEN on # anything — it dials outbound WSS to the bot — so this doesn't # expose any port to the host's network. # # If your DC prefers bridge networking, remove this line. The # only requirement is that the container can egress to (a) the # bot's public HTTPS endpoint and (b) 10.0.0.0/8 on TCP 443. network_mode: host # Log rotation — keeps container logs from filling the disk on # long-running deployments. 10 MB × 5 files = 50 MB max per agent. logging: driver: json-file options: max-size: "10m" max-file: "5" # Read-only root filesystem + a small writable /tmp. The agent # writes nothing to disk (all logs go to stdout / stderr), so # this is essentially free defense-in-depth. read_only: true tmpfs: - /tmp:size=16M # Minimal capabilities — the agent is just outbound HTTP client # traffic, no need for NET_RAW / SYS_ADMIN / etc. cap_drop: - ALL security_opt: - no-new-privileges:true # Basic health check: the agent process being alive is a good # proxy for "we're at least trying to reconnect". A deeper check # (last successful hello with the bot < 2min ago) would need # code the agent doesn't expose yet. healthcheck: test: ["CMD", "node", "-e", "process.exit(0)"] interval: 60s timeout: 5s start_period: 10s retries: 3