PostgreSQL 跑在 Docker 里怎么备份?恢复成功才算备份成功

PostgreSQL 跑在 Docker 里怎么备份?恢复成功才算备份成功

很多自托管应用背后都有 PostgreSQL:书签、财务、知识库、自动化平台。最危险的备份方式,是只把 postgres_data 目录压缩走,等换机器恢复时才发现版本、权限、WAL 状态都对不上。本文给一套适合个人服务器的 Docker PostgreSQL 备份恢复流程。

备份到底要备什么

最小可用备份包括:数据库逻辑导出、compose.yaml.env、应用上传目录。数据库导出负责恢复数据表,配置文件负责恢复连接信息,上传目录负责恢复附件。只备其中一个都不完整。

逻辑导出适合个人和小团队,因为它更容易跨机器、跨小版本恢复。体量很大的数据库才需要额外设计物理备份、WAL 归档和备机。

服务器规格建议

PostgreSQL 对内存和磁盘稳定性比较敏感。轻量应用可以 2 核 4G 起步,多个应用共用一套数据库建议 4 核 8G。备份时会产生压缩文件和临时 I/O,系统盘太小会让备份脚本自己把机器写满。

我会把 PostgreSQL 和两三个中小型自托管应用放在雨云服务器 rainyun-com 的 2 核 4G 或 4 核 8G 机型上,重点关注磁盘和备份空间。注册填优惠码 2026off 领 5折,省下来的预算优先给快照和异地备份,而不是只看 CPU。

Compose 示例

下面只是通用示例,发布前要按具体应用官方文档确认数据库版本和环境变量:

yaml 复制代码
services:
  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD: change-this-password
    volumes:
      - ./postgres-data:/var/lib/postgresql/data

不要把数据库端口直接映射到公网。应用和数据库在同一个 Compose 网络里通信即可,除非你明确需要远程管理,并且已经做好防火墙和访问控制。

备份脚本怎么写

可以用 pg_dump 从容器里导出,再压缩保存:

bash 复制代码
#!/usr/bin/env bash
set -euo pipefail

APP_DIR=/opt/myapp
BACKUP_DIR=/opt/backups/myapp
STAMP=$(date +%F-%H%M)

mkdir -p "$BACKUP_DIR"
cd "$APP_DIR"

docker compose exec -T postgres pg_dump -U app -d app \
  | gzip > "$BACKUP_DIR/postgres-$STAMP.sql.gz"

tar -czf "$BACKUP_DIR/config-$STAMP.tar.gz" compose.yaml .env uploads
find "$BACKUP_DIR" -type f -mtime +14 -delete

如果数据敏感,备份文件要加密后再同步到异地,不要直接放公开网盘。至少每月做一次恢复演练,不然你只能证明"脚本会生成文件",不能证明"数据能回来"。

恢复演练

恢复不要直接在生产机上练。开一台临时机器,复制备份文件,启动同版本 PostgreSQL,再导入:

bash 复制代码
gzip -dc postgres-2026-06-10-0300.sql.gz \
  | docker compose exec -T postgres psql -U app -d app

验证标准不是命令退出 0,而是应用能登录、列表能打开、附件能下载、关键数据数量大致对得上。演练完成后销毁临时机器,避免测试环境继续暴露。

常见问题

pg_dump 报认证失败,多半是用户名、数据库名或环境变量和实际不一致。导入时报对象已存在,说明目标库不是空库。恢复后中文乱码,通常是客户端环境或导入方式有问题,优先保持 PostgreSQL 默认 UTF-8。

如果数据库很大,不要在业务高峰压缩备份。可以先降低压缩级别,或者把备份放到业务低谷执行。

总结

PostgreSQL 的备份不能只看有没有文件,要看能不能在另一台机器恢复。逻辑导出、配置备份、异地保存、恢复演练,四步缺一不可。

如果你想低成本做恢复演练,可以临时开一台雨云服务器 rainyun-com 做测试机,注册填优惠码 2026off 领 5折。把恢复流程跑通后,再处理生产环境会踏实很多。

相关推荐
白帽小丑38 分钟前
# 一次 MySQL DELETE 误操作的数据恢复尝试实录
数据库·mysql
Quincy_Freak3 小时前
信创内网数据规范实践:银河麒麟下SQLite本地数据安全管理方案
数据库·sqlite·arm·数据库管理·大数据分析·银河麒麟·aarch64
2601_962683895 小时前
治理遗留系统中的“生肉 SQL”:一次用多模型协作优化慢查询的实战复盘
数据库·人工智能·sql
酱学编程6 小时前
【从零到一实现一个 AI Agent 框架 · 第四篇】04. 任务规划:拆解复杂目标 -
服务器·网络·数据库·人工智能
程序员老油条6 小时前
WSL2 + Docker Desktop:Windows 下的完美 Java 开发环境
java·windows·docker·wsl2
shushangyun_7 小时前
2026智能采购商城系统选型指南:如何引领企业数字化采购升级
java·大数据·数据库·人工智能·机器学习
大侠锅锅7 小时前
第 4 篇:策略模式实践——用统一接口管理 Docker 容器、原生进程与 K3s Pod
docker·容器·边缘计算·策略模式·iot
华山令狐虫8 小时前
DBAPI AI 写 SQL:支持动态 SQL 与参数占位符,自然语言一键生成
数据库·人工智能·sql·dbapi
IvorySQL8 小时前
PG 技术日报|2026-07-04
数据库·人工智能·postgresql·开源
Hoxy.R8 小时前
KingbaseES读写分离高可用集群扩容、备库重建与故障切换实战
运维·数据库