Docker部署PostgreSQL后如何实现定期自动备份至NAS?
PostgreSQL容器化自动备份方案(基于pg_dump)
pg_dump是PostgreSQL官方提供的热备份工具,支持在线备份无需停止数据库,完全解决你之前停库备份的痛点。下面提供几种实用的自动备份方案:
方案一:直接在宿主机定时执行备份命令
手动执行备份
直接通过Docker命令在运行的PostgreSQL容器内执行pg_dump,备份文件保存到Windows本地:
# PowerShell 命令(带时间戳,避免覆盖) docker exec imatecTest pg_dump -U root test | Out-File "D:\postgres_backups\backup_$(Get-Date -Format 'yyyyMMdd_HHmmss').sql" -Encoding utf8
或者用CMD:
docker exec imatecTest pg_dump -U root test > D:\postgres_backups\backup_%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%.sql
自动定时备份
在Windows上通过任务计划程序创建定时任务:
- 新建任务,设置触发时间(比如每天凌晨2点)
- 操作选择「启动程序」,程序/脚本填
powershell.exe,添加参数填上面的PowerShell命令 - 确保任务执行账户有Docker操作权限和备份目录的读写权限
方案二:扩展Docker Compose,添加自动备份服务
通过新增一个备份服务,用cron定时执行备份,适合容器化环境的统一管理:
1. 创建备份脚本
在本地创建backup.sh文件(注意编码为UTF-8无BOM):
#!/bin/bash # 创建备份目录(如果不存在) mkdir -p /backups # 生成带时间戳的备份文件名 DATE=$(date +%Y%m%d_%H%M%S) # 执行备份,压缩文件节省空间 pg_dump -U $POSTGRES_USER $POSTGRES_DB | gzip > /backups/backup_$DATE.sql.gz # 清理7天前的旧备份 find /backups -name "backup_*.sql.gz" -mtime +7 -delete
给脚本添加可执行权限:
# Windows上用WSL或者Git Bash执行 chmod +x backup.sh
2. 修改Docker Compose文件
更新你的docker-compose.yml,添加备份服务并挂载数据卷:
version: '3.8' services: db: container_name: imatecTest image: postgres restart: always environment: POSTGRES_USER: root POSTGRES_PASSWORD: root POSTGRES_DB: test ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./local_backups:/backups # 挂载本地备份目录到容器 pgadmin: container_name: pgadmin4 image: dpage/pgadmin4 restart: always environment: PGADMIN_DEFAULT_EMAIL: admin@admin.com PGADMIN_DEFAULT_PASSWORD: root ports: - "5050:80" db_backup: image: postgres restart: always volumes: - ./local_backups:/backups - ./backup.sh:/backup.sh environment: POSTGRES_USER: root POSTGRES_PASSWORD: root POSTGRES_DB: test POSTGRES_HOST: db # 连接到db服务(Docker内部网络) # 设置cron定时:每6小时备份一次(可修改为0 2 * * * 每天凌晨2点) command: bash -c "echo '0 */6 * * * /backup.sh' | crontab - && crond -f" volumes: postgres_data: # 正式环境建议用命名卷管理数据,比直接挂载目录更稳定
说明
- 备份服务复用postgres镜像,自带pg_dump工具,无需额外安装
- cron表达式可根据需求调整,比如
0 2 * * *表示每天凌晨2点执行一次 - 脚本自动压缩备份并清理旧文件,避免磁盘溢出
方案三:全量备份所有数据库
如果需要备份PostgreSQL实例中的所有数据库,用pg_dumpall替换pg_dump即可:
# 手动全量备份 docker exec imatecTest pg_dumpall -U root | Out-File "D:\postgres_backups\full_backup_$(Get-Date -Format 'yyyyMMdd_HHmmss').sql" -Encoding utf8
自动备份同理替换命令即可。
备份恢复方法
需要恢复时,执行以下命令:
# 恢复单个数据库 docker exec -i imatecTest psql -U root test < D:\postgres_backups\backup_xxxx.sql # 恢复全量备份(注意先停止应用,避免数据冲突) docker exec -i imatecTest psql -U root < D:\postgres_backups\full_backup_xxxx.sql # 如果是压缩备份,先解压再恢复 gzip -d backup_xxxx.sql.gz docker exec -i imatecTest psql -U root test < backup_xxxx.sql
注意事项
- 定期验证备份:将备份文件恢复到测试环境,确保备份有效,避免真正需要时发现备份损坏
- 权限设置:Windows挂载的目录,容器内可能需要设置读写权限,可在backup.sh开头添加
chmod 777 /backups(生产环境建议更严格的权限) - 离线备份补充:如果需要更完整的离线备份,可在备份完成后,用Docker命令备份命名卷:
docker run --rm -v postgres_data:/data -v D:\postgres_volume_backups:/backup busybox tar czf /backup/volume_backup_$(date +%Y%m%d).tar.gz /data
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

