一条命令部署 PostgreSQL!容器化方案让数据库迁移效率提升 10 倍

16 阅读6分钟

说实话,我一直是 MySQL 的忠实用户。

从入行到现在,MySQL 陪我走过了无数个项目。熟悉它的脾气,踩过它的坑,也写过无数条 SQL。换数据库?从来没想过。

但最近两年,风向变了。

PostgreSQL 在开源社区的热度一路飙升。Stack Overflow 调查显示,它已经连续多年被评为"最受开发者喜爱的数据库"。

国内信创浪潮中,一大批国产数据库都是基于 PostgreSQL 二次开发——华为 openGauss、阿里 PolarDB、腾讯 TBase……为什么都选它?因为 PostgreSQL 的 License 是最宽松的 MIT 风格,不像 MySQL 被 Oracle 卡着脖子。

更让我触动的是 AI 时代的变化。Supabase 这个估值数十亿的"开源 Firebase",底层就是 PostgreSQL;pgvector 扩展让 PostgreSQL 直接存储和检索向量数据,成了 AI 应用的标配。很多 AI 项目甚至直接把 PostgreSQL 当向量数据库用,省掉了一个组件。

那 PostgreSQL 到底比 MySQL 强在哪?

对比项MySQLPostgreSQL
JSON 支持有,但功能有限原生 JSONB,查询性能强悍
全文搜索基础能力内置分词、权重、排名
扩展生态较少丰富(PostGIS、pgvector、pg_stat_statements...)
复杂查询JOIN 性能一般优化器更智能,复杂查询更强
数据类型基础类型数组、范围、几何、自定义类型
开源协议GPL(Oracle 控制)PostgreSQL License(完全自由)

说到底,MySQL 够用,但 PostgreSQL 更"能打"。

于是我也开始了 PostgreSQL 的学习之路。第一步当然是部署一个环境。用 Docker 容器化部署,干净利落,一条命令搞定。

今天就给大家分享这套 PostgreSQL 容器化部署方案,从目录结构到权限设置,从启动验证到远程访问,一次性讲透。


一、最终推荐目录结构

首先,我们需要一个清晰的目录结构。这样不仅方便管理,还能让你在出问题时快速定位。

/home/docker/postgres/
├── data/              # 数据核心目录
├── backup/            # 备份目录
└── docker-compose.yml # 编排文件

创建目录的命令:

mkdir -p /home/docker/postgres/{data,backup}

为什么这样设计?

  • data 目录:存放数据库核心数据,必须严格控制权限
  • backup 目录:定期备份数据,防止数据丢失
  • docker-compose.yml:统一管理容器配置,版本可控

二、最重要:权限设置(踩坑预警)

这一步 90% 的人会踩坑,请务必重视。

chown -R 999:999 /home/docker/postgres/data
chmod 700 /home/docker/postgres/data

为什么是 999?

PostgreSQL 容器内部运行用户是 UID 999,数据目录必须完全归它控制。如果你不设置这个权限,容器启动时会直接报错:

initdb: error: directory "/var/lib/postgresql/data" exists but is not empty

权限 700 的含义:

  • 只有目录所有者(UID 999)有读写执行权限
  • 其他任何用户都无法访问,保证数据安全

三、Docker Compose 配置文件

/home/docker/postgres/ 目录下创建 docker-compose.yml

version: "3.8"

services:
  postgres:
    image: postgres:16
    container_name: postgres
    restart: always
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: StrongPass_123
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"
    volumes:
      - /home/docker/postgres/data:/var/lib/postgresql/data

配置说明:

参数说明
image: postgres:16使用 PostgreSQL 16 版本,稳定且功能丰富
restart: always服务器重启后自动启动容器
POSTGRES_USER超级管理员用户名
POSTGRES_PASSWORD密码(生产环境请使用更强的密码)
POSTGRES_DB默认创建的数据库名
volumes数据持久化挂载

企业生产级建议:如果对数据一致性要求极高,建议使用精确版本标签如 postgres:16.9-bookworm,避免镜像自动升级导致的 glibc 版本兼容问题。个人或测试环境用 postgres:16 完全没问题。

转存失败,建议直接上传图片文件


四、启动与验证

启动容器:

cd /home/docker/postgres
docker compose up -d

