From e6b4c1618ecedef23e3997ae26fd51636955861d Mon Sep 17 00:00:00 2001 From: karti Date: Wed, 12 Aug 2026 20:30:24 -0700 Subject: [PATCH] CI: reach Postgres through the gateway instead of a shared namespace Second attempt failed differently: /etc/hostname inside the job reports the HOST's name rather than the container id, so `--network container:$HOSTNAME` found no such container. Rather than hunt for our own container id through /proc, publish the port on the host and connect through the job container's default gateway. That needs no container identity at all. The port is derived from the run id so two concurrent runs cannot collide, and DATABASE_URL is exported through GITHUB_ENV once Postgres is actually accepting connections. Co-Authored-By: Claude Opus 5 (1M context) --- .gitea/workflows/ci.yml | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index ccd8d77..9a6e4c1 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -32,14 +32,20 @@ jobs: # Postgres is started as a step rather than through `services:`. # - # The runner here does not put service containers on the job's network, so - # `services:` yields "getaddrinfo EAI_AGAIN postgres". Sharing the job - # container's own network namespace (`--network container:$HOSTNAME`) puts - # Postgres on 127.0.0.1 and works regardless of how the runner is - # configured — which matters because this runner is shared with other - # repositories and should not have to be reconfigured to suit this one. + # Two approaches were tried and rejected before this one: + # + # `services:` — this runner does not attach service + # containers to the job network, giving + # "getaddrinfo EAI_AGAIN postgres". + # `--network container:$HOSTNAME` — /etc/hostname inside the job reports + # the HOST's name, not the container id, + # so the namespace join finds no such + # container. + # + # What works without needing to know our own container id: publish the port + # on the host and reach it through the job container's default gateway. The + # port is derived from the run id so concurrent runs cannot collide. env: - DATABASE_URL: postgres://pig:pig@127.0.0.1:5432/pig PG_CONTAINER: pig-ci-pg-${{ github.run_id }} steps: @@ -51,14 +57,24 @@ jobs: - name: Start Postgres run: | + # A per-run port in the ephemeral range, so two runs never collide. + PG_PORT=$(( 45000 + (${{ github.run_id }} % 15000) )) + GATEWAY=$(ip route | awk '/^default/ {print $3; exit}') + if [ -z "$GATEWAY" ]; then echo "Could not determine the gateway"; exit 1; fi + echo "Postgres will be published on ${GATEWAY}:${PG_PORT}" + docker rm -f "$PG_CONTAINER" 2>/dev/null || true docker run -d --name "$PG_CONTAINER" \ - --network "container:$(cat /etc/hostname)" \ + -p "${PG_PORT}:5432" \ -e POSTGRES_USER=pig -e POSTGRES_PASSWORD=pig -e POSTGRES_DB=pig \ postgres:16-alpine + for i in $(seq 1 60); do if docker exec "$PG_CONTAINER" pg_isready -U pig -q; then - echo "Postgres ready after ${i}s"; exit 0 + echo "Postgres ready after ${i}s" + # Export for every later step. + echo "DATABASE_URL=postgres://pig:pig@${GATEWAY}:${PG_PORT}/pig" >> "$GITHUB_ENV" + exit 0 fi sleep 1 done