From 77d55e941ccb0c1b483cfa76277e8071c834e03a Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Sun, 28 Jun 2026 17:38:51 +0200 Subject: [PATCH] harden(deploy): add app/frontend healthchecks + readiness-gate Caddy Caddy depended on app/frontend with no readiness gate, so it could proxy to a not-yet-listening upstream and surface brief 502s on boot/restart. Add wget-based healthchecks (busybox wget ships in both alpine runtime images): app hits the unauthenticated /health, frontend hits / (SSR returns 200; the redirect is client-side). app uses a 30s start_period to cover boot-time migrations. Caddy now depends_on both with condition: service_healthy. Co-Authored-By: Claude Opus 4.8 (1M context) --- docker-compose.yml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e269cdf..9823c08 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,6 +35,13 @@ services: - media_data:/media expose: - "3000" + # /health is unauthenticated; start_period covers the boot-time migrations. + healthcheck: + test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:3000/health"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s frontend: build: @@ -43,9 +50,16 @@ services: restart: unless-stopped env_file: .env depends_on: - - app + app: + condition: service_healthy expose: - "3001" + healthcheck: + test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:3001/"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 15s caddy: image: caddy:2-alpine @@ -56,9 +70,13 @@ services: volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - caddy_data:/data + # Gate on readiness so Caddy doesn't proxy to a not-yet-listening upstream + # (which otherwise shows brief 502s on boot/restart). depends_on: - - app - - frontend + app: + condition: service_healthy + frontend: + condition: service_healthy volumes: postgres_data: