pgjdbc/pgjdbc GitHub issues and pull requests (mirror)
help / color / mirror / Atom feedFrom: vlsi (@vlsi) <[email protected]>
To: pgjdbc/pgjdbc <[email protected]>
Subject: [pgjdbc/pgjdbc] PR #4189: feat(test): opt-in per-worktree isolation for the test Postgres container
Date: Mon, 15 Jun 2026 19:07:46 +0000
Message-ID: <[email protected]> (raw)
## Why
`docker/postgres-server/docker-compose.yml` is shared across git worktrees and plain checkouts. Compose derives the project name from the directory (`postgres-server`), so every worktree is treated as the **same** project: shared network, shared container, and `run --rm`/`down` in one worktree tears down the server another is using. The published ports (5432/5433/5434) are fixed too, so two servers cannot run side by side.
This bites anyone running work in parallel across worktrees — for example several branches, or multiple agents, sharing one machine.
## What
Opt-in isolation, gated by a single environment variable. Default behaviour is unchanged.
- `docker/bin/postgres-server`: when `PG_ISOLATE=1` is set, the script derives a unique `COMPOSE_PROJECT_NAME` and a host-port offset from `git rev-parse --show-toplevel` (a `cksum` of the worktree path → slot 0–199 → offset ×10). With `PG_ISOLATE` unset it keeps the historic project name and ports `5432/5433/5434`, so CI and existing setups are untouched. An explicit `PG_PUBLISH_PORT` still wins.
- `docker-compose.yml`: the port mappings now substitute `PG_PUBLISH_PORT` / `PG_REPLICA_ONE_PUBLISH_PORT` / `PG_REPLICA_TWO_PUBLISH_PORT` (with the old defaults), so a direct `docker compose up` honours them as well.
- Fix a copy-paste bug: the second replica port read `PG_REPLICA_ONE_PUBLISH_PORT` instead of `PG_REPLICA_TWO_PUBLISH_PORT`.
The variable works as a global toggle: export `PG_ISOLATE=1` once in your shell profile or a `direnv` `.envrc`, and every worktree gets its own container and ports automatically.
## How to verify
```bash
cd docker/postgres-server
# default — ports 5432/5433/5434, project "postgres-server"
docker compose config | grep -E 'name:|published:'
# isolated — distinct ports and project name
PG_ISOLATE=1 ../bin/postgres-server # logs the chosen project and ports, then starts
```
## Draft — open questions
This is a draft to settle the design before finishing. Deliberately **not** included yet:
- Writing the chosen ports into `build.local.properties`, so `./gradlew test` in a worktree hits its own server. Without it, the tests still target 5432 when isolation is on.
- Slot-collision handling. Two worktrees whose paths hash to the same `cksum % 200` would share ports. The robust alternative is ephemeral host ports read back via `docker compose port`, at the cost of being harder to write into `build.local.properties` up front.
Alternatives considered (Gradle shared `BuildService`, Testcontainers) are heavier and change the CI flow; happy to discuss if reviewers prefer one of those.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
diff --git a/docker/bin/postgres-server b/docker/bin/postgres-server
index d9fb4dd137..34e0f8bdf2 100755
--- a/docker/bin/postgres-server
+++ b/docker/bin/postgres-server
@@ -48,12 +48,34 @@ log () {
main () {
local publish_port="${PG_PUBLISH_PORT:-5432}"
local replica_one_port="${PG_REPLICA_ONE_PUBLISH_PORT:-5433}"
- local replica_two_port="${PG_REPLICA_ONE_PUBLISH_PORT:-5434}"
+ local replica_two_port="${PG_REPLICA_TWO_PUBLISH_PORT:-5434}"
# Determine our current directory and change to be in the same directory as the compose file
local script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
cd "${script_dir}/../postgres-server"
+ # Opt-in per-worktree isolation. Set PG_ISOLATE=1 (for example via direnv or your
+ # shell profile) to give each git worktree its own Compose project and host ports,
+ # so parallel checkouts no longer share or tear down each other's server. The default
+ # (PG_ISOLATE unset) keeps the historic project name and ports 5432/5433/5434, so CI
+ # and existing setups are unaffected. An explicit PG_PUBLISH_PORT still wins.
+ if [[ -n "${PG_ISOLATE:-}" ]]; then
+ local worktree
+ worktree="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
+ local slot
+ slot=$(( $(printf '%s' "${worktree}" | cksum | cut -d' ' -f1) % 200 ))
+ local offset=$(( slot * 10 ))
+
+ publish_port="${PG_PUBLISH_PORT:-$(( 5432 + offset ))}"
+ replica_one_port="${PG_REPLICA_ONE_PUBLISH_PORT:-$(( 5433 + offset ))}"
+ replica_two_port="${PG_REPLICA_TWO_PUBLISH_PORT:-$(( 5434 + offset ))}"
+
+ local slug
+ slug="$(basename "${worktree}" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9_-' '_' | tr -s '_')"
+ export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-pgjdbc_${slug}_${slot}}"
+ log "Worktree isolation on: project=${COMPOSE_PROJECT_NAME}, ports=${publish_port}/${replica_one_port}/${replica_two_port}"
+ fi
+
log "Starting Postgres server and mapping to local port ${publish_port}"
exec docker compose run \
--rm \
diff --git a/docker/postgres-server/docker-compose.yml b/docker/postgres-server/docker-compose.yml
index 1108aa819e..2ecde90a02 100644
--- a/docker/postgres-server/docker-compose.yml
+++ b/docker/postgres-server/docker-compose.yml
@@ -2,9 +2,9 @@ services:
pgdb:
image: postgres:${PGV:-latest}
ports:
- - 5432:5432
- - 5433:5433
- - 5434:5434
+ - ${PG_PUBLISH_PORT:-5432}:5432
+ - ${PG_REPLICA_ONE_PUBLISH_PORT:-5433}:5433
+ - ${PG_REPLICA_TWO_PUBLISH_PORT:-5434}:5434
security_opt:
- seccomp:unconfined
volumes:
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: github://pgjdbc/pgjdbc
Cc: [email protected], [email protected]
Subject: Re: [pgjdbc/pgjdbc] PR #4189: feat(test): opt-in per-worktree isolation for the test Postgres container
In-Reply-To: <<[email protected]>>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox