feat(deploy): compose.yaml — T2 reference deployment (deploy-B §2.2)
Four services per spec §2.2:
* caddy — image rutster-edge; ports 80/443; volume caddy-data:/data
(Caddy ACME state — loss risks LE 5/week duplicate-cert lockout
per TLS brief §5 risk 5; mounts ./Caddyfile for edit-without-
rebuild).
* engine — image rutster-engine; ports 8080 + 49152-49407/udp (media
UDP direct, never proxied — spec §2.1); stop_grace_period 660s
paired with RUTSTER_DRAIN_DEADLINE_SECS=600 (grace exceeds drain
invariant, spec §2.2/§8).
* brain — image rutster-brain; network_mode: "service:engine" so the
loopback-only tap posture survives unchanged (resolve_tap_url
rejects non-loopback until step 6 per spec §2.2). Quoted in
YAML — `service:engine` would parse as a mapping otherwise.
* valkey — upstream valkey/valkey:8.0 (BSD-3); volume valkey-data:/data;
dark on day one except slice-E ValkeyEventSink consumer.
Bring-your-own-proxy: comment out the caddy service; the engine keeps
plaintext :8080; tuned-timeout snippets land in slice-G reverse-proxies.md.
Signed-off-by: Aaron D. Lee <himself@adlee.work>
This commit is contained in:
109
deploy/compose.yaml
Normal file
109
deploy/compose.yaml
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
# deploy/compose.yaml — T2 modular reference deployment (spec §2.2 / ADR-0011).
|
||||||
|
#
|
||||||
|
# Four services: caddy (rutster-edge), engine (rutster-engine), brain
|
||||||
|
# (rutster-brain, network_mode: "service:engine" so the loopback tap posture
|
||||||
|
# survives unchanged — resolve_tap_url rejects non-loopback until step 6),
|
||||||
|
# valkey (upstream valkey/valkey).
|
||||||
|
#
|
||||||
|
# stop_grace_period 660s paired with RUTSTER_DRAIN_DEADLINE_SECS=600 —
|
||||||
|
# grace EXCEEDS drain or the orchestrator kills calls the engine was
|
||||||
|
# gracefully draining (spec §2.2 / §8). 60s slack accounts for a
|
||||||
|
# legitimately-long in-flight call (599s) + shutdown round-trip.
|
||||||
|
#
|
||||||
|
# Bring your own proxy: comment out the `caddy` service; the engine keeps
|
||||||
|
# its plaintext :8080 listener; tuned-timeout configs for nginx/HAProxy/
|
||||||
|
# Traefik ship in docs/deploy/reverse-proxies.md (slice G).
|
||||||
|
#
|
||||||
|
# Bring-up:
|
||||||
|
# cp .env.example .env
|
||||||
|
# $EDITOR .env # set DOMAIN, ACME_EMAIL, MEDIA_ADVERTISED_IP, TWILIO_*
|
||||||
|
# docker compose up -d
|
||||||
|
# curl -fsS https://$RUTSTER_DOMAIN/healthz && echo OK
|
||||||
|
|
||||||
|
services:
|
||||||
|
caddy:
|
||||||
|
# The custom xcaddy build with curated DNS plugins (cloudflare/
|
||||||
|
# route53/porkbun/hetzner/desec — duckdns excluded per spec §3.2).
|
||||||
|
# In production, pulls from the git.adlee.work/alee/rutster-edge
|
||||||
|
# registry (slice F). For local dev / CI without registry auth, build
|
||||||
|
# from the Dockerfile:
|
||||||
|
# build:
|
||||||
|
# context: ..
|
||||||
|
# dockerfile: deploy/Dockerfile
|
||||||
|
# target: rutster-edge
|
||||||
|
image: rutster-edge:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- caddy-data:/data
|
||||||
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- engine
|
||||||
|
networks:
|
||||||
|
- rutster-net
|
||||||
|
|
||||||
|
engine:
|
||||||
|
# The FOB: axum signaling + media thread + trunk WS + /metrics.
|
||||||
|
# Plaintext :8080 behind Caddy (slice C's rustls will terminate
|
||||||
|
# in-process TLS — same listener, operator-choice).
|
||||||
|
image: rutster-engine:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
# 660s grace > 600s drain (RUTSTER_DRAIN_DEADLINE_SECS) — invariant.
|
||||||
|
stop_grace_period: 660s
|
||||||
|
ports:
|
||||||
|
# Signaling + trunk WS behind Caddy (Caddy proxies :443 -> engine:8080).
|
||||||
|
# Comment out for production hardening (Caddy is the only entry).
|
||||||
|
- "8080:8080"
|
||||||
|
# WebRTC media UDP direct — never proxied (spec §2.1).
|
||||||
|
- "49152-49407:49152-49407/udp"
|
||||||
|
volumes:
|
||||||
|
- ./Caddyfile:/etc/rutster/Caddyfile:ro # copied in image already; mount for edit-without-rebuild
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
networks:
|
||||||
|
- rutster-net
|
||||||
|
|
||||||
|
brain:
|
||||||
|
# Brain shares engine's network namespace — the FOB reaches the brain's
|
||||||
|
# tap port via 127.0.0.1:8082 (loopback-only posture; resolve_tap_url
|
||||||
|
# rejects non-loopback URLs until step 6 per spec §2.2). The brain
|
||||||
|
# graduates to its own netns + wss:// tap auth with step 6.
|
||||||
|
image: rutster-brain:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
# CRITICAL: quoted — YAML would otherwise parse `service:engine` as a
|
||||||
|
# `service: engine` mapping (key:value). The quotes make it a string.
|
||||||
|
network_mode: "service:engine"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- engine
|
||||||
|
|
||||||
|
valkey:
|
||||||
|
# Upstream valkey image (BSD-3; aggregation-clean vs GPL-3 per ADR-0004).
|
||||||
|
# Dark on day one except EventSink (slice E lands ValkeyEventSink
|
||||||
|
# against this service). The operator contract (volumes, ports, upgrade
|
||||||
|
# shape) is stable from v1 per spec §2.1 — the spend ledger (ADR-0009)
|
||||||
|
# + fleet directory land later without changing this service.
|
||||||
|
image: valkey/valkey:8.0
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ["valkey-server", "--dir", "/data", "--save", "60", "1", "--appendonly", "yes"]
|
||||||
|
volumes:
|
||||||
|
- valkey-data:/data
|
||||||
|
networks:
|
||||||
|
- rutster-net
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
# /data — Caddy's cert/ACME state. Loss risks the Let's Encrypt
|
||||||
|
# duplicate-cert lockout (5/week — total inbound outage class).
|
||||||
|
# See docs/deploy/certificates.md (slice G) + TLS brief §5 risk 5.
|
||||||
|
caddy-data:
|
||||||
|
# /var/lib/valkey — stream/state persistence (ADR-0005).
|
||||||
|
valkey-data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
rutster-net:
|
||||||
|
driver: bridge
|
||||||
Reference in New Issue
Block a user