PostgreSQL数据库工程化部署安装流程

PostgreSQL数据库部署安装流程

📌 文档说明 :本文档以 Docker 方式快速部署 PostgreSQL 15.4。为兼顾可读性,教程中直接使用了示例账号 postgres / 密码 postgres,便于初学者照做。生产环境请务必修改默认密码并收紧访问权限(详见下文「安全提醒」)


目录


一、配置需求

1. 系统要求

  • 一台装了 Docker 的服务器
  • 该服务器能与本地win电脑ping通
  • 操作系统:Ubuntu 22.04(推荐)

2. 资源需求

  • PostgreSQL 15.4 镜像(Docker官方仓库)
  • 国内的能用来拉取镜像的docker镜像源

3. 预备配置参数

参数
端口 5432
用户名 postgres
密码 postgres
默认数据库 postgres

二、大概流程简述

  1. 拉取官方 PostgreSQL 镜像
  2. 编写 docker-compose.yml 部署文件
  3. 启动容器(含数据持久化、健康检查、资源限制、日志轮转)
  4. 配置远程访问与认证
  5. 验证数据库连接

三、验证环节

1. 验证 Docker 环境

bash 复制代码
# 检查 Docker 是否安装
sudo docker --version

(如图所示结果)

显示类似 Docker version 24.03.1, build xxxx 就说明已安装。

bash 复制代码
# 检查 Docker 服务是否运行
sudo systemctl status docker

(如图所示结果)

看到 active (running) 就正常。

退出查看:ctrl+c

2. 验证镜像源是否能进行拉取镜像

bash 复制代码
# 拉取测试镜像
sudo docker pull hello-world

(失败结果如图所示)

(成功结果如图所示)

能正常运行就说明镜像源没问题。

如果拉取失败,配置国内 Docker 镜像加速器

创建文件

bash 复制代码
sudo mkdir -p /etc/docker
shellscript 复制代码
sudo vim /etc/docker/daemon.json

配置加速镜 清空文件内容,写入以下 JSON(注意格式)

开始编写按:i

bash 复制代码
{
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://docker.1ms.run",
    "https://docker.anyhub.us.kg"
  ],
  "dns": ["223.5.5.5", "114.114.114.114"]
}

退出编写+保存+退出:esc+:wq

应用配置

bash 复制代码
sudo systemctl daemon-reload

重启docker

bash 复制代码
sudo systemctl restart docker

配置成功后,重新执行上面的拉取命令测试即可。

四、具体流程(docker-compose 工程化部署)

💡 本节使用 docker-compose 将部署配置文件化,做到「一份配置,处处可起」,便于维护、复现与升级。账号密码仍沿用 postgres / postgres(仅教程示例,生产请修改)。

1. 拉取 PostgreSQL 镜像

bash 复制代码
sudo docker pull postgres:15.4

2. 准备部署目录

bash 复制代码
sudo mkdir -p /opt/postgresql/compose
cd /opt/postgresql/compose

3. 创建数据持久化目录并授权

bash 复制代码
# 创建数据目录
sudo mkdir -p /opt/postgresql/data
# 授权给容器内的 postgres 用户(UID/GID 均为 999)
sudo chown -R 999:999 /opt/postgresql/data

📌 说明999:999 是官方 postgres 镜像内部运行账户的 UID:GID,授权后容器才有权写入数据目录。

4. 编写 docker-compose.yml

/opt/postgresql/compose/ 目录下创建 docker-compose.yml

yaml 复制代码
# /opt/postgresql/compose/docker-compose.yml
services:
  postgres:
    image: postgres:15.4
    container_name: postgres_db
    restart: unless-stopped            # 宕机自动拉起,手动停止则不拉起
    # 教程沿用默认账号密码,生产环境请改为强密码(建议通过 .env 注入)
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
      TZ: Asia/Shanghai
    ports:
      - "5432:5432"                    # 对外暴露端口;如仅需本机访问改为 "127.0.0.1:5432:5432"
    volumes:
      - /opt/postgresql/data:/var/lib/postgresql/data   # 数据持久化
    # 资源限制,避免单个容器拖垮宿主机
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 2G
    # 健康检查:容器假活时能被发现
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s
    # 日志轮转,防止日志撑满磁盘
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

5. 启动服务

bash 复制代码
# 后台启动(老版本的启动命令:sudo docker-compose up -d)
#老版本不支持 docker compose(空格分隔)这个子命令。
sudo docker compose up -d

# 查看状态(等待片刻后 STATUS 应显示 healthy)
sudo docker compose ps

# 查看实时日志
sudo docker compose logs -f postgres

6. 验证数据库连接

bash 复制代码
sudo docker exec -it postgres_db psql -U postgres

进入 psql 后可执行 \l 查看数据库列表,\q 退出。

7. 配置远程访问

容器首次启动时会在数据目录生成默认的 postgresql.confpg_hba.conf。修改它们以允许远程连接:

