外观
PostgreSQL:给其他应用提供数据库
很多自托管应用需要一个数据库。这一页讲通用的部署和备份方式。
数据库不能靠直接复制文件来备份
在数据库运行期间直接复制数据目录,得到的副本很可能是不一致的,恢复时报错。必须用数据库自己的导出工具,或者在完全停止容器后再复制。
部署
yaml
services:
db:
image: postgres:16
container_name: app-db
restart: unless-stopped
environment:
POSTGRES_DB: appdb
POSTGRES_USER: appuser
POSTGRES_PASSWORD: 用强密码替换
volumes:
- /vol1/docker/app/db:/var/lib/postgresql/data要点:
- 固定主版本号(这里是
16),不要用latest。PostgreSQL 跨主版本升级需要执行数据迁移,镜像自动跳版本会导致容器起不来。 - 不要映射端口到宿主机,除非确实需要从外部连接。同一个 compose 网络内的应用容器用服务名(这里是
db)就能访问。 - 数据目录建议放在固态盘上,机械盘上的随机写入会让硬盘无法休眠。
备份
用 pg_dump 导出逻辑备份:
sh
docker exec app-db pg_dump -U appuser -d appdb > /vol1/backup/appdb-$(date +%F).sqldocker exec 在运行中的容器里执行命令;-U 指定用户;-d 指定数据库;输出重定向到一个带日期的文件。把这条命令做成每日定时任务,并设置失败通知。
恢复时,把 SQL 文件导入一个空数据库即可。恢复流程要实际演练过,见恢复演练。
升级主版本
- 用
pg_dump导出完整备份。 - 停止并删除旧容器(保留数据目录)。
- 把数据目录移到别处存档,创建一个新的空目录。
- 用新版本镜像启动,导入备份。
- 验证应用能正常工作后,再考虑清理存档。
跳过第 1 步直接换镜像版本,容器会因数据目录版本不匹配而拒绝启动。
已知坑
- 密码写在 compose 文件里,注意这个文件的权限,也不要提交到公开仓库。
- 多个应用共用一个数据库实例可以省资源,但升级时会互相牵制,新手建议每个应用独立一个。
- 数据库容器占用内存不低,规划时算进去。