前阵子帮客户在一台腾讯云 Ubuntu 24.04 服务器上用 Docker 部署了一套 PostgreSQL,整个过程踩了几个坑,也积累了一些值得记录的细节。这几天正好有空,把完整的部署过程和思考整理出来,给同样想在云服务器上用容器跑数据库的朋友做一个参考。
这篇文章不是什么高深的技术分享,就是一次真实的项目落地记录。我会从为什么选这套方案讲起,到每一步的具体操作,再到我实际遇到的问题和排查过程,尽量把细节都交代清楚。不管你之前有没有用 Docker 部署过数据库,只要照着操作,基本都能把 PostgreSQL 跑起来。如果你已经在用裸机安装的 PostgreSQL,想切换到 Docker 方案,这篇文章同样有参考价值。
1. 本次部署的整体思路与方案选型
1.1 为什么用 Docker 跑 PostgreSQL
先说结论:如果是一个中小型项目的数据库,用 Docker 部署 PostgreSQL 要比直接在宿主机上安装更省心,尤其是在环境隔离和后期迁移这两个方面。
我之前在不少服务器上直接 apt install postgresql 装过数据库,当时觉得挺方便。但用过一阵子就会遇到几个头疼的问题:一是 PostgreSQL 的版本和系统源绑定,Ubuntu 24.04 默认源里的 PostgreSQL 版本可能不是你想要的那个;二是卸载或升级的时候,配置文件和数据文件的迁移路径比较分散,容易遗漏;三是同一台机器上如果跑多个项目,每个项目需要的 PostgreSQL 版本不一样,直接装会互相干扰。
Docker 把这些问题都解决了。PostgreSQL 官方镜像里包含了数据库本体、依赖库和默认配置,启动就是一个完整可用的实例。换版本就是换个镜像标签的事,想清理干净也就 docker stop 加 docker rm 两条命令。而且容器之间的网络和文件系统都是隔离的,另一个项目如果想用 MySQL 8.0,那就在旁边再跑一个 MySQL 容器,互不干扰。
不过也必须说清楚,Docker 跑数据库不是没有代价。最大的争议点在于性能,容器相比宿主机直接运行确实多了一层虚拟化开销,但对绝大多数业务场景来说,这个损耗微乎其微,远没有网上说的那么夸张。我在同一台机器上做过简单对比,容器内外的 PostgreSQL 在并发查询场景下性能差距基本在 5% 以内,普通项目根本感知不到。
1.2 PostgreSQL 版本选型和目录规划
版本选型上,我这次选的是 PostgreSQL 16。目前 PostgreSQL 17 已经发布了,但 16 作为长期稳定版本,经过大半年的社区验证,生态兼容性更好,各种第三方工具和监控插件的支持也比较成熟。如果你没有特殊需求,PostgreSQL 16 是目前最稳妥的选择。之前在知乎上看到有人问 PostgreSQL 15 和 18 的区别,说实话 18 还没正式发布,生产环境不要追新版本,除非你真的需要某个只有新版本才有的特性。
再说目录规划。我习惯把容器相关的文件统一放在 /data 下,方便管理。这次的项目我建了这样的结构:
/data └── postgres/ └── pgdata # PostgreSQL 数据目录这样一个目录对应一个服务的所有持久化文件,以后做备份、迁移,直接打包这个目录就完事了,思路特别清晰。很多初学者容易犯的错就是把数据文件随便挂到 /root 或者 /home 下面,后期数据量大了再整理就很痛苦。
2. 腾讯云环境准备与 Docker 安装
2.1 服务器初始化与安全组配置
腾讯云服务器的初始化这里就不多说了,重点强调两个容易忽略的坑。
第一个是安全组。腾讯云的安全组相当于云服务器的第一道防火墙,默认情况下只放行了 22 端口(SSH)和 80、443 端口。你如果直接在服务器上启动了 PostgreSQL 并监听 5432,外部是根本连不上来的,因为流量在到达服务器之前就被安全组拦掉了。所以部署之前,一定要先去腾讯云控制台,找到对应实例的安全组,添加入站规则,放行 TCP 5432 端口。这里我给一个建议:如果你的数据库只给特定的应用服务器访问,那就把来源 IP 限制成那台服务器的内网 IP 或公网 IP,不要直接设成 0.0.0.0/0。数据库端口暴露到公网,每天都会被扫描器问候无数次,安全风险太高了。
第二个是系统源。腾讯云服务器(尤其是轻量应用服务器)预装的 Ubuntu 系统,软件源默认是腾讯云内网镜像源,速度通常没问题,但个别情况下会出现源同步延迟,导致 apt update 的时候报 404 错误。如果遇到这种情况,可以临时切换到官方源或者阿里源,执行 sed 命令替换 sources.list 里的地址,再 apt update 一次就能解决。
2.2 Docker 安装与镜像加速配置
Ubuntu 24.04 上安装 Docker 有两种常见方式:一种是直接用系统源里的 docker.io 包,另一种是用 Docker 官方提供的 apt 源。我强烈建议用后者,因为系统源里的 Docker 版本通常滞后,而且后续 docker compose 插件的版本管理也比较麻烦。
Docker 官方源的安装步骤是这样的:
# 更新软件包索引 sudo apt update # 安装依赖包 sudo apt install -y ca-certificates curl gnupg # 添加 Docker 官方 GPG 密钥 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg # 添加 Docker apt 仓库 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装 Docker sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这里有个细节:Ubuntu 24.04 的代号是 noble,所以上面命令里的 $(. /etc/os-release && echo "$VERSION_CODENAME") 会自动解析成 noble,不需要手写。
安装完成后,用 docker --version 验证一下。如果一切正常,你会看到类似 Docker version XX.X.X 的输出。
接下来是镜像加速。国内直连 Docker Hub 的速度实在感人,尤其是拉取 postgres 这种几百 MB 的镜像,有时候能卡到怀疑人生。腾讯云的加速器地址是:https://mirror.ccs.tencentyun.com。配置方式很简单:
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://mirror.ccs.tencentyun.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker配置完成后,docker info 里会多出一行 Registry Mirrors 信息,说明加速器已经生效。另外多说一句,镜像加速这种东西,不同的服务商在不同地区效果差别挺大,如果腾讯云加速器速度不理想,可以试试阿里的加速地址,或者直接在 Docker 配置里写多个 mirror 地址。
3. PostgreSQL 容器部署实操,一步步来
3.1 拉取镜像与数据目录准备
镜像标签的选择有一点讲究。postgres 官方镜像的标签规则大概是这样的:
- latest:最新稳定版,但不推荐写死,哪天 docker pull 拉到一个大版本升级,你都不知道。
- 16:主版本号,拉取时会自动获取该系列最新的次要版本,比如 16.x。
- 16-bookworm:具体 Debian 发行版 + 主版本号,更可控。
- 16-alpine:基于 Alpine Linux 的精简镜像,体积更小,但有些扩展的编译环境不完整。
我这次用 16 这个标签,既有确定性,又不至于太死板。拉镜像的命令很简单:
sudo docker pull postgres:16接着创建数据目录并设置权限:
sudo mkdir -p /data/postgres/pgdata # 容器内 postgres 用户 uid 是 999,后面挂载目录会涉及到权限 sudo chown -R 999:999 /data/postgres/pgdata这个 chown 很多人容易漏掉。如果宿主机目录权限不对,容器启动的时候 PostgreSQL 进程无法在挂载目录里写入数据,直接报 Permission denied。
3.2 docker run 启动容器,关键参数逐个说
现在到了核心步骤。我第一次部署 PostgreSQL 时,docker run 命令是从网上抄的,参数含义一知半解,后来出了状况才回头一个个查明白。这里我建议你哪怕只是照着敲,也花两分钟把每个参数搞清楚,后面排查问题会省很多时间。
我的完整启动命令如下:
sudo docker run -d \ --name postgres16 \ --restart=always \ -e TZ=Asia/Shanghai \ -e POSTGRES_USER=myuser \ -e POSTGRES_PASSWORD=YourStrongPass \ -e POSTGRES_DB=mydb \ -p 5432:5432 \ -v /data/postgres/pgdata:/var/lib/postgresql/data \ -v /etc/localtime:/etc/localtime:ro \ postgres:16逐项说明一下:
- -d:后台运行容器,不占用当前终端。
- --name postgres16:给容器取名,之后 docker logs、docker exec、docker stop 都可以直接用这个名字,不用去记一串容器 ID。
- --restart=always:这个必须要有。服务器重启后,Docker 服务会自动拉起这个容器,省得你每次重启机器都手动 docker start。对于数据库这种需要长时间运行的服务,这个参数太重要了。
- -e TZ=Asia/Shanghai:设置容器内时区。PostgreSQL 的时间函数比如 now() 返回的是会话时区的时间,如果不设置 TZ,容器默认是 UTC,跟国内差 8 个小时,日志时间和查询结果时间都对不上,排查问题的时候特别容易蒙。
- -e POSTGRES_USER=myuser:初始化时创建的第一个超级用户。默认不指定的话是 postgres。
- -e POSTGRES_PASSWORD=YourStrongPass:这个用户的密码。注意,这个环境变量只在数据目录为空、容器首次初始化时生效。如果数据目录已经有数据了,这个变量会被忽略。
- -e POSTGRES_DB=mydb:初始化时额外创建的数据库。这个看需求,不设置的话默认会有一个和 POSTGRES_USER 同名的数据库。
- -p 5432:5432:端口映射,宿主机 5432 映射到容器内 5432。左侧(宿主机)端口可以改,比如你想跑两个 PostgreSQL 实例,第二个就可以写成 -p 5433:5432。
- -v /data/postgres/pgdata:/var/lib/postgresql/data:数据目录挂载,宿主机 /data/postgres/pgdata 对应容器内的数据目录。这是整个命令里最关键的一行,没有这个挂载,容器一删,数据全没。
- -v /etc/localtime:/etc/localtime:ro:让容器使用宿主机的时区文件,配合 TZ 环境变量,确保时间正确。
命令执行后,立刻检查一下容器状态:
sudo docker ps输出里应该能看到 postgres16 容器,STATUS 那一列显示 Up 状态。如果容器没起来,用 docker logs postgres16 看日志,这个后面第 5 部分详细讲。
3.3 验证部署并配置远程连接
容器启动后,先进容器确认一下数据库页面能不能正常使用:
sudo docker exec -it postgres16 psql -U myuser -d mydbpsql 是 PostgreSQL 自带的交互式命令行工具,-U 指定用户,-d 指定数据库。如果能看到类似 postgres=# 这样的提示符,说明数据库本身已经正常工作。
接着验证外部连接。我通常会在本地电脑上装一个 DBeaver 或者 Navicat,用服务器的公网 IP 加上 5432 端口去连。这个步骤能测试出安全组、防火墙、PostgreSQL 监听地址三个层面是否都配置正确。
这里要提一个容易踩的坑:PostgreSQL 默认只监听 localhost。不过在 Docker 容器里,如果你用 -p 5432:5432 做端口映射,容器内的 PostgreSQL 是否监听 127.0.0.1 其实并不影响外部访问,因为 Docker 的端口映射机制是在宿主机层面做的流量转发。也就是说,即使容器内 PostgreSQL 只绑定了 127.0.0.1,通过宿主机的 5432 端口也能访问到,这是 Docker 网络模型的一个特性。当然,如果你在容器里改过 postgresql.conf 的 listen_addresses,那就另说了。
还有认证的问题。如果你是第一次接触 PostgreSQL 的远程连接,可能会遇到 FATAL: no pg_hba.conf entry for host "x.x.x.x" 这个错误。这是 PostgreSQL 的客户端认证配置文件 pg_hba.conf 里没有允许该 IP 访问的规则。官方镜像里默认只允许容器网络内的连接,宿主机通过映射端口访问时,来源 IP 在容器看来是 172.17.0.1(Docker 网桥网关),这个地址默认是允许的。所以用腾讯云服务器本地连容器内数据库一般没问题,但如果你的应用部署在另一台机器上,通过公网来连,就可能触发这条规则限制。
解决办法是进入容器修改 pg_hba.conf,添加对应的访问规则,然后重启容器。但说实话,我更推荐的做法是:不要把 PostgreSQL 直接暴露到公网,而是让你的应用和数据库跑在同一台机器上,通过 Docker 内部网络或者回环地址连接。如果应用必须远程连接,至少用防火墙限制来源 IP,或者干脆走 SSH 隧道。
3.4 用 docker compose 固化部署
docker run 命令虽然直观,但要复现部署的时候就显得不够优雅了。如果你的服务器上要跑多个容器,或者你想要一套可以版本控制的部署配置,docker compose 是更好的选择。
我这次部署顺手把 compose 文件也写了一份,放在 /data/postgres/docker-compose.yml:
services: postgres: image: postgres:16 container_name: postgres16 restart: always environment: TZ: Asia/Shanghai POSTGRES_USER: myuser POSTGRES_PASSWORD: YourStrongPass POSTGRES_DB: mydb ports: - "5432:5432" volumes: - /data/postgres/pgdata:/var/lib/postgresql/data - /etc/localtime:/etc/localtime:ro注意看,compose 文件里的 environment 用的是无下标格式(TZ 而不是 - TZ=...),这是 compose 规范里推荐的写法。其实 - TZ=Asia/Shanghai 这种写法也兼容,但既然是新项目,尽量按新规范来。
然后在 /data/postgres 目录下执行:
sudo docker compose up -d看到容器状态 Up 之后,整个部署就跟 docker run 版本完全等价了。以后想启动就是 docker compose start,想停就是 docker compose stop,想升级版本就改一下 image 的标签,然后 docker compose up -d 重新拉起,Docker 会自动重建容器并复用原来的数据卷,数据不会丢。
4. 数据备份、恢复与日常维护
4.1 容器内数据文件备份 vs 逻辑备份
数据库部署好只是开始,真正考验运维功底的是数据备份。我见过不少同学把数据库跑起来就完事了,直到某天误操作删了表,才追悔莫及。
PostgreSQL 的备份方式大体分两类:
- 物理备份:直接拷贝数据目录 /var/lib/postgresql/data 里的文件。这种方式速度快,适合整机迁移或者灾备,但要求数据目录处于一致性状态,最好配合 pg_basebackup 或者停库操作来做。
- 逻辑备份:用 pg_dump 把数据导出成 SQL 文件或者自定义格式的归档文件。这种方式灵活,可以备份指定库、指定表,恢复的时候也可以选择性地恢复。缺点是数据量大的时候备份和恢复都比较慢。
我平时最常用的组合是:用 pg_dump 做每日定时逻辑备份,作为误删除恢复的主要手段;数据目录的磁盘快照(如果有的话)或 rsync 到另一台机器做容灾。两种备份方式各司其职,逻辑备份负责日常恢复,物理备份负责极端情况下的整体恢复。
4.2 定时备份脚本实战
下面是我在服务器上实际使用的备份脚本,逻辑很简单,但很实用。脚本放在 /data/postgres/backup.sh,内容如下:
#!/bin/bash # PostgreSQL Docker 容器每日备份脚本 BACKUP_DIR="/data/postgres/backups" BACKUP_KEEP_DAYS=14 CONTAINER_NAME="postgres16" DB_USER="myuser" DB_NAME="mydb" DATE=$(date +%Y%m%d_%H%M%S) # 创建备份目录 mkdir -p ${BACKUP_DIR} # 使用 pg_dump 导出数据 docker exec ${CONTAINER_NAME} pg_dump -U ${DB_USER} -d ${DB_NAME} -F c -f /tmp/${DB_NAME}_${DATE}.dump # 从容器内拷贝到宿主机 docker cp ${CONTAINER_NAME}:/tmp/${DB_NAME}_${DATE}.dump ${BACKUP_DIR}/ # 清理容器内外临时文件 docker exec ${CONTAINER_NAME} rm -f /tmp/${DB_NAME}_${DATE}.dump # 删除超过保留天数的旧备份 find ${BACKUP_DIR} -name "*.dump" -mtime +${BACKUP_KEEP_DAYS} -delete echo "Backup completed: ${BACKUP_DIR}/${DB_NAME}_${DATE}.dump"解释一下里面的关键点:
- pg_dump -F c 表示输出为自定义归档格式,这个格式体积小,而且支持 pg_restore 的选择性恢复。
- 为什么先把 dump 文件导出到容器 /tmp 再 docker cp 出来?因为容器内可能没有安装和宿主机共享的存储工具,直接输出到 stdout 再重定向也可以,但文件大的时候二进制数据可能被终端干扰,所以用 docker cp 最稳妥。
- 备份保留 14 天,基本能覆盖日常的回滚需求,也不会无限积压占用磁盘空间。
给脚本加上执行权限,然后通过 crontab 定时执行:
chmod +x /data/postgres/backup.sh crontab -e在 crontab 文件里加一行:
30 2 * * * /data/postgres/backup.sh >> /data/postgres/backup.log 2>&1意思是每天凌晨 2:30 执行一次备份,日志输出到 backup.log。凌晨备份的好处是业务低峰期,数据库压力小,备份一致性也更可靠。
4.3 演练一次数据恢复
备份是为了恢复,所以恢复流程必须亲自演练过,别等到出事了才手忙脚乱。下面演示从刚才的备份文件恢复数据的过程。
假设我们的 mydb 库被误删了两张表,恢复步骤如下:
# 进入备份文件所在目录 cd /data/postgres/backups # 查看备份文件中包含的对象 sudo docker exec -i postgres16 pg_restore -U myuser -d mydb --list /tmp/latest.dump | head -50因为备份文件在宿主机上,容器内访问不到,有两条路:一是先 docker cp 进容器,二是直接把备份文件通过 stdin 传给 pg_restore。我习惯用 stdin 的方式:
sudo docker exec -i postgres16 pg_restore -U myuser -d mydb --clean --if-exists < mydb_20250101_023000.dump参数说明:
- --clean:在恢复前先尝试删除目标数据库中的同名对象,防止冲突。
- --if-exists:配合 --clean 使用,删除对象时加上 IF EXISTS 条件,避免因为对象不存在而报错中断。
- -d mydb:指定恢复到哪个数据库。注意目标数据库必须存在,不存在的话先 createdb 或者用 psql 创建一个。
恢复过程中,pg_restore 会把每条 SQL 的执行结果输出到终端。如果某个对象恢复失败,它不会中断整个恢复流程,而是继续执行后面的对象,最后在结尾汇总错误。所以我一般恢复完了还会通过查询几条关键数据来确认结果。
这个小节想表达的核心是:定期恢复演练真的很有必要。我见过不止一次备份脚本跑得好好的,但恢复时才发现备份文件损坏或者不全的场景。每个月至少做一次恢复演练,把备份和恢复当作同等重要的事情对待。
5. 常见问题速查与避坑指南
5.1 启动类问题
容器无法启动是最常见的故障,我把它列在第一位。不同原因对应的现象和排查方法完全不同,这里整理成一个速查表。
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| docker ps 里没有 postgres16 容器 | 启动命令执行失败 | docker logs postgres16 查看具体报错 |
| 日志报 chmod: changing permissions of '/var/lib/postgresql/data': Operation not permitted | 宿主机数据目录权限不对 | 确认 /data/postgres/pgdata 的属主是 999:999,执行 chown -R 999:999 |
| 日志报 could not create directory ... Permission denied | 同上,通常是挂载目录权限问题 | 同上,或考虑用命名卷代替绑定挂载 |
| 日志报 FATAL: data directory "/var/lib/postgresql/data" has invalid permissions | 数据目录权限过于宽松 | PostgreSQL 要求数据目录权限不大于 0700,执行 chmod 700 后重试 |
| 日志报 The database cluster is initialized with locale "en_US.utf8",但系统没这个 locale | 系统缺 locale | 在宿主机上执行 locale-gen en_US.UTF-8 后重启容器 |
第一次部署 PostgreSQL 容器的人最容易栽在权限问题上。PostgreSQL 是个安全要求极高的数据库,对数据目录权限的检查非常严格,目录权限必须是 700,属主必须是要运行数据库的用户。官方镜像里的 postgres 用户 uid 是 999,So 在宿主机上 chown 999:999 是最直接的解法。
另一个容易忽略的点是 locale。如果你在启动容器时通过 POSTGRES_INITDB_ARGS 指定了 --locale=zh_CN.UTF-8 之类的参数,而容器内或者系统镜像里没有对应的 locale 数据,初始化就会失败。这个我在测试环境里踩过一次,后来干脆不折腾,直接用默认的 en_US.utf8,数据库里存中文完全没问题,只要客户端连接时设置正确的 client_encoding 就行。
5.2 连接与权限类问题
数据库起来了但连不上,这种问题排在第二位。核心方向有三个:端口、监听地址、认证。
端口层面,先确认容器端口映射状态:
sudo docker port postgres16正常输出应该是 5432/tcp -> 0.0.0.0:5432。如果这个命令没有输出,说明容器没有配置端口映射,需要重新创建容器。
接着验证宿主机本地能不能连:
sudo docker exec -it postgres16 psql -U myuser -d mydb -c "SELECT version();"如果这一步成功,说明数据库本身没问题,问题出在网络链路。这时检查腾讯云安全组是否放行了 5432 入站端口,以及宿主机防火墙(如果启用了 ufw 或 firewalld)是否拦截了端口。
认证层面,常见的报错是:
- Password authentication failed for user "myuser":密码不对。注意 POSTGRES_PASSWORD 只在初始化时生效,如果你想改密码,得用 ALTER USER 命令,或者再设置一个 POSTGRES_PASSWORD 环境变量然后重新初始化数据目录(会丢数据,不推荐)。
- no pg_hba.conf entry for host "x.x.x.x":客户端 IP 不在 pg_hba.conf 的允许列表里。官方镜像默认的 pg_hba.conf 对容器网络内的所有 IP 使用 scram-sha-256 认证,如果外部 IP 访问不了,可以进入容器修改配置:
sudo docker exec -it postgres16 bash echo "host all all 0.0.0.0/0 scram-sha-256" >> /var/lib/postgresql/data/pg_hba.conf改完重载配置即可,不用重启容器:
sudo docker exec -it postgres16 psql -U myuser -d mydb -c "SELECT pg_reload_conf();"不过我再啰嗦一句:生产环境不要图省事把 pg_hba.conf 设成 0.0.0.0/0,这是将数据库完全暴露给公网的行为,等于把家门钥匙放在门口脚垫下面。
5.3 数据与性能类问题
最后说几个数据与性能方面的坑,这些是数据库跑了一段时间之后才会暴露出来的。
数据目录占用膨胀。PostgreSQL 的 MVCC 机制决定了删除大量数据后,磁盘空间不会立刻还给操作系统,而是在数据文件里留下死元组。如果长期只增删不清理,数据目录会越来越大。解决办法是定期执行 VACUUM FULL。在容器里操作:
sudo docker exec -it postgres16 psql -U myuser -d mydb -c "VACUUM FULL ANALYZE;"注意 VACUUM FULL 会锁表,业务高峰期不要执行,建议放在凌晨维护窗口,配合备份脚本一起做。
连接数打满。默认 max_connections 是 100,如果应用连接池配置不当,很容易把连接数吃满,新连接直接报 sorry, too many clients already。这时需要调大 max_connections。但这里有个连带关系:max_connections 调大,共享缓冲区 shared_buffers 也要随之调整,不然 PostgreSQL 的共享内存可能不足。容器里改配置的方式是挂载自定义的 postgresql.conf,或者在启动时用 -c 参数:
sudo docker run ... \ -c max_connections=200 \ -c shared_buffers=512MB \ postgres:16或者更规范一点,把配置文件放到宿主机,挂载到容器内的 /etc/postgresql/postgresql.conf,然后启动参数里指定 config_file。这个做法适合对 PostgreSQL 参数有精细要求的场景。
备份文件越堆越多导致磁盘满。这个问题在 4.2 的脚本里已经通过 find + mtime 处理了,但如果你是自己手动跑备份,一定要记得定期清理。磁盘 100% 会导致 PostgreSQL 无法写入 WAL 日志,整个数据库直接进入只读模式甚至宕机,这个后果比丢失几个备份文件严重得多。
最后再分享一点个人心得
这次部署 PostgreSQL 用 Docker 方案,整体感受是:上手快,结构清晰,迁移方便,但也要求你对 Docker 的数据卷机制和 PostgreSQL 的目录权限有基本的了解。整套方案我已经在好几台服务器上跑了大半年,中间经历了两次服务器重启、一次数据恢复演练,都很稳。
如果你之前完全没接触过 Docker,我建议在正式部署前先在一台临时机器上把流程完整走一遍,尤其是 docker run 和 docker compose 两个方式都试一次,感受一下容器和宿主机的文件交互方式。这样真正在腾讯云上操作的时候,你会更从容一些。
如果后续想在这个基础上做更完整的方案,可以考虑配置 PostgreSQL 的日志轮转、接入 Prometheus + Grafana 监控,或者搞一套主从复制做高可用。Docker 的生态决定了这些扩展都有成熟的镜像和方案可以借鉴。希望这篇记录能帮你少踩几个坑。