bash 复制代码
# 1) 让 PostgreSQL 监听所有网卡
sudo docker exec -it postgres_db bash -c "sed -i \"s/^#listen_addresses = 'localhost'/listen_addresses = '*'/\" /var/lib/postgresql/data/postgresql.conf"

# 2) 放行远程访问(示例:放行 192.168.1.0/24 网段)
sudo docker exec -it postgres_db bash -c "echo \"host all all 192.168.1.0/24 md5\" >> /var/lib/postgresql/data/pg_hba.conf"

# 3) 重启容器使配置生效
sudo docker compose restart

⚠️ 安全提醒(务必阅读)

  • 上面的 pg_hba.conf 规则请按实际网段收紧,不要 在生产环境使用 0.0.0.0/0 md5(允许任意 IP 登录,风险极大)。
  • 默认密码 postgres 为公开示例,生产环境必须修改 :进入 psql 后执行 ALTER USER postgres PASSWORD '你的强密码';
  • 若数据库需要暴露到公网,强烈建议启用 SSL 加密,并通过防火墙/安全组限制 5432 端口来源 IP。
  • 应用代码中不要硬编码密码,推荐使用环境变量或配置中心。

五、常用管理命令

以下命令均在 /opt/postgresql/compose/ 目录(docker-compose.yml 所在目录)下执行。

bash 复制代码
# 查看容器状态
sudo docker compose ps

# 查看实时日志
sudo docker compose logs -f postgres

# 停止服务(保留数据)
sudo docker compose stop

# 启动服务
sudo docker compose start

# 重启服务(修改配置后使其生效)
sudo docker compose restart

# 进入容器内的 psql
sudo docker exec -it postgres_db psql -U postgres

# 进入容器 shell 排查
sudo docker exec -it postgres_db bash

# 停止并删除容器(数据目录 /opt/postgresql/data 保留,不会丢数据)
sudo docker compose down

# 修改 compose 文件后重新生效
sudo docker compose up -d

六、验证连接

1. 服务器本地验证

bash 复制代码
# 进入容器内部连接数据库
sudo docker exec -it postgres_db psql -U postgres

(成功结果如图所示)

2. Windows 本地连接

使用 Python 测试连接

进入虚拟环境,安装 psycopg2 库:

bash 复制代码
pip install psycopg2-binary

(成功结果如图所示)

创建测试脚本:

python 复制代码
# test01.py

import psycopg2

try:
    conn = psycopg2.connect(
        host="192.168.1.128",
        port="5432",
        database="postgres",
        user="postgres",
        password="postgres"
    )
    print("连接成功!")
    cursor = conn.cursor()
    cursor.execute("SELECT version();")
    print("PostgreSQL 版本:", cursor.fetchone())
    cursor.close()
    conn.close()
except Exception as e:
    print("连接失败:", e)

⚠️ 注意 :请将代码中的 192.168.1.128 替换为您自己的服务器 IP 地址。

(成功结果如图所示)

运行脚本:

bash 复制代码
python test01.py

七、备份与恢复

数据库最重要的运维能力就是「能恢复」。没有备份等于裸奔

1. 手动备份(逻辑备份)

bash 复制代码
# 备份单个数据库
sudo docker exec postgres_db pg_dump -U postgres postgres > backup_$(date +%F).sql


# 备份所有数据库与角色(推荐)
sudo docker exec postgres_db pg_dumpall -U postgres > full_backup_$(date +%F).sql

# 备份并压缩,节省空间
sudo docker exec postgres_db pg_dumpall -U postgres | gzip > full_backup_$(date +%F).sql.gz

2. 定时备份(crontab)

在宿主机执行 crontab -e,添加:

cron 复制代码
# 每天凌晨 2:30 全量备份,保留最近 14 天
30 2 * * * docker exec postgres_db pg_dumpall -U postgres | gzip > /opt/postgresql/backup/full_$(date +%F).sql.gz && find /opt/postgresql/backup -name "full_*.sql.gz" -mtime +14 -delete

3. 恢复

bash 复制代码
# 恢复全量备份
gunzip -c full_backup_2026-06-26.sql.gz | sudo docker exec -i postgres_db psql -U postgres

# 恢复单库
cat backup_2026-06-26.sql | sudo docker exec -i postgres_db psql -U postgres -d postgres

⚠️ 注意:恢复前请先停止写入业务,避免数据冲突;重要数据建议先在测试库演练恢复流程。


八、监控与告警

容器跑起来不等于健康,需要持续监控。

1. 容器层面

bash 复制代码
# 实时资源占用
sudo docker stats postgres_db

# 健康状态(compose 方式下已配置 healthcheck)
sudo docker inspect --format='{{.State.Health.Status}}' postgres_db

2. 数据库层面(轻量方案)

进入 psql 后执行:

sql 复制代码
-- 当前连接数
SELECT count(*) FROM pg_stat_activity;

-- 长事务(运行超过 5 分钟)
SELECT pid, now() - query_start AS duration, query
FROM pg_stat_activity
WHERE state = 'active' AND now() - query_start > interval '5 minutes';

