Reloading a dump
This is the copy that puts a machine back: the whole database, every reader, into an empty volume. A single reader’s file goes back through the interface instead, under Restoring an export.
The sequence
Section titled “The sequence”export PGPASSWORD=$(grep -m1 '^POSTGRES_PASSWORD=' .env | cut -d= -f2-)docker compose downdocker volume rm badlen_pgdatadocker compose up -d --wait dbdocker run --rm -i --network badlen_default -e PGPASSWORD postgres:18-alpine \ psql -h db -U badlen -d badlen -v ON_ERROR_STOP=1 < badlen-2026-08-01.sqldocker run --rm --network badlen_default -e PGPASSWORD postgres:18-alpine \ psql -h db -U badlen -d badlen -tAc \ 'select (select count(*) from "User"), (select count(*) from "Account"), (select count(*) from "Transaction")'docker compose up -d appWhy each line is there
Section titled “Why each line is there”The first is the one the dump began with, and it is repeated rather than assumed: a restore happens
in a terminal opened long after the backup was taken, and -e PGPASSWORD passes a variable that is
not there. What you get then is password authentication failed for user "badlen", which reads as a
wrong password in .env rather than as an export missing from this shell.
--wait is not a nicety. The volume you just deleted was the database’s whole data home, so this is
the start where it creates its cluster from nothing, and that takes some ten seconds during which
the container is up and the server is not listening. Without it, up -d hands back the moment the
container exists and psql lands on Connection refused.
ON_ERROR_STOP=1 matters too: without it psql reports every error and exits 0 anyway, and a
restore that failed halfway looks like one that worked.
The count is to the restore what the completion marker is to the dump, and it comes before the app rather than after it: readers, accounts, operations. Three zeroes, or an error naming a relation that does not exist, mean nothing was restored. Bring the app up on an empty database and it applies the migrations and serves a sign-up page, which looks exactly like a first install, the one thing a restore is not supposed to look like.
If the instance carries another key
Section titled “If the instance carries another key”If the instance you are restoring into carries a different SECRET_ENCRYPTION_KEY, read
Restoring under another key before you sign in: two things come
back unreadable, and one of them is how you get in.