说明docker compose up -d 会自动检查并拉取镜像,无需单独执行 docker pull。如果想提前拉取镜像,可以执行 docker pull postgres:16

查看启动日志:

docker logs -f postgres

看到这行就说明成功了:

database system is ready to accept connections

验证数据库:

docker exec -it postgres psql -U admin -d mydb

进入 psql 后,执行以下命令:

\l    -- 查看所有数据库
\dt   -- 查看当前库的表


五、远程访问配置(云服务器必看)

如果你需要从外部连接数据库(比如用 Navicat、DBeaver),需要做以下配置。

1. 修改 postgresql.conf

vim /home/docker/postgres/data/postgresql.conf

找到并修改:

listen_addresses = '*'

2. 修改 pg_hba.conf

vim /home/docker/postgres/data/pg_hba.conf

添加一行:

host    all    all    0.0.0.0/0    md5

3. 重启容器

docker restart postgres

4. 开放服务器端口

别忘了在云服务器控制台开放 5432 端口。

转存失败,建议直接上传图片文件


六、最佳实践:创建独立业务用户

生产环境中,千万不要用超级管理员做业务连接!

这是很多团队的血泪教训。正确的做法是创建独立的业务用户:

CREATE USER app_user WITH PASSWORD 'StrongPass123';
GRANT ALL PRIVILEGES ON DATABASE mydb TO app_user;

为什么要这样做?

  • 超级管理员权限过大,误操作可能导致灾难性后果
  • 独立用户可以精确控制权限范围
  • 便于审计和安全排查

七、自动备份脚本(生产必备)

数据是核心资产,定期备份必不可少。这里提供一个简单实用的自动备份脚本:

#!/bin/bash
# 保存为 /home/docker/postgres/backup.sh

BACKUP_DIR="/home/docker/postgres/backup"
DATE=$(date +%Y%m%d_%H%M%S)
CONTAINER="postgres"
DB_USER="admin"
DB_NAME="mydb"

# 创建备份
docker exec $CONTAINER pg_dump -U $DB_USER -d $DB_NAME -Fc > \
  $BACKUP_DIR/backup_$DATE.dump

# 保留最近 7 天备份
find $BACKUP_DIR -name "backup_*.dump" -mtime +7 -delete

echo "备份完成: backup_$DATE.dump"

设置定时任务:

chmod +x /home/docker/postgres/backup.sh
crontab -e

添加一行(每天凌晨 2 点自动备份):

0 2 * * * /home/docker/postgres/backup.sh >> /home/docker/postgres/backup.log 2>&1

恢复数据:

docker exec -i postgres pg_restore -U admin -d mydb < backup_20240101_020000.dump

八、附加技巧:Vim 粘贴不乱码

在使用 Vim 编辑配置文件时,如果你遇到过粘贴后格式乱掉的问题,这个技巧能帮你彻底解决。

编辑 Vim 配置:

vim ~/.vimrc

加入:

set pastetoggle=<F2>

使用方法:

  • F2 开启 paste 模式
  • 粘贴内容
  • 再按 F2 关闭

简单高效,从此告别粘贴格式问题。


九、统一管理建议

如果你有多个容器服务,建议统一采用以下目录结构:

/home/docker/
├── postgres/
│   ├── docker-compose.yml
│   ├── data/
│   └── backup/
├── redis/
│   ├── docker-compose.yml
│   └── data/
└── nginx/
    ├── docker-compose.yml
    └── conf.d/

这样每个服务都有独立的目录,配置清晰,迁移方便。


总结

今天分享的这套 PostgreSQL 容器化部署方案,涵盖了从目录规划、权限设置、配置编写到远程访问的完整流程。

核心要点回顾:

  1. 目录结构要清晰,data 和 backup 分离
  2. 权限设置是关键,UID 999 和 chmod 700 缺一不可
  3. 生产环境要创建独立业务用户,避免使用超级管理员
  4. 远程访问需要配置两个文件:postgresql.conf 和 pg_hba.conf
  5. 定期备份不能少,自动化脚本安排上

这套方案已经在多个生产环境中验证过,稳定可靠。如果你正在考虑容器化数据库,不妨试试这个方案。


欢迎关注公众号 FishTech Notes,一块交流使用心得!