说实话,我一直是 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 强在哪?
| 对比项 | MySQL | PostgreSQL |
|---|---|---|
| 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 容器化部署方案,涵盖了从目录规划、权限设置、配置编写到远程访问的完整流程。
核心要点回顾:
- 目录结构要清晰,data 和 backup 分离
- 权限设置是关键,UID 999 和 chmod 700 缺一不可
- 生产环境要创建独立业务用户,避免使用超级管理员
- 远程访问需要配置两个文件:postgresql.conf 和 pg_hba.conf
- 定期备份不能少,自动化脚本安排上
这套方案已经在多个生产环境中验证过,稳定可靠。如果你正在考虑容器化数据库,不妨试试这个方案。
欢迎关注公众号 FishTech Notes,一块交流使用心得!