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) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-28 17:38:51 +02:00
parent a895bebdc2
commit 77d55e941c

View File

@@ -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: