正确配置需将restart字段置于service下级且与image等同级缩进,策略选unless-stopped最稳妥,配合healthcheck可防启动风暴。

直接在 docker-compose.yml 的每个服务下配置 restart 字段,就能让容器按需自动重启。关键不是写对了字段,而是选对策略、放对位置、配好依赖。
restart 字段必须放在 service 下级,且缩进对齐
很多人写了 restart 却没生效,根本原因是 YAML 缩进错误或位置不对。它必须和 image、ports、environment 处在同一缩进层级,不能顶格、不能多缩进一级,也不能写在 services 顶层。
- ✅ 正确写法:
services:
web:
image: nginx:latest
ports: ["80:80"]
restart: unless-stopped # ← 和 ports 同级,缩进一致
- ❌ 常见错误:
写成 restart: always 在 services: 下一级(顶格)、或缩进比 image 多两格、或误写在 deploy: 下面——这些都会被 Compose 忽略,容器启动后不重启。
四种策略怎么选:看服务性质和运维习惯
不同策略行为差异明显,选错容易引发维护困扰或意外拉起。
- no:适合一次性任务或调试容器,比如日志清理脚本、数据迁移工具。退出后绝不自动重试。
-
on-failure[:N]:适合可能临时失败但不该无限重启的服务,比如定时任务、批处理 worker。加数字可限重试次数,避免死循环,例如
on-failure:3。 -
always:适合长期运行、不允许中断的 Web 或 API 服务。注意:即使你手动
docker-compose stop,下次 Docker 守护进程重启(如宿主机重启),它仍会自动起来。 -
unless-stopped:生产环境最推荐。它和
always行为基本一致,但会记住“你曾手动 stop 过”,之后 Docker 重启也不会再拉起——方便做计划内维护。
配合 depends_on 和 healthcheck 避免启动失败循环
光设 restart 不够,若服务依赖数据库却等不及就开跑,可能反复崩溃重启(“重启风暴”)。
- 用
depends_on控制启动顺序,但注意它只等容器 启动成功,不等服务就绪; - 真正可靠的做法是加
healthcheck,再配合condition: service_healthy:
services:
db:
image: postgres:13
environment: POSTGRES_PASSWORD=example
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 3
<p>app:
image: myapp:v1
depends_on:
db:
condition: service_healthy # ← 等 db 健康检查通过才启动 app
restart: unless-stopped
验证和调试技巧
配置完别急着上线,先本地验证是否生效:
- 运行
docker-compose up -d启动; - 用
docker-compose ps查看状态,确认State列显示Up; - 手动停止容器:
docker-compose kill app或docker kill $(docker-compose ps -q app); - 等几秒后执行
docker-compose ps,观察容器是否已重新出现在Up状态; - 查日志确认重启行为:
docker-compose logs --tail=20 app,能看到重复的启动记录。
如果没重启,优先检查 YAML 缩进、restart 字段位置、Docker 版本兼容性(restart 在 Compose v2+ 原生支持,无需 deploy.restart_policy)。


















