on-failure是唯一支持次数限制的重启策略,如on-failure:3表示最多重启3次;always和unless-stopped无上限,易引发雪崩。其语法在docker run和docker-compose.yml中均需严格为“on-failure:N”,YAML中必须加引号,且须配合healthcheck与depends_on.service_healthy才能真正防故障扩散。

on-failure 策略才是唯一支持 restart-limit 的方式
Docker 本身没有叫 restart-limit 的独立配置项,真正能限制重启次数的,只有 on-failure 策略配合数字后缀。比如 on-failure:3 表示最多重试 3 次,超过即停止;而 always 或 unless-stopped 完全不设上限,故障持续就会无限重启——这正是雪崩的温床。
docker run 和 docker-compose.yml 中的写法差异
命令行和 Compose 配置里,on-failure 的语法一致,但容易漏掉冒号或数字:
-
docker run -d --restart=on-failure:5 nginx✅ 正确:冒号后紧跟整数 -
docker run -d --restart=on-failure:5s❌ 错误:加了单位会静默退化为on-failure(无次数限制) - 在
docker-compose.yml中必须写成restart: "on-failure:3",引号不能省——YAML 解析器会把on-failure:3当作键值对处理,导致配置失效
为什么只靠 restart-limit 不足以防雪崩
单纯设个重试次数只是“刹车”,不是“避障”。常见疏漏包括:
- 没配
healthcheck:容器进程活着但业务不可用(如卡死、假死),on-failure根本不触发 - 依赖服务未就绪就启动:比如应用连不上
db直接退出,反复重试压垮数据库连接池 - 重试间隔太短:Docker 默认不退避,连续失败会瞬间打满日志和 CPU,加剧系统压力
- 没结合日志分析:重试 3 次后停摆,但没人查
docker logs <container></container>看退出码和堆栈,问题照旧
真正起效的组合配置示例
以一个需要连 MySQL 的 Web 服务为例,安全重启需同时约束次数、探测健康、错开启动:
version: '3.8'
services:
web:
image: my-web:latest
restart: "on-failure:3"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 20s
timeout: 5s
retries: 3
start_period: 40s
depends_on:
db:
condition: service_healthy
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: example
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "--password=example"]
interval: 15s
timeout: 10s
retries: 5
关键点:重试上限 + 健康检查 + depends_on 的 service_healthy 条件,三者缺一不可。否则,哪怕设了 on-failure:1,也挡不住因依赖缺失引发的循环崩溃。


















