Docker Postgres Backup Manager
3.5K
Docker Postgres Backup Manager is a lightweight controller container that orchestrates regular backups for one or many PostgreSQL instances. It exposes a small CLI that can be used both for scheduled operations (inside the container) and for manual backup or restore tasks.
DATABASE_LIST.The container expects the following mount points:
| Mount | Purpose |
|---|---|
/var/lib/postgresql/backup/data/<database> | Primary backup storage for each database. |
When MODE=production, the controller writes directly to the /var/lib/postgresql/backup/*
paths above. Otherwise backups are stored inside the working directory (./backup-data).
The controller's backup and restore flow remains the same on PostgreSQL 18 because it uses
logical dumps via pg_dump and pg_restore, not PostgreSQL's on-disk cluster format.
pg_upgrade, or logical replication.postgres:18 Docker image, mount the database service volume at
/var/lib/postgresql rather than /var/lib/postgresql/data.docker-compose.yml.DATABASE_LIST environment variable of the
controller (comma-separated).A complete example is available in compose.example.yaml.
| Variable | Description |
|---|---|
BACKUP_TARGET | Storage provider used for backups. Set to local (default) or s3. |
DATABASE_LIST | Comma-separated list of database service identifiers that the controller manages. |
MODE | Set to production to use the predefined /var/lib/postgresql/backup/* locations and enable scheduled dumps. |
TZ | Optional timezone used by cron-like scheduling inside the container. |
The controller optionally reads /etc/postgres-backuper/config.yaml. When the file
is missing, backups remain full logical dumps exactly as before. When the file exists,
profiles.default.exclude_table_data can list schema-qualified tables whose data
should be omitted while keeping their table structure, constraints, triggers and index
definitions in the dump. In automated start mode, the file is read during controller
startup; restart the container after changing the config.
profiles:
default:
exclude_table_data:
- public.resource_document_ai_semantic_chunks
- public.resource_document_ai_representative_vectors
- public.resource_document_ai_index_states
Each entry is passed to pg_dump as --exclude-table-data=<schema.table>. The
controller validates that every configured relation exists before running pg_dump.
Entries must be exact lowercase schema.table names; wildcard patterns, quoted
identifiers and mixed-case table names are intentionally not supported. Missing tables
or unknown YAML fields are treated as configuration errors. This setting applies to
every current backup type: manual, daily, weekly and monthly.
Use this only for rebuildable or disposable data. After restore, excluded tables will
exist but will be empty, so the application must be able to rebuild or tolerate that
state. description and notes fields are accepted inside a profile for human
documentation, but they do not affect backup behavior. See config.example.yaml for
a complete example.
| Variable | Description |
|---|---|
<SERVICE>_POSTGRES_HOST | Hostname of the database service (defaults to the service name). |
<SERVICE>_POSTGRES_USER | Username for the target database (defaults to postgres). |
<SERVICE>_POSTGRES_PASSWORD | Password for the target database (defaults to postgres). |
<SERVICE>_POSTGRES_PASSWORD_FILE | Path to a file containing the target database password. If both password variables are set, the file value wins. |
<SERVICE>_POSTGRES_DB | Database name used for restores (defaults to postgres). |
Note: Environment variable prefixes are derived from the service identifier in
DATABASE_LIST. For example, a service namedusersusesUSERS_POSTGRES_USER,USERS_POSTGRES_PASSWORD, etc. Hyphens (-) in service names are converted to underscores.
| Variable | Description |
|---|---|
S3_BUCKET | Bucket name used when BACKUP_TARGET=s3. |
S3_PREFIX | Optional prefix inside the S3 bucket where backups are stored. |
S3_REGION | AWS region of the S3 endpoint. |
S3_ENDPOINT | Endpoint URL of the S3-compatible service. |
S3_ACCESS_KEY_ID | Access key for the S3 service. |
S3_ACCESS_KEY_ID_FILE | Path to a file containing the S3 access key ID. If both access key variables are set, the file value wins. |
S3_SECRET_ACCESS_KEY | Secret key for the S3 service. |
S3_SECRET_ACCESS_KEY_FILE | Path to a file containing the S3 secret access key. If both secret key variables are set, the file value wins. |
S3_USE_TLS | Set to true to use HTTPS (recommended). |
S3_FORCE_PATH_STYLE | Set to true for S3-compatible services that require path-style addressing. |
Set BACKUP_TARGET=s3 to store backups in an S3-compatible bucket. The controller will
upload each dump using the credentials and endpoint supplied via the S3_* variables
listed above. Backups remain fully compatible with all other commands (listing and
restoring downloads the dump to a temporary location inside the container).
The integration test suite uses Docker to spin up PostgreSQL and controller containers.
Tests that exercise S3 storage require credentials supplied through the TEST_S3_*
environment variables. You can create a local .env file (ignored by Git) by copying
.env.example and filling in the required values. The test harness automatically loads
the file when present.
The controller binary is available inside the container as /controller. All commands
must be executed as the postgres user.
./controller start
Runs an infinite loop (designed for container start-up) that performs a dump every
6 hours at HH:03, HH:09, HH:15 and HH:21 when MODE=production. The backup type is
selected automatically:
Retention is enforced after each run according to the policy described above.
./controller dump <database-name|--all>
Creates a dump for a single database, or for every database listed in DATABASE_LIST
when --all is provided.
./controller restore <database-name> <backup-file>
Restores a dump located in the database backup directory. Use the filename listed by
./controller list (for example file_daily_2025-07-04T09:00:00Z.dump).
./controller list <database-name>
Lists available backup files for the given database.
The image runs the controller as the postgres user, matching the default user in
the upstream PostgreSQL image. Mounted backup volumes must already be writable by that
user—use user: postgres in your Compose configuration (or adjust ownership on the
host) so the controller can create and restore dump files. If you mount
/etc/postgres-backuper/config.yaml, the file only needs to be readable by postgres;
Docker configs and bind-mounted files with 0444 or 0644 permissions work.
This project is distributed under the terms of the MIT License.
Integration tests cover the full backup and restore flow by orchestrating PostgreSQL and the controller inside Docker containers. To run them locally:
go clean -testcache ; go test ./test/... -v
Tip: run with
-vto see a step-by-step log of every Docker command that the suite executes.
Note: Docker must be available in the environment. When it is missing the integration suite is skipped.
Content type
Image
Digest
sha256:80187ea03…
Size
114.2 MB
Last updated
4 months ago
docker pull alexbidenko/postgres-backuper