PostgreSQL 18.6 Docker Compose 部署指南
使用 Docker Compose 一键部署 PostgreSQL 18.6(官方镜像 `postgres:18.6`),涵盖数据目录持久化、常用环境变量与参数配置(`-c` 传参)、健康检查,并给出等价的 `docker run` 运行方式。本文档已在 `/opt/data/ops/postgresql` 目录实测通过
PostgreSQL 18.6 Docker Compose 部署指南
目标:使用 Docker Compose 一键部署 PostgreSQL 18.6(官方镜像
postgres:18.6),涵盖数据目录持久化、常用环境变量与参数配置(-c传参)、健康检查,并给出等价的docker run运行方式。本文档已在/opt/data/ops/postgresql目录实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS
- 系统架构:x86_64
- Docker 版本:Docker Engine 27.x(含 Compose v2 插件)
- 镜像版本:
postgres:18.6(与《Ubuntu 22.04 安装 PostgreSQL 18 指南》版本一致) - 容器名称:
postgres-18-6 - 端口映射:宿主机
15432→ 容器5432 - 数据目录:宿主机
/opt/data/ops/postgresql/data(挂载到容器/var/lib/postgresql) - 部署文件:
/opt/data/ops/postgresql/docker-compose.yaml
二、镜像选型说明
| 镜像标签 | 对应版本 | 特点 |
|---|---|---|
postgres:18.6 | PostgreSQL 18.6(当前最新稳定版) | 含全部小版本安全修复,支持新特性 |
postgres:18 | PostgreSQL 18 系列最新小版本 | 会跟随上游小版本自动变化 |
postgres:latest | 最新稳定版(当前指向 18.x) | 版本会随上游变化,不建议生产锁定 |
💡 说明:官方镜像仓库为
docker.io/library/postgres。国内拉取可配置阿里云 / daocloud 镜像加速器,或通过中转节点拉取后docker load导入宿主机(本文档实测即采用此方式,镜像已 load 到宿主机)。
三、前置条件
- 已安装 Docker Engine 与 Docker Compose 插件:
docker --version && docker compose version - 已规划数据目录(建议放在独立磁盘,避免系统盘被数据占满)
- 已准备好强密码(禁止使用默认/弱密码,见"六、常用环境变量表"章节)
四、部署步骤
4.1 创建部署目录
sudo mkdir -p /opt/data/ops/postgresql
cd /opt/data/ops/postgresql
4.2 编写 docker-compose.yaml
将以下内容保存为 /opt/data/ops/postgresql/docker-compose.yaml:
# =============================================================================
# PostgreSQL 18.6 Docker Compose 部署文件
# 镜像版本:postgres:18.6(与《Ubuntu 22.04 安装 PostgreSQL 18 指南》版本一致)
# 使用方式:cd /opt/data/ops/postgresql && docker compose up -d
# 密码等敏感值通过环境变量注入,请先 export(见文档"六、常用环境变量表"章节)
# =============================================================================
services:
postgres:
# 镜像版本:18.6 官方镜像
image: postgres:18.6
# 容器名称,方便 docker ps / docker logs 定位
container_name: postgres-18-6
# 重启策略:容器异常退出时自动重启(除非手动 stop)
restart: unless-stopped
# ---- 常用环境变量配置(值由外部环境变量注入)----
environment:
- TZ=Asia/Shanghai # 容器时区(与宿主机一致)
- POSTGRES_USER=${POSTGRES_USER:-app_user} # 超级用户(默认 app_user)
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?请在环境变量中设置} # 超级用户密码
- POSTGRES_DB=${POSTGRES_DB:-app_db} # 自动创建的默认数据库
# ---- 常用配置参数(-c 等价于写进 postgresql.conf)----
# 说明:参数已统一放入 ./conf/postgresql.conf(见下方 volumes 挂载),
# 修改配置只需编辑该文件后 docker compose restart postgres,无需改 yaml
command:
- "-c"
- "config_file=/etc/postgresql/postgresql.conf" # 使用自定义配置文件(完整替换默认 conf)
# ---- 端口映射:宿主机15432 -> 容器5432 ----
ports:
- "15432:5432"
# ---- 数据持久化(重要)----
# 18+ 官方镜像使用 pg_ctlcluster 布局(数据在 /var/lib/postgresql/<版本>/<集群名>),
# 必须挂载父目录 /var/lib/postgresql,否则容器启动报错
volumes:
- ./data:/var/lib/postgresql
# ---- 配置文件持久化(重要)----
# ./conf 为宿主机配置目录,挂载到 /etc/postgresql,
# 通过 -c config_file 指定使用该配置文件,编辑后 docker compose restart postgres 生效
- ./conf:/etc/postgresql
# ---- 健康检查:容器内 pg_isready 判断数据库就绪 ----
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s # 每 10 秒检查一次
timeout: 5s # 单次检查超时
retries: 10 # 连续 10 次失败视为不健康
start_period: 30s # 启动后 30 秒才开始检查
# 容器日志大小限制,防止磁盘被日志占满
logging:
driver: json-file
options:
max-size: "50m"
max-file: "3"
4.3 设置环境变量并启动
# 注入密码(首次初始化生效,容器重建后需保持一致才能正常读取数据目录)
export POSTGRES_PASSWORD='your-password'
docker compose up -d
💡 说明:
${POSTGRES_PASSWORD:?请在环境变量中设置}语法表示:若该环境变量未设置,docker compose up会直接报错退出,防止密码缺失导致初始化失败或使用默认值。
4.4 验证部署
# 查看容器状态(healthy 表示健康检查通过)
docker ps --filter name=postgres-18-6
# 连接测试
docker exec -it postgres-18-6 psql -U app_user -d app_db
五、数据持久化说明(重点)
- 数据目录映射:
./data:/var/lib/postgresql。 - 配置目录映射:
./conf:/etc/postgresql,通过-c config_file=/etc/postgresql/postgresql.conf生效,修改后重启容器生效(见"八、配置文件持久化(conf 挂载)"章节)。 - ⚠️ 18+ 镜像布局变更:PostgreSQL 18 官方镜像的数据目录由
/var/lib/postgresql/data改为pg_ctlcluster布局,实际数据在/var/lib/postgresql/<版本>/<集群名>(如/var/lib/postgresql/18/main)。 - 必须挂载父目录
/var/lib/postgresql。若仍按旧文档挂载./data:/var/lib/postgresql/data,容器会反复重启(初始化脚本找不到预期目录结构)。 - 重启容器(
docker compose restart/docker compose up -d)数据不丢失。 - 删除容器不会删除数据:
docker compose down只移除容器,./data与./conf目录仍在;只有docker compose down -v才会删除卷数据。 - 备份:对宿主机
./data目录做快照/rsync,或使用pg_dump逻辑备份。 - 权限说明:镜像内 PostgreSQL 以
postgres用户(uid 999)运行,首次启动时镜像会自动对挂载目录做chown,无需手动处理权限。
六、常用环境变量表
| 环境变量 | 默认值 | 说明 |
|---|---|---|
POSTGRES_USER | app_user | 超级用户(相当于默认的 postgres 用户) |
POSTGRES_PASSWORD | (必填,无默认) | 超级用户密码 |
POSTGRES_DB | app_db | 首次初始化自动创建的默认数据库(不设置则与用户名相同) |
TZ | 镜像默认(UTC) | 容器时区,建议与宿主机一致 |
⚠️ 安全提醒:
POSTGRES_PASSWORD属于敏感值,务必通过环境变量注入,禁止写入 yaml 明文。生产环境可用 Docker secrets 或密码管理工具注入。
七、常用配置参数说明(-c 传参)
command 中以 -c key=value 方式传参,等价于写入 postgresql.conf。多个参数需重复 -c。本方案通过 -c config_file=/etc/postgresql/postgresql.conf 指定完整使用自定义配置文件(见下方"八、配置文件持久化(conf 挂载)"章节)。
| 参数 | 说明 |
|---|---|
config_file=/etc/postgresql/postgresql.conf | 指定自定义配置文件路径(挂载自宿主机 ./conf) |
shared_buffers=256MB | 共享缓冲区大小,建议设为物理内存的 25% 左右 |
max_connections=200 | 最大连接数,按业务规模调整(过高会占用更多共享内存) |
listen_addresses='*' | 监听所有网卡,配合端口映射供外部连接 |
💡 说明:
shared_buffers、max_connections、listen_addresses已写入./conf/postgresql.conf,与-c config_file组合生效。更多参数(如work_mem、effective_cache_size)直接编辑该配置文件即可,参考《PostgreSQL 18 配置参数详解》文档。
八、配置文件持久化(conf 挂载)
本方案在 volumes 中挂载了配置目录 ./conf:/etc/postgresql,并通过 -c config_file 指定使用该配置文件,实现配置文件持久化,方便后续修改参数而无需改动 yaml:
# 配置文件位于宿主机,可随时编辑
sudo vim /opt/data/ops/postgresql/conf/postgresql.conf
./conf/postgresql.conf 内容如下(含常用参数示例):
# PostgreSQL 自定义配置文件(挂载到 /etc/postgresql/postgresql.conf)
# 启动参数:-c config_file=/etc/postgresql/postgresql.conf(完整替换默认 postgresql.conf)
# 修改后重启容器生效:docker compose restart postgres
# 共享缓冲区(默认 128MB,建议设为物理内存的 25% 左右)
shared_buffers = 256MB
# 最大连接数(默认 100)
max_connections = 200
# 监听所有网卡(配合端口映射供外部连接)
listen_addresses = '*'
# 更多常用参数示例(按需取消注释):
# work_mem = 16MB # 排序/哈希等操作的内存上限
# effective_cache_size = 4GB # 操作系统缓存评估值(约物理内存的 50%~75%)
# maintenance_work_mem = 256MB # 维护操作(VACUUM/索引重建)内存
# log_min_duration_statement = 1000 # 记录执行超过 1 秒的慢 SQL(毫秒)
# log_statement = 'none' # 日志级别:none/ddl/mod/all
⚠️ 注意:
-c config_file=...会完整替换默认的postgresql.conf。因此自定义配置文件中需包含必需的参数(如listen_addresses);若容器启动异常,先检查该文件语法(docker logs postgres-18-6查看报错)。修改后执行docker compose restart postgres即生效(已验证)。
九、等价 docker run 运行方式
不使用 Compose 时,可用以下 docker run 达到相同效果:
# 先注入环境变量
export POSTGRES_PASSWORD='your-password'
docker run -d \
--name postgres-18-6 \
--restart unless-stopped \
-e TZ=Asia/Shanghai \
-e POSTGRES_USER=app_user \
-e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \
-e POSTGRES_DB=app_db \
-p 15432:5432 \
-v /opt/data/ops/postgresql/data:/var/lib/postgresql \
-v /opt/data/ops/postgresql/conf:/etc/postgresql \
--health-cmd='pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
--health-interval=10s \
--health-timeout=5s \
--health-retries=10 \
--health-start-period=30s \
postgres:18.6 \
-c config_file=/etc/postgresql/postgresql.conf
参数对照:
| Compose 写法 | docker run 写法 |
|---|---|
image: postgres:18.6 | 末尾镜像名 postgres:18.6 |
container_name | --name |
restart: unless-stopped | --restart unless-stopped |
environment | -e KEY=value |
ports: "15432:5432" | -p 15432:5432 |
volumes: ./data:/var/lib/postgresql | -v /opt/data/ops/postgresql/data:/var/lib/postgresql |
volumes: ./conf:/etc/postgresql | -v /opt/data/ops/postgresql/conf:/etc/postgresql |
healthcheck | --health-cmd / --health-interval 等 |
command | 镜像名之后的附加参数 |
💡 说明:
--health-cmd中"$POSTGRES_USER"会被 shell 展开为容器内环境变量值,故无需转义$(与 Compose 中需$$转义不同)。
十、常用运维命令
# 查看日志
docker logs -f postgres-18-6
# 重启容器(数据保留)
docker compose restart
# 停止并移除容器(保留数据)
docker compose down
# 彻底移除容器 + 数据目录(谨慎操作!)
docker compose down -v
# 进入 psql 交互
docker exec -it postgres-18-6 psql -U app_user -d app_db
十一、常见问题(FAQ)
11.1 容器反复重启(Exited / Restarting 循环)?
最常见原因是卷挂载目录错误。确认挂载的是 /var/lib/postgresql(18+ 布局)而非 /var/lib/postgresql/data。查看日志:docker logs postgres-18-6,若报 FATAL: data directory ... has invalid permissions 或 initdb: error,请检查挂载路径与目录权限。
11.2 端口映射失败:宿主机 15432 已被占用?
修改 ports 为其他宿主机端口,如 "15433:5432"。注意客户端连接地址随之变化。
11.3 修改密码后连接报 password authentication failed?
POSTGRES_PASSWORD只在首次初始化数据目录时生效;数据目录已存在时修改该变量不会改变密码。- 已部署后改密请用 SQL:
ALTER USER app_user WITH PASSWORD '新密码';。
11.4 外部连接被拒绝?
确认已传 -c listen_addresses=*,且宿主机防火墙/安全组放行对应端口(15432)。
11.5 容器重启后数据还在吗?
在:docker compose restart / down 后 up -d 都不会删除 ./data 目录。只有 docker compose down -v 会删除卷数据。
11.6 如何自定义更多参数?
本方案已挂载配置目录 ./conf:/etc/postgresql 并通过 -c config_file 指定使用,直接编辑 ./conf/postgresql.conf 追加参数(如 work_mem、effective_cache_size),然后 docker compose restart postgres 即生效,无需改动 yaml。注意 config_file 会完整替换默认配置,请保留 listen_addresses 等必要参数。更多参数含义参考《PostgreSQL 18 配置参数详解》文档。