Health checks
How VAC gates deploys on health, and how it detects crash-loops and OOM kills.
VAC doesn't flip a deploy to "running" until it has proof the new version is serving. Because the control plane can't reach app containers directly (it's off the edge network), that proof comes from Caddy.
Deploy health gating
After bringing the new stack up and syncing routes, VAC polls Caddy's
/reverse_proxy/upstreams admin endpoint until every routable service reports healthy — or it
times out. Caddy runs active health checks against each service's health path.
| Setting | Default |
|---|---|
| Health path | / (per-service, configurable) |
| Healthy response | HTTP 2xx or 3xx |
| Check interval | 5 seconds |
| Overall gate budget | ~30 seconds |
You can set a custom health path per service (e.g. /healthz, /api/health) from its
settings; the change re-syncs Caddy immediately, no redeploy required.
Outcomes
running— upstreams went healthy within the budget. The deploy is live.degraded— the stack came up but never passed health checks. The app is recorded as degraded and you're notified; the previous version, if any, keeps serving.error— a build or preflight failure before the stack ever came up.
Only services with an HTTP port are routed and health-checked. Background workers, queues, and databases have no route and don't gate the deploy.
Auto-restart
VAC's generated stacks restart containers automatically when they exit, so a transient crash recovers on its own. What you don't want is a container that crashes, restarts, crashes again, forever — which is where crash-loop detection comes in.
Crash-loop detection
VAC watches container death events. If a service restarts 5 times within 2 minutes, VAC considers it crash-looping:
- it stops the service (rather than letting it thrash the box),
- marks it
crash-loop, - writes a system log line explaining why,
- and fires a notification.
Restarting the service from the dashboard clears the flag and resets the counter.
OOM kills
If a container is killed by the kernel's out-of-memory killer (exit code 137), VAC confirms the OOM, increments the service's OOM counter, and notifies you once per episode — often the signal that you need a higher (or a first) memory limit.
Certificate expiry
Separately from app health, VAC checks managed certificates daily and warns you 14 days before any expires without having renewed — so a stuck renewal surfaces as an alert, not an outage.