on-failure:n是唯一支持次数限制的重启策略,适用于可能临时出错但不宜无限重试的服务,如定时任务、后台worker和初始化脚本;需与image等同级缩进,配合healthcheck和depends_on condition: service_healthy使用才有效。

在 docker-compose.yml 中配置“合理的重启次数限制”,核心不是单纯写个数字,而是结合服务类型、失败原因和系统韧性来选对策略——真正起作用的是 on-failure:N 这一种带次数限制的策略,其他策略(always、unless-stopped、no)都不支持次数限制。
哪些场景适合用 on-failure:N?
它专为“可能临时出错、但不该无限重试”的服务设计,比如:
- 定时任务容器(如每小时跑一次数据同步),失败可能是网络抖动或依赖未就绪,重试 3 次合理,再失败就该告警而不是死循环
- 后台 worker(处理消息队列),若因数据库连接超时失败,等几秒重试有意义;但若配置错误导致每次启动都报错,重试 5 次后停住,方便人工介入
- 初始化脚本类容器(如首次启动需建表、加载初始数据),失败大概率是环境问题,盲目重启没用
怎么写才生效?位置和缩进必须严格
restart: on-failure:3 必须和 image、ports、environment 处在同一缩进层级,属于 service 的直系字段:
services:
worker:
image: my-worker:latest
environment:
- DB_HOST=db
restart: on-failure:3 # ← 正确:与 environment 同级,缩进一致
depends_on:
db:
condition: service_healthy
常见失效原因:
- 顶格写在
services:下面(被忽略) - 缩进比
image多一级(YAML 解析为子对象,Compose 不识别) - 误放在
deploy:或healthcheck:块里
N 设多少算“合理”?参考这些原则
没有万能数字,但可按失败性质判断:
-
2~3 次:适合依赖短暂不可用(如 DB 启动慢、网络瞬断),配合
healthcheck+depends_on … condition: service_healthy效果更好 - 5 次:较常见默认值,给足时间等待下游就绪,也防偶然错误
- 不建议超过 10:重试太多易掩盖真实问题(比如密码写错、端口冲突),反而延长故障发现时间
-
0 次不合法:
on-failure:0等价于no,但写法不标准,直接用restart: no更清晰
光靠次数不够,得配合健康检查防“假成功”
只设 on-failure:5 不能解决“容器起来了但服务根本没跑起来”的问题。例如 PostgreSQL 容器进程在,但数据库还没接受连接。这时需要:
- 在依赖服务(如 db)中定义
healthcheck,用真实命令检测服务可用性 - 在上游服务(如 app)的
depends_on中指定condition: service_healthy
这样 Compose 才会真正等 DB “准备好”再启动 app,避免因抢跑导致反复失败重启。
不复杂但容易忽略