-- 数据库大小
SELECT pg_size_pretty(pg_database_size('postgres'));

3. 专业监控(可选,进阶)

接入 postgres_exporter + Prometheus + Grafana,可图形化监控连接数、缓存命中率、复制延迟等,并配置告警(邮件/钉钉/飞书)。


九、故障排查

现象 可能原因 解决方案
容器启动后立即退出 数据目录权限不对 / 端口被占 sudo docker compose logs postgres 查看日志;确认 chown 999:999;`ss -tlnp
docker pull 超时 镜像源失效 修改 /etc/docker/daemon.json 更换可用镜像源,sudo systemctl restart docker 后重试
远程连接被拒绝 pg_hba.conf 未放行 / 未监听 进入容器检查 cat /var/lib/postgresql/data/pg_hba.conf;确认 listen_addresses = '*'sudo docker compose restart
password authentication failed 密码错误 / 用户名错误 sudo docker exec -it postgres_db psql -U postgres 本地登录验证
数据目录初始化失败 目录非空且不是 PG 数据目录 清空目录后重试(⚠️ 会丢数据,先备份)
容器健康检查 unhealthy 数据库未就绪或资源不足 sudo docker compose logssudo docker stats 排查;适当调大 start_period
磁盘写满 日志/备份未轮转 清理旧备份;确认 compose 中已配置 logging 轮转

常用排查命令汇总

bash 复制代码
# 看容器日志(最近 200 行)
sudo docker compose logs --tail 200 postgres

# 进入容器排查
sudo docker exec -it postgres_db bash

# 查看端口监听
ss -tlnp | grep 5432

# 查看磁盘空间
df -h

十、升级与回滚

1. 升级前必做

bash 复制代码
# 1) 完整备份(务必!)
sudo docker exec postgres_db pg_dumpall -U postgres > pre_upgrade_$(date +%F).sql

# 2) 停止并删除旧容器(数据目录保留)
cd /opt/postgresql/compose
sudo docker compose down

2. 升级(修改 compose 中的镜像版本)

修改 docker-compose.yml 中的 image: postgres:15.4 为新版本(如 postgres:16.2),然后:

bash 复制代码
sudo docker compose up -d

⚠️ 跨大版本升级 (如 15 → 16)不能直接挂载旧数据目录 ,必须使用 pg_upgrade 迁移数据,否则容器会启动失败。小版本升级(15.4 → 15.5)可直接升级。

3. 回滚

若升级后异常:

bash 复制代码
cd /opt/postgresql/compose
# 1) 将 docker-compose.yml 的 image 改回旧版本(如 postgres:15.4)
# 2) 重新启动(数据目录未被新版本改写时可直接回退)
sudo docker compose up -d

# 若数据目录已被改写,则从 pre_upgrade_*.sql 恢复
gunzip -c pre_upgrade_2026-06-26.sql | sudo docker exec -i postgres_db psql -U postgres

附录 A:安全加固清单

生产环境上线前,逐项确认:

  • 修改默认密码ALTER USER postgres PASSWORD '<强密码>';,禁用 postgres/postgres
  • 收紧 pg_hba.conf :用具体网段(如 192.168.1.0/24 scram-sha-256)替代 0.0.0.0/0,认证方式优先 scram-sha-256 而非 md5
  • 启用 SSL/TLSpostgresql.conf 设置 ssl = on,挂载证书,客户端强制 SSL 连接
  • 网络隔离:5432 端口不直接暴露公网;通过防火墙/安全组限制来源 IP
  • 最小权限账号:应用使用专用账号,仅授予对应库的增删改查权限,不要用 superuser
  • 凭证管理:密码通过环境变量/密钥管理服务注入,禁止硬编码进代码或镜像
  • 定期备份 :开启定时备份并演练恢复,备份文件异地存储
  • 日志审计:开启连接日志,定期审计异常登录
  • 版本补丁:关注 PostgreSQL 安全公告,及时升级小版本

附录 B:配置参数速查表

类别 参数 本文档取值 说明
连接 端口 5432 默认端口
连接 用户名 postgres 教程默认,生产请修改
连接 密码 postgres 教程默认,生产必须修改
连接 默认库 postgres 初始化数据库
持久化 数据目录(宿主机) /opt/postgresql/data 绑定挂载路径
持久化 数据目录(容器内) /var/lib/postgresql/data PG 标准路径
持久化 数据卷属主 999:999 容器内 postgres 用户的 UID:GID
部署 compose 目录 /opt/postgresql/compose docker-compose.yml 所在目录
镜像 版本 postgres:15.4 官方镜像
容器 名称 postgres_db 本文档统一命名
重启 策略 unless-stopped 宕机自动拉起,手动停止不拉起
时区 TZ Asia/Shanghai 在 compose 中设置

📝 维护建议 :本文档内嵌了大量截图,导致文件体积较大。建议后续将图片迁移至 docs/images/ 目录并以相对路径引用,便于 Git 版本管理与团队协作。