ci(smoke): pin curl to 127.0.0.1 via --resolve
The smoke step previously curled the public hostname unconditionally, which routes the runner's request via DNS → router → back into the same host. Many SOHO routers do not implement hairpin NAT (or do so only after a firmware update), so the deploy may pass on day one and silently fail on day 90. --resolve "<host>:443:127.0.0.1" pins the hostname to the runner's loopback while keeping SNI on the public name (so the cert validates correctly and the Caddy vhost block matches). The smoke test now verifies that the Caddy-on-the-same-host is serving the right hostname end-to-end, with no router dependency. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user