From 18705aaefba46d8bc2eb592e24849bb680c084a0 Mon Sep 17 00:00:00 2001 From: bonamin Date: Wed, 30 Sep 2026 16:45:58 +0300 Subject: [PATCH] fix(docker): keep server Postgres on ./data/postgres, move Windows volume to an override 751cac7 switched the base compose file to an external named volume (bellsystems-postgres-data) to dodge a WSL2/Docker Desktop bind-mount bug. That volume only exists on the Windows dev machine: on the VPS, where the push auto-deploys via deploy-host.sh, `docker compose up` would fail on the missing external volume (or, if created, start Postgres on an empty database while the real data sat unused in ./data/postgres). The base file goes back to the ./data/postgres bind mount the server has always used (Linux has no such bug). The named volume now lives in docker-compose.override.yml, which Compose loads automatically, is gitignored, and is created from docker-compose.override.example.yml on Windows machines only. Co-Authored-By: Claude Opus 5.5 --- .gitignore | 4 +++- docker-compose.override.example.yml | 18 ++++++++++++++++++ docker-compose.yml | 19 ++++--------------- 3 files changed, 25 insertions(+), 16 deletions(-) create mode 100644 docker-compose.override.example.yml diff --git a/.gitignore b/.gitignore index 77877d1..cd47277 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,6 @@ Thumbs.db .project-vesper-plan.md # claude -.claude/ \ No newline at end of file +.claude/ +# Per-machine compose overrides (e.g. Windows Postgres volume) +docker-compose.override.yml diff --git a/docker-compose.override.example.yml b/docker-compose.override.example.yml new file mode 100644 index 0000000..93077b0 --- /dev/null +++ b/docker-compose.override.example.yml @@ -0,0 +1,18 @@ +# Windows / Docker Desktop dev machines only — copy to docker-compose.override.yml +# (gitignored; Docker Compose loads it automatically). The server does NOT use this. +# +# Why: a ./data/postgres bind mount onto the Windows filesystem hits a +# WSL2/Docker Desktop bug where the 9p/virtiofs bridge reports normal +# postgres:postgres 0600 ownership but the kernel still refuses the postgres +# user's own open() calls for write — silent on read, fatal on any WAL write. +# A Docker-managed named volume lives inside the WSL2 VM's own filesystem and +# avoids it. Create it once with: docker volume create bellsystems-postgres-data +services: + postgres: + volumes: + - postgres-data:/var/lib/postgresql/data + +volumes: + postgres-data: + name: bellsystems-postgres-data + external: true diff --git a/docker-compose.yml b/docker-compose.yml index bcdc4a7..a237ba9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,7 +50,10 @@ services: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - - postgres-data:/var/lib/postgresql/data + # Server default: plain folder on the host (Linux, no WSL2 issues). + # Windows dev machines override this with a Docker volume in + # docker-compose.override.yml — see docker-compose.override.example.yml. + - ./data/postgres:/var/lib/postgresql/data networks: - internal healthcheck: @@ -62,17 +65,3 @@ services: networks: internal: driver: bridge - -volumes: - # Docker-managed volume (lives inside the WSL2 VM's own filesystem) instead - # of a ./data/postgres bind mount onto the Windows filesystem. The bind - # mount hit a WSL2/Docker Desktop bug where the 9p/virtiofs bridge reports - # normal postgres:postgres 0600 ownership but the kernel still refuses the - # postgres user's own open() calls for write — silent on read, fatal on any - # WAL write, which took the whole database down after an unclean shutdown. - # Migrated 2026-09-04; the old bind-mounted data is untouched at - # ./data/postgres/ as a backup (that folder itself was too wedged by the - # same bug to even rename — leave it alone; it's not used anymore). - postgres-data: - name: bellsystems-postgres-data - external: true