CI: reach Postgres through the gateway instead of a shared namespace
CI / verify (push) Failing after 5s
CI / verify (push) Failing after 5s
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) <noreply@anthropic.com>
This commit is contained in:
+25
-9
@@ -32,14 +32,20 @@ jobs:
|
|||||||
|
|
||||||
# Postgres is started as a step rather than through `services:`.
|
# Postgres is started as a step rather than through `services:`.
|
||||||
#
|
#
|
||||||
# The runner here does not put service containers on the job's network, so
|
# Two approaches were tried and rejected before this one:
|
||||||
# `services:` yields "getaddrinfo EAI_AGAIN postgres". Sharing the job
|
#
|
||||||
# container's own network namespace (`--network container:$HOSTNAME`) puts
|
# `services:` — this runner does not attach service
|
||||||
# Postgres on 127.0.0.1 and works regardless of how the runner is
|
# containers to the job network, giving
|
||||||
# configured — which matters because this runner is shared with other
|
# "getaddrinfo EAI_AGAIN postgres".
|
||||||
# repositories and should not have to be reconfigured to suit this one.
|
# `--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:
|
env:
|
||||||
DATABASE_URL: postgres://pig:pig@127.0.0.1:5432/pig
|
|
||||||
PG_CONTAINER: pig-ci-pg-${{ github.run_id }}
|
PG_CONTAINER: pig-ci-pg-${{ github.run_id }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -51,14 +57,24 @@ jobs:
|
|||||||
|
|
||||||
- name: Start Postgres
|
- name: Start Postgres
|
||||||
run: |
|
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 rm -f "$PG_CONTAINER" 2>/dev/null || true
|
||||||
docker run -d --name "$PG_CONTAINER" \
|
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 \
|
-e POSTGRES_USER=pig -e POSTGRES_PASSWORD=pig -e POSTGRES_DB=pig \
|
||||||
postgres:16-alpine
|
postgres:16-alpine
|
||||||
|
|
||||||
for i in $(seq 1 60); do
|
for i in $(seq 1 60); do
|
||||||
if docker exec "$PG_CONTAINER" pg_isready -U pig -q; then
|
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
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user