Give the staging database its own name

The staging database now runs as qrmaster_test instead of reusing the production name.
Container and volume already kept the two apart, but a hand-typed psql session against
two databases both called `qrmaster` looks identical on either side - the distinct name is
what makes the wrong window obvious before a DELETE lands in it.

The base compose file hardcodes `pg_isready -d qrmaster` in the db healthcheck, so the
overlay has to override the probe as well. Without it the container stays unhealthy and web
never starts, because it waits on service_healthy.

Verified against `docker compose config`: staging resolves to qrmaster_test in POSTGRES_DB,
DATABASE_URL and the healthcheck, while production still resolves to qrmaster.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 22:20:30 +02:00
parent 40b73877b6
commit d623f39c54
2 changed files with 22 additions and 10 deletions

View File

@@ -121,9 +121,9 @@ NEXT_PUBLIC_INDEXABLE=false
# Eigene DB im Test-Stack # Eigene DB im Test-Stack
POSTGRES_USER=postgres POSTGRES_USER=postgres
POSTGRES_PASSWORD=<eigenes> POSTGRES_PASSWORD=<eigenes, hex - ein "/" aus base64 zerlegt die DATABASE_URL>
POSTGRES_DB=qrmaster POSTGRES_DB=qrmaster_test
DATABASE_URL=postgresql://postgres:<eigenes>@db:5432/qrmaster?schema=public # DATABASE_URL nicht setzen - Compose baut sie aus den drei Werten oben
# Test-Keys / leer, siehe Falle 3 # Test-Keys / leer, siehe Falle 3
STRIPE_SECRET_KEY=sk_test_… STRIPE_SECRET_KEY=sk_test_…
@@ -175,9 +175,15 @@ networks:
driver: bridge driver: bridge
``` ```
`POSTGRES_DB` auf Test **gleich lassen** (`qrmaster`): der Healthcheck hat `pg_isready -d `POSTGRES_DB` heißt auf Test `qrmaster_test`. Die Trennung kommt zwar schon vom eigenen
qrmaster` hartkodiert ([Zeile 19](docker-compose.yml:19)) und würde bei abweichendem Namen den Container und Volume, aber der abweichende Name macht bei einer von Hand getippten
Container als unhealthy melden. Die Trennung kommt vom Volume, nicht vom Datenbanknamen. `psql`-Sitzung sofort sichtbar, auf welcher Instanz man ist - die billigste Versicherung
gegen ein `DELETE` in der falschen Datenbank.
Dafür muss der Healthcheck mitgezogen werden: das Basis-File hat `pg_isready -d qrmaster`
hartkodiert ([Zeile 19](docker-compose.yml:19)). Ohne Override prüft er eine Datenbank, die
es nicht gibt, der Container bleibt `unhealthy`, und `web` startet wegen
`depends_on: condition: service_healthy` nie.
Start: Start:
@@ -222,11 +228,11 @@ Eigene PostgreSQL-Instanz im Test-Stack, befüllt mit **Struktur ohne Zeilen**.
Kundendaten verlassen die Produktion. Kundendaten verlassen die Produktion.
```bash ```bash
# auf dem Server, aus dem Prod-Stack # Struktur aus Prod ziehen (keine Zeilen)
docker compose exec db pg_dump -U postgres --schema-only qrmaster > /tmp/schema.sql docker exec qrmaster-db pg_dump -U postgres --schema-only qrmaster > schema.sql
# in den Test-Stack einspielen # in die Test-DB einspielen
docker compose -p qrmaster-test exec -T db psql -U postgres qrmaster < /tmp/schema.sql docker exec -i qrmaster-test-db psql -U postgres -d qrmaster_test < schema.sql
``` ```
Danach einen Testaccount anlegen - entweder über das Signup-Formular auf testmodul oder per Danach einen Testaccount anlegen - entweder über das Signup-Formular auf testmodul oder per

View File

@@ -12,6 +12,12 @@ services:
container_name: qrmaster-test-db container_name: qrmaster-test-db
# Production already publishes 5435 on the host. # Production already publishes 5435 on the host.
ports: !reset [] ports: !reset []
# The base file hardcodes the database name in the probe. Staging uses its own name so a
# hand-typed psql session makes it obvious which instance you are on - without this
# override the probe would check a database that does not exist, the container would stay
# unhealthy and web (depends_on: service_healthy) would never start.
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d qrmaster_test"]
# Only on the internal network. `db` and `redis` are network aliases assigned per # Only on the internal network. `db` and `redis` are network aliases assigned per
# compose project, so leaving them on the shared external network would make `db` # compose project, so leaving them on the shared external network would make `db`
# resolve to two containers and this stack could reach the production database. # resolve to two containers and this stack could reach the production database.