用于 Docker PostgreSQL 项目的逻辑备份与集中管理。
server/ 服务器端:执行 pg_dump,生成校验后的归档,并只读 SFTP 提供下载
local/ 本地端:通过 Web 管理项目、密钥、日志与备份文件,主动经 SFTP 拉取归档
本地端不运行 PostgreSQL 服务;仅包含 SFTP、tar、SHA256 和 PostgreSQL 18 pg_restore,用于传输与校验备份。
- 每台服务器的 root 定时执行
pg-backup-postgres。 - 脚本从 Docker Compose 中的 PostgreSQL 服务执行
pg_dump、pg_dumpall --globals-only。 - 服务器生成
backup-*.tar与对应 SHA256 文件。 - 本地端按定时规则主动通过 SFTP 拉取、校验、保存和清理归档。
本地端没有公网 IP 不影响使用;只要求它能访问服务器的 SSH 端口。
- Web 管理多台服务器、多个 PostgreSQL 项目。
- 上传并管理本地端 SSH 私钥。
- 首次连接自动信任 SSH 主机指纹,之后指纹变更会拒绝连接。
- 支持立即拉取单个项目或全部项目,也支持 CRON 定时拉取。
- 分页校验、下载、浏览与清理备份文件。
- 增量加载运行日志,可手动清空;服务端日志文件超过 10 MB 时自动仅保留最近 2 MB。
- 支持多选删除。提交删除前必须手动输入随机生成的 6 位验证码;验证码仅绑定当前所选文件,5 分钟有效,成功后立即失效。
.
├── local/
│ ├── Dockerfile
│ ├── docker-compose.yml
│ ├── .env.example
│ └── main.go
└── server/
├── install-backup-server.sh
├── backup-postgres.sh
└── projects.conf.example
以 Debian / Ubuntu 为例:
sudo apt update
sudo apt install -y postgresql-client openssh-server cron tar coreutils服务器必须已安装 Docker 与 Docker Compose 插件,并且 PostgreSQL 服务由 Compose 管理。
在运行 local 容器的设备上生成独立密钥。不要复用日常登录服务器的私钥:
ssh-keygen -t ed25519 -a 64 -f ~/.ssh/id_ed25519_pg_backup -C pg-backup-local生成后有两个文件:
~/.ssh/id_ed25519_pg_backup 私钥,只保存在本地端
~/.ssh/id_ed25519_pg_backup.pub 公钥,用于配置服务器
将 server/ 目录和本地生成的公钥文件 id_ed25519_pg_backup.pub 上传到服务器。例如将公钥上传为 /root/id_ed25519_pg_backup.pub。
cd server
sudo bash ./install-backup-server.sh \
--public-key-file /root/id_ed25519_pg_backup.pub \
--backup-root /srv/pg-backups \
--schedule '0 3 * * *' \
--retention-days 14安装完成后,backupread 是受限只读 SFTP 用户:无密码登录、无终端、无端口转发、无 sudo、也不属于 Docker 组。私钥始终保留在本地端;仅 .pub 公钥文件会短暂上传到服务器,安装完成后可删除该公钥上传文件。
创建配置文件:
sudo cp projects.conf.example /etc/pg-backup/projects.conf
sudo chmod 600 /etc/pg-backup/projects.conf
sudo editor /etc/pg-backup/projects.conf每行格式:
项目标识|项目目录|Compose文件|环境文件或-|PostgreSQL服务|数据库用户或env:变量名|数据库名或env:变量名|密码环境变量名或-
示例:
store|/srv/store|/srv/store/docker-compose.prod.yml|/srv/store/.env.prod|postgres|env:POSTGRES_USER|env:POSTGRES_DB|POSTGRES_PASSWORD
billing|/srv/billing|/srv/billing/docker-compose.yml|-|db|postgres|billing|POSTGRES_PASSWORD
- 用户名和数据库名可填写字面量,也可写为
env:变量名,后者会从 PostgreSQL 容器环境变量中读取。 - 最后一列填写容器内的密码环境变量名,例如
POSTGRES_PASSWORD;不填写实际密码。若不需要密码认证,填写单独的-。 - PostgreSQL 用户必须能执行
pg_dump与pg_dumpall --globals-only。 - 项目目录、Compose 文件、环境文件及其父目录必须由 root 所有,且不能被组或其他用户写入。
首次手动生成备份:
sudo /usr/local/sbin/pg-backup-postgres
sudo find /srv/pg-backups/data -maxdepth 2 -type f -name 'backup-*' -ls每个归档包含:
database.dump
globals.sql
manifest.json
cd local
cp .env.example .env编辑 .env,至少设置一个长度不小于 12 位的管理密码:
ADMIN_PASSWORD=请替换为高强度随机密码
DATA_DIR=./data启动:
docker compose up -d --build默认访问地址:
http://<本地端地址>:8088
浏览器用户名固定为 admin,密码为 ADMIN_PASSWORD。
生产环境请在反向代理配置 HTTPS 后再暴露 Web 界面;HTTP Basic Auth 不适合通过未加密的公网 HTTP 使用。
- 在 SSH 私钥 页面上传
~/.ssh/id_ed25519_pg_backup。 - 在 项目 页面添加服务器项目。
- 点击项目行的 拉取。
- 在 运行日志 确认拉取完成。
- 在 备份文件 确认归档校验状态为“通过”。
项目配置示例:
| 字段 | 示例 |
|---|---|
| 项目标识 | store-prod |
| 显示名称 | 商城生产库 |
| 服务器地址 | 203.0.113.10 |
| SSH 端口 | 22 |
| SSH 用户 | backupread |
| 私钥文件 | id_ed25519_pg_backup |
| 服务器项目标识 | store |
服务器项目标识必须与 /etc/pg-backup/projects.conf 的首列完全一致。
首次成功连接会在 ${DATA_DIR}/ssh/known_hosts 自动保存服务器主机指纹。服务器确实重装或更换 SSH 主机密钥时,点击项目行的 重置信任,下次拉取才会重新信任新指纹。
默认按照 Asia/Shanghai 时区执行:
30 3 * * * 每天 03:30
保留 30 天
在 项目 -> 定时与保留 中修改。支持标准五段 CRON:
0 */6 * * * 每 6 小时
30 3 * * * 每天 03:30
0 4 * * 1-5 工作日 04:00
定时拉取与手动拉取不会并发执行。
DATA_DIR 包含所有运行数据,必须持久化并妥善保护:
data/
├── projects.json 项目和定时配置
├── ssh/
│ ├── id_ed25519_* 本地端私钥
│ └── known_hosts 自动维护的主机指纹
├── backups/
│ └── <项目标识>/
│ ├── backup-*.tar
│ └── backup-*.tar.sha256
└── logs/
└── app.log
上传私钥后,确认文件权限为仅所有者可读写:
chmod 600 data/ssh/id_ed25519_pg_backup恢复前应先在测试 PostgreSQL 实例验证。解包后恢复数据库:
mkdir restore-test
tar -xf backup-*.tar -C restore-test
createdb restore_test
pg_restore --clean --if-exists --no-owner --no-acl \
-d restore_test restore-test/database.dumpglobals.sql 会影响实例级角色和权限。执行前必须审查其内容:
psql -d postgres -f restore-test/globals.sql