From ec119af2740668335ad220a141e69f8c37d5b9e4 Mon Sep 17 00:00:00 2001 From: Julian Cuni Date: Sat, 2 May 2026 10:38:26 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20CI=20port=20collision=20=E2=80=94=20remap?= =?UTF-8?q?=20throwaway=20Postgres=20to=20host=20port=2015432?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The runner host typically has another Postgres listening on 5432 (local dev stack, stage instance, etc.), which made the services: postgres container fail at start with "port already allocated." Remap the host-side port from 5432:5432 to 15432:5432. The service container still listens on 5432 internally; only the runner host binding changes. Dry-run's DB_PORT updated to 15432 to match. --network host semantics preserved: DB_HOST=localhost reaches the service on the runner's loopback at the new port. Why we still need a Postgres container at all: the dry-run gate applies db-init/*.sql migrations and the directus schema snapshot against a real DB to catch breakage before pushing the image. No Postgres = no validation = the gate is bypassed. Inline comment in the workflow now explains the choice; task spec's Done section captures the correction so future readers don't re-discover this. --- .gitea/workflows/build.yml | 12 ++++++++---- .../phase-1-slice-1-schema/08-gitea-ci-dryrun.md | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index a9bc2ae..0c616a1 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -26,8 +26,12 @@ jobs: # PGDATA: the timescaledb-ha image initialises at /home/postgres/pgdata/data; # the healthcheck uses pg_isready, which doesn't depend on the PGDATA path. # - # Port mapping: 5432:5432 binds the service on the runner's loopback. - # The dry-run docker run uses --network host so DB_HOST=localhost reaches it. + # Port mapping: 15432:5432 — host port 15432 is the conventional + # Postgres-second-instance port. We deliberately do NOT use 5432 on the + # runner because the runner host typically has another Postgres on 5432 + # (dev stack, stage instance) which would cause a port-allocation collision. + # The dry-run docker run uses --network host so DB_HOST=localhost reaches + # the service on the runner's loopback at port 15432. # --------------------------------------------------------------------------- services: postgres: @@ -37,7 +41,7 @@ jobs: POSTGRES_PASSWORD: directus POSTGRES_DB: directus ports: - - '5432:5432' + - '15432:5432' options: >- --health-cmd "pg_isready -U directus -d directus" --health-interval 5s @@ -93,7 +97,7 @@ jobs: --entrypoint bash \ -e DB_CLIENT=pg \ -e DB_HOST=localhost \ - -e DB_PORT=5432 \ + -e DB_PORT=15432 \ -e DB_USER=directus \ -e DB_PASSWORD=directus \ -e DB_DATABASE=directus \ diff --git a/.planning/phase-1-slice-1-schema/08-gitea-ci-dryrun.md b/.planning/phase-1-slice-1-schema/08-gitea-ci-dryrun.md index 44cfee6..accfc57 100644 --- a/.planning/phase-1-slice-1-schema/08-gitea-ci-dryrun.md +++ b/.planning/phase-1-slice-1-schema/08-gitea-ci-dryrun.md @@ -173,3 +173,5 @@ Pending live trigger (will validate on first push that hits the path filter): - `PORTAINER_WEBHOOK_URL` (optional) — for auto-redeploy on push Without `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` the Login step fails with a clear auth error. Without `PORTAINER_WEBHOOK_URL` the Portainer step is skipped entirely. + +**Port-allocation correction (2026-05-02):** initial workflow used `5432:5432` for the throwaway-Postgres port mapping. On a self-hosted Gitea runner, the host typically has another Postgres on 5432 (dev stack, stage instance), causing the service container to fail at start with "port already allocated." Fixed by remapping to `15432:5432` (the conventional Postgres-second-instance port) and updating the dry-run's `DB_PORT=15432`. The service container itself still listens on 5432 internally — only the host-side mapping changed. `--network host` semantics are preserved: `DB_HOST=localhost` reaches the service on the runner's loopback at `:15432`.