Groundwork for testmodul.qrmaster.net, a second stack running the `test` branch on a real qrmaster.net subdomain. Production scopes its session cookie to .qrmaster.net, so the browser sends it to every subdomain including staging. With both environments naming the cookie `userId`, the browser holds two cookies of the same name and cookies.get() picks one arbitrarily - staging logins would look randomly signed-out. AUTH_COOKIE_NAME lets staging pick `userId_test` instead. Production keeps the `userId` default; changing it there would invalidate every existing session. Wired getAuthCookieName() into the six places that named the cookie literally. The account deletion route now expires both the host-only and the domain-scoped variant like the logout route already does, instead of a single cookies().delete() that would leave the other one behind. NEXT_PUBLIC_WWW_URL and NEXT_PUBLIC_APP_URL become build ARGs so the same image can be built pointing at the staging host - the defaults keep a plain production build byte identical to before. Like COOKIE_DOMAIN these must exist at build time, because process.env is inlined into the Edge middleware bundle. robots.ts now serves Disallow-all unless NEXT_PUBLIC_INDEXABLE is true. Staging otherwise returns the production robots.txt and invites crawlers to index a duplicate of www. docker-compose.test.yml is the staging overlay. Two things it must get right, both verified against `docker compose config`: - db and redis need `networks: !override`. Compose MERGES the networks mapping from the base file, and since qrmaster-network is external and shared, a plain list left them attached to it - `db` would then resolve to two containers and staging could read and write the production database. - The web entrypoint is replaced so `prisma migrate deploy` never runs. prisma/migrations stopped in April 2026 and the schema has moved on through manual SQL since, so applying them to a fresh database would build a stale schema. Staging gets its schema from `pg_dump --schema-only` against production instead. Verified: tsc clean, production build succeeds, and the merged compose config confirms staging keeps db/redis off the shared network while production resolves unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
60 lines
2.5 KiB
YAML
60 lines
2.5 KiB
YAML
# Test/staging overlay for testmodul.qrmaster.net.
|
|
#
|
|
# Start with:
|
|
# docker compose -p qrmaster-test --env-file .env.test \
|
|
# -f docker-compose.yml -f docker-compose.test.yml up -d --build
|
|
#
|
|
# The project name is what keeps the data apart: `-p qrmaster-test` gives this stack its own
|
|
# volumes, so its Postgres can never touch the production one.
|
|
|
|
services:
|
|
db:
|
|
container_name: qrmaster-test-db
|
|
# Production already publishes 5435 on the host.
|
|
ports: !reset []
|
|
# 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`
|
|
# resolve to two containers and this stack could reach the production database.
|
|
#
|
|
# `!override` is required: compose MERGES the networks mapping from the base file, so a
|
|
# plain list would leave qrmaster-network attached and reintroduce exactly that bug.
|
|
networks: !override
|
|
- test-internal
|
|
|
|
redis:
|
|
container_name: qrmaster-test-redis
|
|
networks: !override
|
|
- test-internal
|
|
|
|
web:
|
|
container_name: qrmaster-test-web
|
|
# No `prisma migrate deploy` here. The migrations in prisma/migrations stopped in
|
|
# April 2026 and the schema has moved on through manual SQL since, so running them
|
|
# against a fresh database would build a stale schema the app cannot work with.
|
|
# Bring the schema in with `pg_dump --schema-only` from production instead.
|
|
entrypoint: ["node", "server.js"]
|
|
build:
|
|
args:
|
|
# Host-only cookie on staging, so `:-` (empty) is the correct value here.
|
|
COOKIE_DOMAIN: ${COOKIE_DOMAIN:-}
|
|
# These three use `:?` on purpose: an empty value would silently fall back to the
|
|
# production defaults baked into the Dockerfile, and the staging frontend would then
|
|
# talk to production. Better to fail the build with a readable message.
|
|
AUTH_COOKIE_NAME: ${AUTH_COOKIE_NAME:?set AUTH_COOKIE_NAME in .env.test, e.g. userId_test}
|
|
NEXT_PUBLIC_WWW_URL: ${NEXT_PUBLIC_WWW_URL:?set NEXT_PUBLIC_WWW_URL in .env.test to https://testmodul.qrmaster.net}
|
|
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:?set NEXT_PUBLIC_APP_URL in .env.test to https://testmodul.qrmaster.net}
|
|
# Reachable by Caddy over the shared network, everything else stays internal.
|
|
networks:
|
|
- test-internal
|
|
- qrmaster-network
|
|
|
|
adminer:
|
|
container_name: qrmaster-test-adminer
|
|
ports: !reset []
|
|
networks: !override
|
|
- test-internal
|
|
|
|
networks:
|
|
test-internal:
|
|
driver: bridge
|