零停机更新必须显式配置deploy.update_config(含order: start-first)和healthcheck,且需replicas≥2、compose v2.19+或swarm模式支持;否则docker-compose up -d默认执行停旧启新,导致中断。

直接用 docker-compose up -d 默认不会做平滑更新——它会先停旧容器、再启新容器,中间有服务中断窗口。真正实现零停机,必须显式配置 deploy.update_config 并配合 healthcheck,且仅在 Swarm 模式或 Compose v2.19+(启用 experimental 功能)下才被完整支持。
docker-compose.yml 必须加 deploy 和 healthcheck 才能触发滚动逻辑
Compose 本身不内置滚动更新引擎,它依赖底层编排器行为。如果你没写 deploy 块,哪怕只改了镜像标签,up -d 也会走“停→删→建→启”老路;加上后,才会尝试按策略替换。
-
update_config.order: start-first是关键:不设这个,就默认stop-first,必然中断 -
healthcheck不是可选项:没有它,Compose 不知道新容器是否真就绪,可能提前切流量 -
replicas必须 ≥2:单副本时即使设了start-first,启动新容器期间旧容器还在运行,但网络端点(如 Docker 内置 DNS)未必及时轮询到新实例,实际仍可能丢请求 - 注意版本兼容:
update_config在纯 Compose CLI(非 Swarm)中从 v2.19 起才支持,旧版会静默忽略该配置
执行更新时别用 docker-compose up -d 全量重跑
全量重跑会强制重建所有服务,哪怕你只改了一个 image,也可能因依赖关系触发无关服务重启。更稳妥的是锁定目标服务,跳过依赖检查:
- 只更新 web 服务:
docker-compose up -d --no-deps web - 如果服务间有严格依赖(比如 db 必须先就绪),
--no-deps可能导致新 web 启动失败——这时要确保应用内有连接重试逻辑,别指望 Compose 等 db ready - 避免用
docker-compose pull && docker-compose up -d组合:pull 失败时 up 仍会执行,可能混用旧镜像和新配置 - 生产环境建议加
--timeout 60:防止健康检查卡住,让命令不至于无限挂起
常见失败现象和对应检查点
更新卡在“Starting new container…”或日志里反复出现 healthcheck failed,不是配置写错了,而是底层条件没满足:
- 健康检查命令超时:
curl -f http://localhost在容器内可能不通——确认应用监听的是0.0.0.0:80而非127.0.0.1:80,否则 curl 自己连不上 - 端口映射冲突:如果
ports写成- "80:80",新旧容器会争抢宿主机 80 端口,导致第二个容器启动失败;应改用expose或依赖内部网络通信 - 资源不足:设了
parallelism: 2但宿主机内存不够同时跑 2 个副本,新容器会 OOM 退出,健康检查永远不通过 - 卷挂载变更:修改了
volumes或environment,Compose 会强制重建容器,绕过所有update_config策略——这类变更本质不可滚动,得接受短时中断
最易被忽略的一点:Docker Desktop 或 Linux 上的 Compose CLI 默认不启用 Swarm 模式,而 update_config 的完整语义(比如 failure_action: rollback)只在 Swarm 下生效;普通模式下它只是“尽力而为”,失败了也不会自动回滚,得手动 docker-compose up -d --force-recreate --no-deps web 切回去。











