news 2026/10/9 5:30:32

Docker 容器重启策略详解:always / unless-stopped / on-failure 怎么选

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker 容器重启策略详解:always / unless-stopped / on-failure 怎么选

服务器重启后容器没跟着起来、容器崩了没人拉、或者反过来——你明明 docker stop 了它却又自己活过来。这三个现象背后都是同一个配置在起作用:重启策略(restart policy)。

很多人图省事一律写 restart: always,结果在"手动停止后宿主机重启,容器又自己跑起来"这种场景踩坑。这篇把四种策略的行为差异讲透,给出一张行为对照表和选型建议。

四种策略

策略含义
no默认值。任何情况都不自动重启
on-failure[:次数]仅当容器非 0 退出码退出时重启,可限制最大重试次数
always无论怎么停的都重启;宿主机/Docker 守护进程重启后也拉起
unless-stopped类似 always,但手动 stop 过的容器,守护进程重启后不再拉起

设置方式:

docker run -d --restart unless-stopped --name app myapp:1.0 # on-failure 限制重试 5 次 docker run -d --restart on-failure:5 --name worker myworker:1.0

Compose:

services: app: image: myapp:1.0 restart: unless-stopped

行为对照表(核心)

四种策略在三个关键场景下的表现:

场景noon-failurealwaysunless-stopped
容器崩溃(非 0 退出)不重启重启重启重启
容器正常退出(退出码 0)不重启不重启重启重启
手动 docker stop 后保持停保持停保持停保持停
手动 stop 后宿主机重启保持停保持停自动拉起保持停
未手动 stop,宿主机重启保持停保持停自动拉起自动拉起

always 和 unless-stopped 的唯一区别就在第四行:手动 stop 之后宿主机重启,always 会把容器再拉起来(因为它只认"是否被 stop 过"在 daemon 重启时被重置),unless-stopped 会记住"你手动停过",保持停止。

这个差异在运维时很要命:你为了维护手动 stop 了一个容器,重启服务器后发现它又跑起来了(always),可能干扰维护窗口或抢占端口。用 unless-stopped 就不会。

on-failure 的"正常退出不重启":如果容器以退出码 0 结束(比如一个跑完就退的批处理任务),on-failure 不会重启它——这正是批处理想要的行为。而 always 会把它再拉起来无限循环跑,批处理任务用 always 是灾难。

查看和修改现有容器的策略

查看:

docker inspect <容器名> --format '{{.HostConfig.RestartPolicy.Name}} {{.HostConfig.RestartPolicy.MaximumRetryCount}}' # 输出如:unless-stopped 0 # on-failure 5

批量看所有容器:

docker ps -a --format "{{.Names}}\t{{.Status}}" for c in $(docker ps -aq); do echo -n "$(docker inspect $c --format '{{.Name}} ')"; docker inspect $c --format '{{.HostConfig.RestartPolicy.Name}}'; done

修改运行中的容器(不用重建):

docker update --restart unless-stopped <容器名> # 取消自动重启 docker update --restart no <容器名>

docker update 对重启策略立即生效,不用重启容器,运维改策略很方便。

选型建议

长期运行的服务(Web、数据库、中间件)→ unless-stopped

理由:崩溃要自动拉起,宿主机重启要自动恢复,但尊重运维的手动停止。这是生产环境最稳妥的默认值。

批处理 / 一次性任务(跑完就退)→ no 或 on-failure:N

理由:正常退出(码 0)不该重启。失败时希望重试几次就用 on-failure:3,避免无限重试。绝不要用 always。

容易抖动但希望有限重试的服务→ on-failure:N

理由:限制重试次数,避免 crash loop 把资源耗死或把日志刷爆。超过次数后保持停止,等人介入。

开发 / 测试容器→ no

理由:开发时你经常手动 stop/start,自动重启会干扰调试。

重启的退避机制(backoff)

Docker 对自动重启有指数退避:第一次崩溃后等 100ms 重启,再崩等 200ms、400ms、800ms……最长到 1 分钟。目的是避免 crash loop 瞬间打满 CPU 和日志。

这意味着:容器崩溃后不会立刻复活,docker ps 里可能短暂看到 Restarting 状态:

docker ps # STATUS: Restarting (1) 10 seconds ago

Restarting (1) 里的 1 是退出码。看到这个状态说明容器在反复崩溃-重启循环,用 docker logs 看崩溃原因,而不是怪重启策略。

容器成功运行 10 秒后,退避计数器重置。所以一个稳定跑了很久再崩的容器,重启会很快(从 100ms 重新开始)。

几个常见误区

误区一:restart 能修复崩溃。不能。重启策略只是"崩了再拉起来",崩溃的根因(配置错、OOM、依赖没就绪)还在。容器反复 Restarting 时先查 docker logs,别指望重启策略兜底。

误区二:on-failure 会对任何停止都重试。只对非 0 退出码。正常退出(0)不重试。想"无论如何都拉起"用 always/unless-stopped。

误区三:docker stop 后策略就失效了。stop 之后容器是 stopped 状态,策略不触发(没在崩)。但宿主机重启后,always 会无视你之前的 stop 把容器拉起,unless-stopped 才不会。这是两者关键差异。

误区四:Compose 的 restart 和 deploy.restart_policy 是一回事。单机 docker compose up 用 restart: 字段;swarm 模式用 deploy.restart_policy。非 swarm 场景写 restart: 就够了,两个都写可能冲突。

与依赖顺序的配合

重启策略只管"单个容器崩了拉起来",不管容器之间的启动顺序。如果 app 依赖 mysql,宿主机重启后两者都被拉起,但 mysql 可能还没就绪 app 就启动连库失败。

配合健康检查依赖(Compose)才能解决顺序问题:

services: mysql: image: mysql:8.4 restart: unless-stopped healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s retries: 10 app: image: myapp:1.0 restart: unless-stopped depends_on: mysql: condition: service_healthy

这样宿主机重启后,app 会等 mysql 健康检查通过才启动,避免"重启后应用连不上库"的经典问题。重启策略 + 健康检查依赖,两者配合才是完整的自愈方案。

小结

四种策略一句话记:no 不管、on-failure 只管崩、always 永远拉、unless-stopped 永远拉但尊重手动停止。

选型:长期服务用 unless-stopped(生产默认),批处理用 no 或 on-failure:N,开发用 no。查看用 docker inspect 的 RestartPolicy 字段,修改用 docker update --restart 不用重建。

记住两个关键点:always 和 unless-stopped 的区别只在"手动 stop 后宿主机重启"这一场景;重启策略不修复崩溃也不管启动顺序,崩溃循环查日志、顺序问题配健康检查依赖。把这两点搞清楚,重启策略就不再是玄学配置。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 5:27:07

CVXPY 优化生态全景:建模框架与求解器生态指南

科学计算 【免费下载链接】cvxpy A Python-embedded modeling language for convex optimization problems. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/cv/cvxpy 点击查看 免费下载 CVXPY 并不是孤立存在的——它处于一个庞大的凸优化软件生态的中心位置。本文基于…

作者头像 李华
网站建设 2026/10/9 5:26:47

python中常用语句

python中常用的语句 &#xff08;1&#xff09;if语句 1、if语句的单分支 格式&#xff1a; if 判断条件:执行语句1 else:执行语句2案例&#xff1a; a10 if a>9:print("ok") else:print("no")2、if语句的多分支 格式&#xff1a;if 条件1:执行语句1…

作者头像 李华
网站建设 2026/10/9 5:26:26

零代码AI图像分割:人像抠图、老照片修复与动漫增强实战指南

1. 这不是“一键美颜”&#xff0c;而是图像语义理解的落地切口你有没有试过把一张泛黄卷边的老照片扫描进电脑&#xff0c;想发到朋友圈却卡在第一步——人像边缘毛糙、背景杂乱、发丝和衣领糊成一片&#xff1f;或者手头有一张动漫线稿&#xff0c;想快速上色但反复用魔棒选区…

作者头像 李华