diff --git a/docker-compose.yml b/docker-compose.yml index 55ca1b5..b084ce1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -83,6 +83,18 @@ services: command: ["api"] stop_signal: SIGTERM stop_grace_period: 30s + # Exists so nomos can wait for the API to actually answer rather than just + # for its container to exist — see nomos's depends_on below. wget is + # BusyBox's, already in the alpine runtime image, so this adds no + # dependency. /healthz pings the DB, so "healthy" means genuinely ready. + healthcheck: + test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:8090/healthz"] + interval: 5s + timeout: 3s + retries: 10 + # Migrations and seed run before this container, but the first bind can + # still take a moment; failures inside the start period don't count. + start_period: 10s # Scheduler (Phase 3) — observe loop scheduler: @@ -139,7 +151,12 @@ services: profiles: ["full"] depends_on: api: - condition: service_started + # service_started only waits for the container to exist, so nomos came + # up while the API was still binding :8090, failed its MCP initialize, + # exited 1, and crash-looped for ~25s on every single deploy. It always + # recovered, which is exactly why it went unnoticed. service_healthy + # waits for the API to actually answer. + condition: service_healthy environment: NOMOS_MCP_URL: http://api:8090/mcp NOMOS_AGENT_SLUG: agent:nomos