diff --git a/deploy/update.sh b/deploy/update.sh index 8a8aaf1..0cf4121 100755 --- a/deploy/update.sh +++ b/deploy/update.sh @@ -159,7 +159,12 @@ reconcile_vpn_readiness() { port="$(sed -n 's/^VPN_HEALTH_PORT=//p' .env | tail -1)" health="http://${hub}:${port:-8081}/healthz" - for _ in $(seq 1 10); do + # Long enough for a restart to finish. These containers are restarted twice + # in a deployment — once by `up -d`, then again after the hub they live + # inside — and `docker compose exec` into one that is still coming up fails + # outright rather than waiting. Twenty seconds was not enough for that, and + # the run then reported a healthy gateway as down. + for _ in $(seq 1 30); do if docker compose exec -T vpn-gateway sh -c \ "wget -q --spider '$health' 2>/dev/null || wget -q -O /dev/null '$health' 2>/dev/null" >/dev/null 2>&1; then vpn_ready=true diff --git a/docker/caddy/vpn.Caddyfile b/docker/caddy/vpn.Caddyfile index f6df4ea..cf115b5 100644 --- a/docker/caddy/vpn.Caddyfile +++ b/docker/caddy/vpn.Caddyfile @@ -43,6 +43,11 @@ https://{$VPN_INTERNAL_HOST}:443 { # published. Caddy also refuses to start when the certificate above cannot be # read, so a health port that answers proves the whole file loaded. http://{$VPN_HUB_ADDRESS}:{$VPN_HEALTH_PORT:8081} { + # bind, not merely a matching hostname: without it Caddy listens on every + # interface in the namespace and only MATCHES on the address. Nothing is + # published, so it was not reachable from outside either way — but "on the + # hub address and nowhere else" should be what the file actually does. + bind {$VPN_HUB_ADDRESS} respond /healthz 204 respond 404 }