PostgreSQL
PostgreSQL is the awkward case: a tar of a running data directory can capture a half-written state. There are two correct answers, and Dockup supports both.
Option 1 — stop the database (simplest)
Postgres flushes cleanly on shutdown, so a stopped container's volume is consistent. This costs a few seconds of downtime per backup.
services:
postgres:
image: postgres:17
volumes:
- pgdata:/var/lib/postgresql/data
labels:
dockup.stop: "true" # Dockup may stop me
volumes:
pgdata:
labels:
dockup.enable: "true"
dockup.schedule: daily
dockup.target: nas
dockup.keep-daily: "7"
dockup.keep-monthly: "6"Dockup stops the container, archives the volume, and starts it again — even when the archive fails. stop-timeout (default 30s) is the grace period before Docker kills it.
Option 2 — dump into the volume (no downtime)
Use a pre-hook to write a logical dump inside the volume, and a post-hook to remove it. The archive then contains a consistent dump instead of raw files.
# dockup.yml
hooks:
postgres:
pre:
- pg_dump -U postgres -Fc -f /var/lib/postgresql/data/dockup.pgcustom app
post:
- rm -f /var/lib/postgresql/data/dockup.pgcustomservices:
postgres:
image: postgres:17
volumes:
- pgdata:/var/lib/postgresql/data
labels:
dockup.hook: postgres # run the hook set above
volumes:
pgdata:
labels:
dockup.enable: "true"
dockup.schedule: daily
dockup.target: nas,offsite
dockup.exclude: dockup.pgcustom # already inside the dumpHooks run through sh -c inside the container, so they see the container's PATH and its PG* environment.
A failing pre-hook aborts the run
Dockup does not stop anything or archive anything when a pre command fails; the run is recorded as failed. That is deliberate: an aborted pg_dump should never produce a backup that looks successful.
Restoring a logical dump
Restore the volume with dockup restore, then load the dump:
$ docker compose exec postgres pg_restore -U postgres -d app --clean --if-exists /var/lib/postgresql/data/dockup.pgcustomChoosing between them
| Stop | Dump | |
|---|---|---|
| Downtime | seconds per run | none |
| Restore | whole cluster, exactly as it was | one database, portable across versions |
| Archive size | full data directory | dump only (usually smaller) |
| Works for | every database | databases pg_dump can read |
Running both is also sensible: dockup.stop: "true" and dockup.hook: postgres gives a clean shutdown plus a portable dump in the same archive.