- PHP 95.8%
- Shell 2.4%
- Dockerfile 1.8%
| .forgejo | ||
| docker | ||
| docs | ||
| src | ||
| docker-compose.yml | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
pgBuddy
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:
custom—pg_dump -Fc, restored withpg_restore.plain—pg_dump -Fp, restored withpsql.- Keep — number of newest backups to keep for the database;
0keeps 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-existsorpsql -f), - Delete a file.
E-mail on failure
- 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.
- Use Send test e-mail to verify delivery.
- A failed scheduled job sends an e-mail via
msmtpusing the settings stored inconfig.json.
SFTP mirror
- In Settings, fill in the SFTP fields (host, port, user, password, remote directory) and tick Enable SFTP mirror.
- Use Test connection to verify credentials.
- 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



