用 Docker Compose 一键拉起分布式数据库并自动执行 Schema 迁移,关键在于串联启动、等待就绪、执行迁移三阶段:优先选用支持 /docker-entrypoint-initdb.d 或类似初始化机制的官方镜像;用 wait-for-it 或 dockerize 实现服务级健康等待;将迁移封装为独立 migrator 服务,避免污染 DB 容器;结合 healthcheck + init: true 实现声明式可靠编排。

用 Docker Compose 一键拉起分布式数据库并自动执行 Schema 迁移,核心在于把数据库服务启动、等待就绪、迁移脚本执行这三个阶段串成可靠流水线。关键不是“能不能”,而是“怎么让迁移只跑一次、且等库真正可连后再跑”。
选对数据库镜像,优先支持初始化脚本
多数主流分布式数据库(如 CockroachDB、TiDB、YugabyteDB)的官方镜像都内置了 /docker-entrypoint-initdb.d 机制或类似逻辑,能自动执行挂载的 SQL 或 Shell 脚本。比如:
- CockroachDB 官方镜像支持通过
COCKROACH_INIT_SQL环境变量指定初始化 SQL 文件路径; - YugabyteDB 的
yugabyted启动模式下,可配合init-sql挂载点; - 若用 PostgreSQL 分片方案(如 Citus),直接复用 PG 的
/docker-entrypoint-initdb.d/*.sql即可。
务必查清你所用数据库版本的文档,确认其是否原生支持「启动时自动执行初始化」——这是免写额外容器的关键。
用 wait-for-it 或 dockerize 实现可靠依赖等待
分布式数据库启动耗时长(尤其多节点间 gossip 同步),单纯靠 depends_on 不够——它只等容器启动,不等服务就绪。必须加一层健康检查:
- 在应用或迁移服务的容器中,加入 wait-for-it.sh,例如:
./wait-for-it.sh db:26257 --timeout=120 --command="sh migrate.sh"; - 或用更轻量的
dockerize:dockerize -wait tcp://db:26257 -timeout 120s -- sh migrate.sh; - 对 CockroachDB,还可调用
cockroach node status --host=db:26257判断集群是否 ready。
迁移脚本封装为独立服务,避免污染数据库容器
不要把 migration 逻辑塞进数据库镜像里,而应单独定义一个 migrator 服务:
- 基于
alpine:latest或python:slim构建最小镜像; - 把
flyway、liquibase、sql-migrate或自研 CLI 工具 COPY 进去; - 挂载
./migrations:/migrations,并通过环境变量传入数据库连接参数; - 设置
restart: on-failure,确保失败后重试,配合 wait 机制形成兜底。
示例 Compose 片段:
migrator:
image: flyway/flyway:9.22.3
volumes:
- ./migrations:/flyway/sql
environment:
- FLYWAY_URL=jdbc:postgresql://db:5432/myapp
- FLYWAY_USER=postgres
- FLYWAY_PASSWORD=postgres
depends_on:
- db
command: ["migrate"]
# 加入等待逻辑(需自定义 entrypoint 或用 wrapper)
利用 healthcheck + init container 模式(Docker Compose v2.3+)
新版 Compose 支持 init 字段和更细粒度的 healthcheck,可组合出声明式流程:
- 为
db服务定义healthcheck,用 curl 或 pg_isready 探活; - 设
restart: "no"防止迁移重复执行; - 用
init: true标记 migrator,保证它一定在 db 健康后、其他服务前运行; - 迁移成功后,migrator 容器退出,不影响后续服务启停。
这样整个过程完全由 Compose 编排驱动,无需外部调度,适合本地开发与 CI 环境快速复现。










