Postgres Automatic Backups
If you run your FileFlows database in Postgres using Docker, a simple way to keep it backed up is to run postgres-backup-local alongside it.
It dumps the database on a schedule, and automatically keeps a rolling set of daily, weekly and monthly backups.
Docker Compose
services:
postgres:
image: postgres:17
container_name: postgres
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: change-me
ports:
- 5432:5432
volumes:
- ./data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
pgbackups:
image: prodrigestivill/postgres-backup-local:17
restart: unless-stopped
user: postgres:postgres
volumes:
- ./backups:/backups
depends_on:
postgres:
condition: service_healthy
environment:
TZ: Etc/UTC
POSTGRES_HOST: postgres
POSTGRES_DB: FileFlows
POSTGRES_USER: postgres
POSTGRES_PASSWORD: change-me
SCHEDULE: "@daily"
BACKUP_ON_START: "TRUE"
BACKUP_KEEP_DAYS: 10
BACKUP_KEEP_WEEKS: 4
BACKUP_KEEP_MONTHS: 6
Change the following to suit your setup:
| Setting | Description |
|---|---|
POSTGRES_PASSWORD | Set a strong password, and use the same value in both services. |
POSTGRES_DB | The name of your FileFlows database, FileFlows by default. |
TZ | Your timezone, e.g. America/New_York, so backups run at local midnight. |
./backups | Where backups are stored on the host. Ideally point this at another disk or a NAS, so a disk failure does not take out both the database and its backups. |
postgres:17 / :17 | Keep the backup image tag the same as your Postgres major version. |
Prepare the Backup Folder
The backup container runs as the postgres user (user: postgres:postgres) rather than root, which is recommended for security. That user has the ID 999, so create the backup folder and give it ownership before starting the containers:
mkdir -p ./backups && sudo chown -R 999:999 ./backups
The backup folder must be on a filesystem that supports hardlinks and symlinks, such as a local disk or an NFS share. SMB/CIFS shares (Windows shares) and FAT/exFAT drives will not work.
Backup Schedule
| Setting | Description |
|---|---|
SCHEDULE | When to run a backup. @daily runs at midnight, a cron expression such as 0 3 * * * (3am) also works. |
BACKUP_ON_START | Run a backup as soon as the container starts, handy to confirm everything is working. |
BACKUP_KEEP_DAYS | Number of daily backups to keep. |
BACKUP_KEEP_WEEKS | Number of weekly backups to keep. |
BACKUP_KEEP_MONTHS | Number of monthly backups to keep. |
With the settings above you will always have the last 10 days, the last 4 weeks and the last 6 months of backups available.
Check It Is Working
Start the containers and check the backup log:
docker compose up -d
docker compose logs pgbackups
Your backup folder should now contain:
backups/
last/FileFlows-20261027-000000.sql.gz
last/FileFlows-latest.sql.gz
daily/FileFlows-20261027.sql.gz
weekly/FileFlows-202644.sql.gz
monthly/FileFlows-202610.sql.gz
last/FileFlows-latest.sql.gz always points to the most recent backup.
Restoring a Backup
-
Stop the FileFlows server so nothing writes to the database while restoring.
-
Recreate an empty database:
docker exec -it postgres psql -U postgres -c 'DROP DATABASE IF EXISTS "FileFlows";'
docker exec -it postgres psql -U postgres -c 'CREATE DATABASE "FileFlows";' -
Restore the backup:
gunzip -c ./backups/last/FileFlows-latest.sql.gz | docker exec -i postgres psql -U postgres -d FileFlows -
Start the FileFlows server.
Test a restore at least once, to a spare database name if you prefer. A backup is only useful if you know it restores.