Skip to content

Reloading a dump

This is the copy that rebuilds a machine: the whole database, every reader, into an empty volume. A single reader’s file goes back through the interface instead, under Restoring an export.

Terminal window
export PGPASSWORD=$(grep -m1 '^POSTGRES_PASSWORD=' .env | cut -d= -f2-)
docker compose down
docker volume rm badlen_pgdata
docker compose up -d --wait db
docker 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.sql
docker 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 app

The first line is also the one the dump began with. It is repeated here because a restore usually happens in a terminal opened long after the backup was taken, where the variable -e PGPASSWORD passes does not exist. 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 matters because the volume you just deleted held all of the database’s data: on this start 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 hits 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 does for the restore what the completion marker does for the dump, and it runs before the app starts, not after: 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.

If the instance you are restoring into has 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.