Files
EventSnap/.env.example
fabi 9759c7c669 fix(ops): the hourly backup never ran, and an unset POSTGRES_USER crash-loops silently
**The backup that did not exist.**
`.env.example` ships `EVENT_NAME=Max & Maria's Wedding` and the runbook tells you
to `cp .env.example .env`. Compose's env_file parser reads that fine. POSIX `sh`
does not: `. ./.env` aborts with "Unterminated quoted string" (verified, rc=2),
and every variable defined after that line is left unset.

The §10.2 cron script is `#!/bin/sh` + `set -eu` + `. ./.env`, so it exited
before `pg_dump` — every hour, into a log nobody reads. The only automated backup
of the one thing the runbook calls irreconstructible produced nothing, and §10.2's
own "prove it works NOW" only catches it if `.env` is already final at that
moment.

The script reads NOTHING from `.env` — `POSTGRES_USER`/`POSTGRES_DB` are expanded
inside the db container by the single-quoted `sh -c`. The source line was pure
liability and is gone. `EVENT_NAME` is now double-quoted in `.env.example`, which
both parsers read identically (verified), and the three interactive sourcing
sites now read just `$DOMAIN` instead of sourcing the whole file. The verify step
also proves the dump is a non-empty valid gzip containing tables, rather than
that a file exists.

Also fixes the script's `cd /root/eventsnap`, which contradicts §5's non-root
deploy and §13's `~/eventsnap` — under a non-root deploy it failed the same way,
silently.

**The crash loop with no message.**
`docker-compose.yml` interpolated `POSTGRES_USER`/`POSTGRES_DB` with no default
and no `:?` guard, into `environment:`, which OVERRIDES `env_file`. Unset does
not fall back — it resolves to the empty string, initdb creates a role and
database named "", `DATABASE_URL` still says `eventsnap`, and the app hits
`FATAL: role "eventsnap" does not exist` forever. `pg_isready -U "" -d ""` never
passes, so `app` never turns healthy and Caddy — gated on `service_healthy` —
never starts: port 443 dead for the whole event, exit only via `down -v`.

Both now carry `:?` guards (verified they fire), and §3's ".env template — ALL of
them" list, which omitted both, now includes them.

Other runbook corrections: the backup/restore pointer named a line range that had
drifted into an unrelated section and stopped mid-restore, before the media
restore and the mandatory `chown` — now referenced by heading, which cannot go
stale. §7.3 told you to verify that `EXPORT_PATH` is not pinned when §3 correctly
says it is. Stale counts: rev-list 196 -> 217, "versions 007–022" -> 007–031,
`frontend/Dockerfile:9` -> :8, and the low-disk description now matches the code
(the 10 GB absolute floor was removed as unreachable).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 19:46:21 +02:00

14 KiB