A tiny web UI to back up and restore multiple PostgreSQL databases from a single Docker container
  • PHP 95.8%
  • Shell 2.4%
  • Dockerfile 1.8%
Find a file
2026-07-12 19:27:32 +02:00
.forgejo Remove Forgejo release job from Docker release workflow 2026-07-10 23:40:02 +02:00
docker Fix crontab job scheduler 2026-07-12 11:57:06 +02:00
docs update images 2026-07-12 19:27:32 +02:00
src Improve SFTP upload functionality to mirror local directory structure 2026-07-12 18:50:21 +02:00
docker-compose.yml Update Docker Compose to use the correct image for pgbuddy service 2026-07-06 19:03:24 +02:00
Dockerfile Add SFTP mirror functionality for backup uploads (mirror) 2026-07-10 20:53:54 +02:00
LICENSE change LICENSE to AGPL3.0 2026-07-05 11:26:01 +02:00
README.md update images 2026-07-12 19:27:32 +02:00

pgBuddy

cargo spaceship

A tiny web UI to back up and restore multiple PostgreSQL databases from a single Docker container. Backups are made with pg_dump / pg_restore, backup jobs are scheduled with an in-container cron, and you get an e-mail when a scheduled backup fails.

Quick start

git clone https://forgejo.hostlab.tech/suitdeer/pgbuddy.git
cd pgbuddy
docker compose up -d

Then open http://localhost:8080 and log in with admin / admin (change it in Settings).

Persistent data lives under ./data/:

  • ./data/config/config.json — your config (DBs, jobs, auth, mail).
  • ./data/config/rate.json — Login is rate-limited (10 attempts per 15 minutes per IP).
  • ./data/backups/ — the generated dump files.

The container timezone is set via the BACKUP_TIMEZONE env var (defaults to UTC; the bundled docker-compose.yml sets Europe/Berlin).

Pictures

A list of all your databases that are connected to pgBuddy.


If you click on "List Backups" you can see all the backups of one database. You can download, restore and delete each database backup if you want.


For each database connection you can create one or more automatic backup jobs (cron-jobs).


In the settings menu you can.

  • Change the current account name and password (stronly recommended to change the initial password).
  • Enable e-mail notification for failed backup jobs.
  • Add a secound (external) backup location via SFTP (mirror of local backup).

Components

  • Web stack: plain PHP (server-rendered).
  • Styling: Bootstrap 5.3 (local).
  • Auth: single user (session login) with integrated rate-limiting.
  • Adding a DB: a friendly Name + DB URL (host:port/dbname) + DB Username + DB Password.
  • Jobs: configure cron schedules from the UI; a 1-minute cron runner inside the container executes due jobs. Each job can auto-delete older backups via a Keep retention setting.
  • E-Mail: e-mail notification on job failure (via msmtp/SMTP).
  • SFTP mirror: every successful backup can be uploaded automatically to a remote SFTP server for off-site redundancy.

Scheduling backups

Backup Jobs → + Add job: pick a database, a 5-field cron expression (e.g. 0 2 * * * = daily at 02:00), a format, and a Keep retention count:

  • custompg_dump -Fc, restored with pg_restore.
  • plainpg_dump -Fp, restored with psql.
  • Keep — number of newest backups to keep for the database; 0 keeps all. Older backups are pruned after each successful job run.

The container runs cron.php every minute; any job whose cron expression matches the current minute is executed. You can also Run now from the UI.

Backup / restore

Databases → Backups for a DB lets you:

  • Backup now (ad-hoc),
  • Download a dump,
  • Restore (overwrites the target DB — pg_restore --clean --if-exists or psql -f),
  • Delete a file.

E-mail on failure

  1. In Settings, fill in the SMTP fields (host, port, user, password, From address) and a recipient, then tick Enable failure notifications. TLS is always enabled: port 465 uses implicit TLS (SMTPS), other ports use STARTTLS.
  2. Use Send test e-mail to verify delivery.
  3. A failed scheduled job sends an e-mail via msmtp using the settings stored in config.json.

SFTP mirror

  1. In Settings, fill in the SFTP fields (host, port, user, password, remote directory) and tick Enable SFTP mirror.
  2. Use Test connection to verify credentials.
  3. Every successful backup — both ad-hoc and scheduled — is uploaded to the remote path right after it is created locally. A failed upload does not delete the local copy; it is reported in the backup message.

Notes / limitations

  • DB passwords and SFTP credentials are stored in config.json (the container-local config volume) — protect that volume.
  • The cron runner matches jobs to the minute, so the shortest interval is 1 minute.
  • Restore uses --clean --if-exists; review dumps before restoring into production.

Future features :)

  • Upload/import an existing dump file to restore it into a database.

  • Success notifications in addition to failure alerts (per-job opt-in).

    Could get out of hand (spam). Hmmm.

  • Internationalization / multi-language UI.

    If some one want it, sure ;)

  • Multi-user support with roles (admin / read-only viewer).

    If I have more free time perhaps in the distant future ;)

  • API (token-authenticated JSON) for integration with external automation.

    I want to keep it simple but if it is requested I might implement it. Also distand future ;)

LICENSE

All contents of this project are protected by the AGPL3.0 LICENSE