# Container shape for the Mode A site (docs/phase-2-static-site.md §2.1). # # Values are fixed by the specification and must not drift: # mem_limit == memswap_limit == 120m so the app cannot eat the host's swap # ports published on 127.0.0.1 only Caddy on .35 is the only public listener # logging capped one bad day cannot fill the disk # # Run it (build the artefacts first — Phase 3's deploy.sh does both): # # make build dist # docker compose -f deploy/compose.yml up -d # # `curl http://127.0.0.1:8096/healthz` must answer with static ready. name: ai-resume services: resume: image: ai-resume:local build: context: .. dockerfile: deploy/Dockerfile restart: unless-stopped mem_limit: 120m memswap_limit: 120m # The app listens on 0.0.0.0 inside the container namespace; the host-side # binding is loopback, so nothing is reachable from the LAN except through # docker-proxy on 127.0.0.1:8096 — which is what Caddy proxies to. ports: - "127.0.0.1:8096:8096" read_only: true security_opt: - no-new-privileges:true logging: driver: json-file options: max-size: 10m max-file: "3" healthcheck: test: ["CMD", "/usr/bin/resume-server", "--health-check"] interval: 30s timeout: 3s retries: 3 start_period: 5s # Phase 4/5 add at most three more containers (Qdrant, Prefect worker, query # service) inside the 4-container and 1.0 GiB budget in AGENTS.md §4.3. Mode A # needs none of them and must keep working when they are stopped (test A1).