docker-postgresql
第一步:环境准备与目录创建
为了防止数据丢失和便于管理配置文件,需要在宿主机上为两个环境创建独立的目录。
将文件存放在
/opt/docker/postgresql目录下:# 创建测试环境目录 mkdir -p /opt/docker/postgresql/test/conf mkdir -p /opt/docker/postgresql/test/data mkdir -p /opt/docker/postgresql/test/logs # 创建生产环境目录 mkdir -p /opt/docker/postgresql/prod/conf mkdir -p /opt/docker/postgresql/prod/data mkdir -p /opt/docker/postgresql/prod/logs把
/opt/docker/postgresql/test和/opt/docker/postgresql/prod权限提高。注意:PostgreSQL 官方镜像默认用户
postgres的 UID 通常也是 999(与 MySQL 类似),但也可能是 70。在大多数现代 Docker 版本中,设置 999 是安全的通用做法。sudo chown -R 999:999 /opt/docker/postgresql/test/ sudo chown -R 999:999 /opt/docker/postgresql/prod/第二步:准备配置文件 (postgresql.conf)
为了支持中文时区并优化性能,我们需要预先创建配置文件。
测试环境(配置较低,够用即可):
touch /opt/docker/postgresql/test/conf/postgresql.confcat > /opt/docker/postgresql/test/conf/postgresql.conf << 'EOF' # 监听设置 listen_addresses = '*' # 连接数限制 (测试环境无需太高) max_connections = 100 # 内存设置 (最小化占用) shared_buffers = 128MB dynamic_shared_memory_type = posix # 时区设置 log_timezone = 'Asia/Shanghai' timezone = 'Asia/Shanghai' # 日志设置 (开启日志收集并指向挂载目录) logging_collector = on log_directory = '/var/log/postgresql' log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' log_statement = 'all' EOF生产环境(针对 8核/8G 且混跑其他服务的优化):
配置说明:
shared_buffers: 设置为 1GB。虽然机器有 8G,但因为跑了 Redis 和 Java/Node 应用,给 PG 留 1GB 专用内存,其余依靠系统缓存,比较稳妥。work_mem: 复杂查询时的内存,设为 4MB 防止连接数多时 OOM。
touch /opt/docker/postgresql/prod/conf/postgresql.confcat > /opt/docker/postgresql/prod/conf/postgresql.conf << 'EOF' # 监听设置 listen_addresses = '*' # 连接数限制 (生产环境) max_connections = 500 # === 内存与性能优化 (基于 8GB 总内存混跑环境) === # 专用内存缓冲 (建议设置为总内存的 15%-25%) shared_buffers = 1GB # 告诉 PG 操作系统还有多少缓存可用 (辅助规划查询) effective_cache_size = 3GB # 维护操作内存 (如 VACUUM, CREATE INDEX) maintenance_work_mem = 256MB # 单个查询操作内存 work_mem = 4MB # 写前日志缓冲 wal_buffers = 16MB # === 时区设置 === log_timezone = 'Asia/Shanghai' timezone = 'Asia/Shanghai' # === 日志设置 === logging_collector = on log_directory = '/var/log/postgresql' log_filename = 'postgresql-%Y-%m-%d.log' # 记录慢查询 (超过 2000ms) log_min_duration_statement = 2000 EOF第三步:启动容器
拉取最新的 PostgreSQL 镜像。
- 同样使用加速镜像地址(以 PostgreSQL 16 为例,这是目前稳定且性能较好的版本):
docker pull docker.1ms.run/postgres:16 docker tag docker.1ms.run/postgres:16 postgres:16- 启动两个容器,映射不同的宿主机端口。
- 测试环境: 宿主机端口 5433 -> 容器端口 5432
- 生产环境: 宿主机端口 5432 (默认) -> 容器端口 5432
1. 启动测试环境 (PG-Test)
docker run -d \ --name pg-test \ --restart always \ -p 5433:5432 \ -v /opt/docker/postgresql/test/data:/var/lib/postgresql/data \ -v /opt/docker/postgresql/test/logs:/var/log/postgresql \ -v /opt/docker/postgresql/test/conf/postgresql.conf:/etc/postgresql/postgresql.conf \ -e POSTGRES_PASSWORD=xxxxxxxxx \ --privileged=true \ postgres:16 \ -c 'config_file=/etc/postgresql/postgresql.conf'2. 启动生产环境 (PG-Prod)
docker run -d \ --name pg-prod \ --restart always \ -p 5432:5432 \ -v /opt/docker/postgresql/prod/data:/var/lib/postgresql/data \ -v /opt/docker/postgresql/prod/logs:/var/log/postgresql \ -v /opt/docker/postgresql/prod/conf/postgresql.conf:/etc/postgresql/postgresql.conf \ -e POSTGRES_PASSWORD=xxxxxxxx \ --privileged=true \ postgres:16 \ -c 'config_file=/etc/postgresql/postgresql.conf'参数解释(与 MySQL 的区别):
-e POSTGRES_PASSWORD=...: 对应 MySQL 的 root 密码,这里设置默认用户postgres的密码。-v ...:/etc/postgresql/postgresql.conf: 挂载我们自定义的配置文件。postgres:16 ... -c 'config_file=...': 关键点。PostgreSQL 默认读取数据目录下的配置,我们需要在镜像名后面加上启动命令,强制让它读取我们挂载到/etc下的配置文件。--privileged=true: 同样为了解决 CentOS 8 可能存在的权限/SELinux 问题。
第四步:检查与验证
查看容器状态:
docker ps应该能看到
pg-test(端口 5433) 和pg-prod(端口 5432) 都在Up状态。连接测试 (使用 docker exec 内部连接):
测试环境:
# 注意:默认用户是 postgres docker exec -it pg-test psql -U postgres -c "SELECT version();" # 此时不需要输入密码,因为 docker exec 本地连接默认信任,或者会提示输入密码生产环境:
docker exec -it pg-prod psql -U postgres -c "SHOW shared_buffers;" # 输出应接近 1GB (如 1024MB),证明配置文件加载成功