本文从最基础的单命令启动到生产级 Compose 编排逐层拆解参数原理、数据持久化、账号管理、远程访问等核心知识点新手可照抄落地老手可查漏补缺。0. 前言与前置准备Docker 部署 PostgreSQL 是开发、测试、生产环境最常用的方案之一核心优势在于环境一致性彻底解决「我本地能跑服务器上不行」的问题秒级部署一条命令启动实例版本切换无成本隔离性强多版本、多实例互不干扰运维简单数据持久化、备份、迁移标准化前置条件已安装 Docker建议 20.10已安装 Docker Compose v2建议 2.20服务器 / 本地已开放对应端口默认 5432本文所有命令均基于 PostgreSQL 16 最新 LTS 版本演示兼容 12/13/14/15 全系列。一、方案一docker run 单命令部署适合快速测试、临时实例、单节点快速启动场景。1.1 最简启动命令仅用于测试不推荐生产docker run -d --name postgres-test -p 5432:5432 -e POSTGRES_PASSWORD123456 postgres:16⚠️ 警告此命令无数据持久化容器删除数据全部丢失仅适合临时测试。1.2 生产级完整启动命令推荐docker run -d \ --name postgres-prod \ --restartunless-stopped \ -p 5432:5432 \ -e POSTGRES_USERadmin \ -e POSTGRES_PASSWORDAdmin2024 \ -e POSTGRES_DBmy_database \ -e TZAsia/Shanghai \ -e PGDATA/var/lib/postgresql/data/pgdata \ -v /opt/postgres/data:/var/lib/postgresql/data \ -v /opt/postgres/conf/pg_hba.conf:/etc/postgresql/pg_hba.conf \ -v /opt/postgres/conf/postgresql.conf:/etc/postgresql/postgresql.conf \ --memory2G \ --cpus2 \ postgres:16 \ -c config_file/etc/postgresql/postgresql.conf \ -c hba_file/etc/postgresql/pg_hba.conf1.3 全参数硬核拆解参数作用说明生产建议-d后台守护进程运行容器必加--name postgres-prod给容器指定唯一名称方便管理建议按「业务 - 版本 - 环境」命名--restartunless-stopped容器重启策略生产必选Docker 重启 / 宿主机重启后自动拉起-p 5432:5432端口映射格式「宿主机端口容器内部端口」生产可修改宿主机端口降低攻击面如-p 15432:5432-e POSTGRES_USERadmin指定初始超级用户名默认postgres生产建议自定义不使用默认名-e POSTGRES_PASSWORDAdmin2024初始超级用户密码必填参数生产必须使用强密码包含大小写 数字 特殊字符-e POSTGRES_DBmy_database初始自动创建的数据库名默认和用户名一致业务库可提前创建省去后续手动建库步骤-e TZAsia/Shanghai设置容器时区为东八区必加否则默认 UTC 时间和国内差 8 小时-e PGDATA/var/lib/postgresql/data/pgdata指定 PostgreSQL 数据文件存储目录挂载宿主机目录时建议加避免直接挂载到 data 根目录引发权限问题-v /opt/postgres/data:/var/lib/postgresql/data数据持久化核心格式「宿主机目录容器目录」生产必配将数据文件映射到宿主机容器删除数据不丢失-v 配置文件挂载将 pg_hba.conf、postgresql.conf 映射到宿主机生产建议方便修改配置不用进入容器--memory2G限制容器最大使用内存生产建议限制防止数据库占满宿主机资源--cpus2限制容器最大使用 CPU 核数按需配置资源隔离postgres:16镜像名称 版本标签生产必须指定具体版本禁止使用 latest避免版本漂移-c config_filexxx启动时指定自定义配置文件路径挂载外部配置文件时必加让 PG 加载我们的配置1.4 重启策略详解--restart有 4 种可选值区别如下no默认值容器退出时不自动重启on-failure[:max-retries]容器非正常退出退出码非 0时自动重启可设置最大重试次数always无论什么原因退出都自动重启包括手动停止的容器Docker 重启后也会自动拉起unless-stopped最推荐生产使用总是自动重启但如果容器之前被手动停止了Docker 重启后不会自动拉起二、方案二Docker Compose 编排部署适合生产环境、多服务协同部署、配置需要版本化管理的场景是企业级首选方案。2.1 完整 docker-compose.yml 配置创建docker-compose.yml文件内容如下version: 3.8 services: postgres: image: postgres:16-alpine container_name: postgres-compose-prod restart: unless-stopped ports: - 5432:5432 environment: POSTGRES_USER: admin # 超级用户名 POSTGRES_PASSWORD: Admin2024 # 超级用户密码 POSTGRES_DB: my_database # 初始数据库 TZ: Asia/Shanghai # 时区 PGDATA: /var/lib/postgresql/data/pgdata # 数据目录 volumes: # 数据持久化挂载 - ./data:/var/lib/postgresql/data # 自定义配置文件挂载 - ./conf/postgresql.conf:/etc/postgresql/postgresql.conf - ./conf/pg_hba.conf:/etc/postgresql/pg_hba.conf # 初始化脚本挂载第一次启动自动执行 - ./init:/docker-entrypoint-initdb.d # 资源限制 deploy: resources: limits: cpus: 2 memory: 2G reservations: cpus: 0.5 memory: 512M networks: - pg-network # 启动命令指定自定义配置文件 command: - -c - config_file/etc/postgresql/postgresql.conf - -c - hba_file/etc/postgresql/pg_hba.conf # 自定义网络方便和其他服务如pgadmin、业务服务互通 networks: pg-network: driver: bridge2.2 配置文件与初始化脚本① 准备配置文件目录在 docker-compose.yml 同级目录创建conf、data、init三个文件夹mkdir -p conf data init② 自定义 postgresql.conf创建conf/postgresql.conf核心配置示例# 监听地址允许所有IP访问配合pg_hba.conf使用 listen_addresses * port 5432 max_connections 200 # 内存配置根据宿主机内存调整建议总内存的25% shared_buffers 512MB work_mem 4MB maintenance_work_mem 128MB # 日志配置 logging_collector on log_directory log log_filename postgresql-%Y-%m-%d_%H%M%S.log log_timezone Asia/Shanghai # 时区 timezone Asia/Shanghai datestyle iso, mdy③ 客户端认证配置 pg_hba.conf创建conf/pg_hba.conf控制哪些 IP 可以连接数据库# TYPE DATABASE USER ADDRESS METHOD # 本地unix套接字连接 local all all trust # IPv4 本地回环 host all all 127.0.0.1/32 trust # 允许所有IP用密码连接生产建议限制IP段如 192.168.1.0/24 host all all 0.0.0.0/0 md5 # IPv6 host all all ::1/128 trust⚠️ 生产环境禁止直接写0.0.0.0/0应限制为具体的业务服务器 IP 段降低安全风险。④ 初始化脚本可选在init目录下放入.sql或.sh文件仅在容器第一次启动、数据目录为空时自动执行适合初始化表结构、创建普通用户、导入基础数据。示例init/01-init-user.sql-- 创建普通业务用户 CREATE USER app_user WITH PASSWORD AppUser2024; -- 创建业务库 CREATE DATABASE app_db OWNER app_user; -- 授予权限 GRANT ALL PRIVILEGES ON DATABASE app_db TO app_user;2.3 Compose 常用运维命令在 docker-compose.yml 所在目录执行# 启动服务后台运行 docker compose up -d # 查看服务状态 docker compose ps # 查看日志实时滚动 docker compose logs -f postgres # 停止服务不删除容器 docker compose stop # 启动已停止的服务 docker compose start # 重启服务 docker compose restart # 停止并删除容器、网络数据卷不会删 docker compose down # 停止并删除容器、网络、数据卷⚠️ 数据会丢失谨慎使用 docker compose down -v三、核心原理数据持久化与初始化机制3.1 为什么必须做数据持久化Docker 容器的文件系统是临时的容器销毁时内部所有数据都会一起删除。PostgreSQL 的数据默认存在容器内的/var/lib/postgresql/data目录下必须通过-v卷挂载映射到宿主机才能实现数据持久化。3.2 两种挂载方式对比表格挂载方式写法示例优点缺点适用场景绑定挂载宿主机目录-v /opt/pg/data:/var/lib/postgresql/data路径直观方便备份、迁移、手动查看文件需注意权限问题PG 容器内部用户 UID 是 999生产环境、需要手动管理数据具名卷Docker 管理-v pg_data:/var/lib/postgresql/dataDocker 自动管理权限无权限问题性能更好路径不直观备份需要用 docker 命令测试环境、快速部署3.3 环境变量初始化机制巨坑预警POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB这三个环境变量仅在容器第一次启动、数据目录为空时生效也就是说容器启动过一次后再修改环境变量里的密码不会生效想修改密码必须进入数据库执行 SQL 语句修改想让新的环境变量生效必须清空数据目录重新初始化这是 90% 的新手都会踩的坑务必记住。3.4 权限问题解决方案挂载宿主机目录时经常会遇到「Permission denied」报错原因是 PostgreSQL 容器内部使用postgres用户运行UID 为 999而宿主机的目录权限属于 root 或其他用户。解决方案二选一# 方案1给宿主机目录开放权限简单粗暴测试可用 chmod 777 /opt/postgres/data # 方案2将目录所有者改为 UID 999推荐生产更安全 chown -R 999:999 /opt/postgres/data四、必备运维操作大全4.1 进入容器与进入数据库① 进入容器 bash 终端docker exec -it postgres-prod bash② 直接进入 PostgreSQL 命令行推荐一步到位# 格式docker exec -it 容器名 psql -U 用户名 -d 数据库名 docker exec -it postgres-prod psql -U admin -d my_database进入 psql 后提示符变为my_database#表示已进入数据库命令行。4.2 psql 常用命令命令作用\l列出所有数据库\c 数据库名切换到指定数据库如\c app_db\dt列出当前数据库所有表\d 表名查看表结构如\d users\du列出所有用户和角色\conninfo查看当前连接信息\timing on开启 SQL 执行耗时显示\q退出 psql 命令行4.3 账号与数据库管理① 修改用户密码-- 语法ALTER USER 用户名 WITH PASSWORD 新密码; ALTER USER admin WITH PASSWORD NewPass2024;② 创建新用户-- 创建普通用户 CREATE USER app_user WITH PASSWORD AppUser2024; -- 创建带超级权限的用户谨慎使用 CREATE USER super_user WITH SUPERUSER PASSWORD Super2024;③ 创建数据库并授权-- 创建数据库指定所有者 CREATE DATABASE business_db OWNER app_user; -- 授予用户对数据库的所有权限 GRANT ALL PRIVILEGES ON DATABASE business_db TO app_user; -- 授予连接权限 GRANT CONNECT ON DATABASE business_db TO app_user;④ 删除用户 / 数据库-- 删除数据库 DROP DATABASE IF EXISTS old_db; -- 删除用户 DROP USER IF EXISTS old_user;4.4 数据备份与恢复① 全库备份pg_dump# 格式docker exec 容器名 pg_dump -U 用户名 数据库名 备份文件路径 docker exec postgres-prod pg_dump -U admin my_database /opt/backup/my_database_20240601.sql② 恢复数据# 方式1从sql文件恢复 docker exec -i postgres-prod psql -U admin -d my_database /opt/backup/my_database_20240601.sql # 方式2进入容器后恢复 docker exec -it postgres-prod bash psql -U admin -d my_database -f /tmp/backup.sql③ 备份整个数据卷适合整实例迁移# 停止容器后打包整个数据目录 docker stop postgres-prod tar -zcvf pg_data_backup.tar.gz /opt/postgres/data五、进阶开启远程访问完整步骤很多人部署完后无法用 Navicat/DBeaver 连接按以下 4 步检查端口映射正确确保-p 5432:5432已配置宿主机防火墙已开放 5432 端口【默认端口建议修改防止被攻击】# 云服务器需在安全组放行端口服务器防火墙放行 firewall-cmd --add-port5432/tcp --permanent firewall-cmd --reload配置监听地址postgresql.conf中listen_addresses *配置客户端认证pg_hba.conf中添加允许连接的 IP 规则重启容器生效docker restart postgres-prod 安全建议生产环境不要直接暴露 5432 端口到公网建议通过 VPN 或内网连接或修改默认端口配合强密码使用。六、避坑指南90% 的人都踩过的坑坑 1修改环境变量密码不生效原因环境变量仅第一次初始化生效。 解决进入数据库执行ALTER USER语句修改密码。坑 2挂载目录后启动报错 Permission denied原因宿主机目录权限和容器内 postgres 用户 UID 不匹配。 解决chown -R 999:999 宿主机数据目录。坑 3用 latest 标签导致版本异常原因latest 标签始终指向最新版本重启后可能自动升级大版本引发数据不兼容。 解决生产必须指定具体版本号如postgres:16.3。坑 4时区不对时间差 8 小时原因容器默认 UTC 时区。 解决添加环境变量TZAsia/Shanghai同时配置文件中设置log_timezone和timezone。坑 5数据没挂载容器删除数据丢失原因新手忘记加-v参数。 解决部署第一时间配置数据卷挂载养成习惯。坑 6远程连接报错「password authentication failed」排查顺序密码是否输入正确pg_hba.conf 是否配置了对应 IP 的 md5 认证规则是否修改过密码但没生效连接的用户名和数据库名是否存在七、总结快速测试用docker run单命令启动简单高效生产部署用Docker Compose编排配置可版本化管理运维更规范核心底线数据持久化必配、强密码必设、端口暴露需谨慎运维习惯定期备份数据、不使用 latest 标签、限制远程访问 IPPostgreSQL Docker 的组合兼顾了灵活性和稳定性掌握本文内容足以应对 99% 的部署场景。下一篇将讲解 PostgreSQL 主从复制的 Docker 部署方案敬请关注。原创不易如果对你有帮助欢迎点赞、收藏、关注持续输出硬核运维干货。