A self-hosted database backup manager with a web UI. Supports PostgreSQL and MySQL/MariaDB with automated scheduling, S3 storage, AES-256-GCM encryption, and one-click restore.
- Multi-database backup — select multiple databases and specific tables per backup job
- Flexible scheduling — built-in cron scheduler with presets (hourly, nightly, weekly, monthly)
- S3 storage — compatible with AWS S3, OVH, Scaleway, MinIO, and any S3-compatible provider
- AES-256-GCM encryption — client-side encryption before upload, PBKDF2-derived key
- Restore from anywhere — restore from local files, S3, or uploaded files; filter by table
- Retention policy — auto-delete old backups by count or age
- Notifications — Slack webhooks and generic HTTP webhooks (with HMAC-SHA256 signing)
- Real-time logs — live streaming log console via Server-Sent Events
docker compose up -dAccess at http://localhost:8080
Default credentials: admin / admin — change immediately in Settings.
go build -o pgbacker ./cmd/main.go
./pgbackerRequires Go 1.21+.
All configuration is stored in config.json (auto-created on first run). No environment variables required.
| Setting | Default | Description |
|---|---|---|
PORT env var |
8080 |
HTTP listen port |
| Admin user | admin |
Changeable in Settings |
| Admin password | admin |
Change on first login |
Each job defines:
- Server — database type, host, port, credentials
- Targets — one or more databases, with optional per-database table selection
- Storage — local only, or S3-compatible bucket
- Encryption — optional AES-256-GCM with passphrase
- Retention — keep last N backups and/or delete files older than N days
- Schedule — cron expression or manual trigger
| Encrypted | Extension |
|---|---|
| No | .sql.gz |
| Yes | .sql.gz.enc |
Encrypted files use a custom header (VLT1) containing a random 32-byte salt and 12-byte IV. The encryption key is derived with PBKDF2-SHA256 (100,000 iterations).
- Go to Restore in the nav
- Select source: local file, S3 bucket, or upload a file
- Configure target database connection
- Optionally analyze the dump and filter tables to restore
- Launch — pgbacker decrypts (if needed), decompresses, and executes SQL
Configure in Notifications settings:
Slack — sends a formatted message with job name, databases, size, and duration.
Generic webhook — POST JSON payload to any URL. Optional HMAC-SHA256 signature via X-pgbacker-Signature header for verification.
{
"job_id": "job_1234567890",
"job_name": "Production",
"status": "success",
"databases": ["myapp"],
"size_bytes": 44040192,
"duration": "1m23s",
"started_at": "2025-06-15T02:00:00Z",
"ended_at": "2025-06-15T02:01:23Z"
}pgbacker uses pg_dump when available and version-compatible with the server. If the server is a newer major version than the local pg_dump (e.g. server PG17, pg_dump PG16), it falls back to a native Go dump engine that supports:
- Proper
"double-quoted"identifier quoting for reserved words E'...'escape string syntax for PostgreSQL- Dollar-quoting in the SQL parser
- UUID, JSON, timestamps, and binary columns
pgbacker/
├── cmd/main.go # Entry point
├── internal/
│ ├── auth/ # Session authentication
│ ├── backup/ # Dump, restore, retention logic
│ ├── config/ # JSON config store
│ ├── crypto/ # AES-256-GCM encryption
│ ├── logger/ # In-memory log ring + SSE broadcast
│ ├── notif/ # Slack & webhook notifications
│ ├── scheduler/ # Cron scheduler
│ ├── storage/ # S3 client (upload, download, list)
│ └── web/ # HTTP handlers & templates
└── templates/ # HTML templates
MIT