diff --git a/deploy/update.sh b/deploy/update.sh index 51d8a2f..51db1ee 100755 --- a/deploy/update.sh +++ b/deploy/update.sh @@ -113,15 +113,25 @@ deployed="$(cat "$STATE_FILE" 2>/dev/null || echo '')" reconcile_vpn_readiness() { grep -qE '^COMPOSE_PROFILES=.*vpn' .env 2>/dev/null || return 0 - sleep 3 - local running vpn_ready - running="$(docker compose --profile vpn ps --status running --services 2>/dev/null || true)" + local host vpn_ready=false + host="$(sed -n 's/^VPN_INTERNAL_HOST=//p' .env | tail -1)" - if grep -q '^vpn-gateway$' <<<"$running" && grep -q '^vpn-dns$' <<<"$running"; then - vpn_ready=true - else - vpn_ready=false - printf '\033[1;33m !\033[0m %s\n' "The tunnel gateway is not running — clients will not be given its resolver." + # ASKED, not assumed. A container can be up and running while the process + # inside it listens in a network namespace that was torn down underneath it + # — nothing errors, the address simply refuses connections, and a + # container-state check reports everything fine. + for _ in $(seq 1 10); do + if docker compose exec -T vpn-gateway sh -c \ + "wget -q --spider --no-check-certificate https://127.0.0.1/ 2>/dev/null \ + || wget -q -O /dev/null --no-check-certificate https://127.0.0.1/ 2>/dev/null" >/dev/null 2>&1; then + vpn_ready=true + break + fi + sleep 2 + done + + if [[ "$vpn_ready" != "true" ]]; then + printf '\033[1;33m !\033[0m %s\n' "The tunnel gateway is not answering on ${host} — clients will not be given its resolver." fi if [[ "$(sed -n 's/^VPN_READY=//p' .env | tail -1)" != "$vpn_ready" ]]; then @@ -322,6 +332,13 @@ docker compose restart queue queue-provisioning scheduler reverb # Nothing errors; connections to the tunnel address are simply refused, which # looks exactly like the gateway never having worked. if grep -qE '^COMPOSE_PROFILES=.*vpn' .env 2>/dev/null; then + # And only once wg0 is back. The hub brings the interface up as part of its + # start command, so restarting these the instant the container is "started" + # has them binding an address that does not exist yet. + for _ in $(seq 1 30); do + docker compose exec -T queue-provisioning ip -4 addr show wg0 2>/dev/null | grep -q 'inet ' && break + sleep 2 + done docker compose --profile vpn restart vpn-dns vpn-gateway >/dev/null 2>&1 || true fi