大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
Docker 运行 PostgreSQL
这一课你将能做到
- 用 Docker Compose 定义带健康检查与命名卷的
postgres服务并启动 - 验证
down再up后数据仍在,会用docker volume inspect看卷 - 配置可选的 Spring
pg-dev联调方式,并与本机 MySQL 3306 / Redis 6379 并存
为什么要学
单条 docker run 适合第一节课;和后端、同事环境对齐时,Compose 文件才是可提交到仓库的「环境即代码」。命名卷避免删容器丢库;健康检查让依赖方等到「可接受连接」再启动。
官方镜像说明与 Compose 规范是操作依据;本课不取代云托管,但覆盖本地开发主路径。
先建立图像
docker-compose.dev.yml
│
▼
service: postgres
image: postgres:16-alpine
ports: 5432→5432
env: USER/PASSWORD/DB
volume: pg_data → /var/lib/postgresql/data
healthcheck: pg_isready
│
▼
本机 Spring (profile pg-dev) 或 psql
| 组件 | 端口 | 用途 |
|---|---|---|
| MySQL 8 | 3306 | CodeRoadMap 主库 |
| PostgreSQL | 5432 | 本 track 练习 |
| Redis | 6379 | redis-essentials 等 |
跟着做
步骤 1:准备 Compose 文件
在项目根或 backend/docker/ 创建 docker-compose.dev.yml(路径自定,以下为片段):
services:
postgres:
image: postgres:16-alpine
container_name: codeforge-pg
environment:
POSTGRES_USER: codeforge
POSTGRES_PASSWORD: devpass
POSTGRES_DB: codeforge_pg
ports:
- "5432:5432"
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U codeforge -d codeforge_pg"]
interval: 5s
timeout: 3s
retries: 5
volumes:
pg_data:
若已有 pg-dev 容器占名,先停掉旧容器,避免冲突。
步骤 2:启动并查看状态
docker compose -f docker-compose.dev.yml up -d postgres
docker compose -f docker-compose.dev.yml ps
状态应健康或至少 Up。日志:
docker compose -f docker-compose.dev.yml logs -f postgres
见到 ready 后 Ctrl+C 退出跟随(容器继续跑)。
步骤 3:写入数据
docker compose -f docker-compose.dev.yml exec postgres \
psql -U codeforge -d codeforge_pg -c "CREATE SCHEMA IF NOT EXISTS app; SELECT 1;"
或交互进入后 CREATE TABLE 插一行(可用前几课的表)。
步骤 4:验证卷持久化
docker compose -f docker-compose.dev.yml down
docker compose -f docker-compose.dev.yml up -d postgres
# 再查表/数据是否仍在
docker volume inspect $(docker volume ls -q | findstr pg_data)
(Linux/macOS 可用 grep;Windows 用 findstr 或直接 docker volume ls。)
数据还在 → 卷生效。down -v 会删卷,练习时小心。
步骤 5:Spring 联调(可选)
# application-pg-dev.yml
spring:
datasource:
url: jdbc:postgresql://127.0.0.1:5432/codeforge_pg?currentSchema=app
username: codeforge
password: devpass
driver-class-name: org.postgresql.Driver
java -jar backend.jar --spring.profiles.active=pg-dev
不要在未准备 PG 方言迁移时把生产 profile 指过来。
步骤 6:草绘三服务拓扑
纸上画出 MySQL / PG / Redis 与 backend 的连线:默认实线只连 MySQL;PG 虚线表示实验 profile。目的:防止「Compose 里有就等于生产在用」。
讲清楚要点
- 因为 数据目录挂到命名卷,所以 重建容器不等于丢库(除非
-v)。 - 健康检查 用
pg_isready,比盲sleep 5可靠。 - 环境变量仅首次初始化数据目录时建用户库:卷已存在时改密码环境变量不会自动改角色——要另改或删卷重建(仅限开发)。
- 端口映射冲突 时改主机端口,URL 跟着改。
- Compose 可提交:密码仍勿用生产真密;本地
devpass可,文档标明。 - 与 run 命令关系:Compose 是声明式;理解 run 有助于排错。
你可能会懵的地方
-
up很慢?
拉镜像、初始化数据目录。看 logs;首次较久。 -
health 一直 starting?
密码/库名与pg_isready参数不一致,或崩溃循环。读 logs。 -
down与stop?
stop停容器;down移除容器与网络,默认保留命名卷。 -
能否与 MySQL 写进同一 compose?
能。本站若已有 MySQL 服务文件,可合并;注意资源与启动顺序。 -
生产也用 Compose 跑数据库?
小型可以,多数生产用托管 RDS;Compose 更适合开发与演示。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 不挂卷却指望数据永久 | 丢库 | volumes: pg_data:… |
down -v 当日常重启 | 卷被删 | 日常用 down 或 stop |
| 主机端口写成 3306 | 冲击 MySQL | 5432 或其它空闲口 |
| 生产密码写进仓库 | 泄露 | 环境变量/密钥;仓库仅示例 |
| 未改迁移就切生产 profile | 启动失败或坏数据 | 仅 pg-dev 实验 |
自测三问
- 为什么
pg_isready出现在 healthcheck 里? docker compose down默认会删命名卷吗?删卷的标志是什么?- 本机 MySQL 与 PG 并存时默认端口各是多少?
小结一句话
Compose + 命名卷 + 健康检查,构成可重复的本地 PostgreSQL 环境,并可与 MySQL 主库并行。