diff --git a/.gitea/workflows/nightly.yml b/.gitea/workflows/nightly.yml index cbf10d39..fa343eb4 100644 --- a/.gitea/workflows/nightly.yml +++ b/.gitea/workflows/nightly.yml @@ -93,15 +93,22 @@ jobs: - name: Smoke test deployed environment # Healthchecks confirm containers are healthy; they do NOT confirm the - # public surface works. This step catches: Caddy not reloaded, DNS - # missing, HSTS header dropped, /actuator block bypassed. + # public surface works. This step catches: Caddy not reloaded, HSTS + # header dropped, /actuator block bypassed. + # + # --resolve pins staging.raddatz.cloud to the runner's loopback so we + # do NOT depend on the host router doing hairpin NAT (many SOHO + # routers do not, or do so only after a firmware update). SNI still + # uses the public hostname so the cert validates correctly. run: | set -e - URL="https://staging.raddatz.cloud" - echo "Smoke test: $URL" - curl -fsS --max-time 10 "$URL/login" -o /dev/null - curl -fsS --max-time 10 -I "$URL/" | grep -qi 'strict-transport-security' - status=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$URL/actuator/health") + HOST="staging.raddatz.cloud" + URL="https://$HOST" + RESOLVE="--resolve $HOST:443:127.0.0.1" + echo "Smoke test: $URL (pinned to 127.0.0.1)" + curl -fsS $RESOLVE --max-time 10 "$URL/login" -o /dev/null + curl -fsS $RESOLVE --max-time 10 -I "$URL/" | grep -qi 'strict-transport-security' + status=$(curl -s $RESOLVE -o /dev/null -w "%{http_code}" --max-time 10 "$URL/actuator/health") [ "$status" = "404" ] || { echo "expected 404 from /actuator/health, got $status"; exit 1; } echo "All smoke checks passed" diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 9ae74ad6..e1eeca2c 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -92,13 +92,17 @@ jobs: - name: Smoke test deployed environment # See nightly.yml — same three checks, against the prod vhost. + # --resolve pins archiv.raddatz.cloud to the runner's loopback so + # the smoke test does NOT depend on hairpin NAT on the host router. run: | set -e - URL="https://archiv.raddatz.cloud" - echo "Smoke test: $URL" - curl -fsS --max-time 10 "$URL/login" -o /dev/null - curl -fsS --max-time 10 -I "$URL/" | grep -qi 'strict-transport-security' - status=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$URL/actuator/health") + HOST="archiv.raddatz.cloud" + URL="https://$HOST" + RESOLVE="--resolve $HOST:443:127.0.0.1" + echo "Smoke test: $URL (pinned to 127.0.0.1)" + curl -fsS $RESOLVE --max-time 10 "$URL/login" -o /dev/null + curl -fsS $RESOLVE --max-time 10 -I "$URL/" | grep -qi 'strict-transport-security' + status=$(curl -s $RESOLVE -o /dev/null -w "%{http_code}" --max-time 10 "$URL/actuator/health") [ "$status" = "404" ] || { echo "expected 404 from /actuator/health, got $status"; exit 1; } echo "All smoke checks passed"