容器崩溃后不重启是因为未设置或未生效restart策略;该策略仅在非人为主动停止时触发,常见策略包括no、on-failure、always和unless-stopped,需按服务类型合理选择并配合健康检查与依赖等待。

容器崩溃后不重启?检查 restart 策略是否生效
默认情况下,Docker 容器退出即停止,不会自动重启。必须显式设置 restart 策略,且该策略只在容器**非人为主动停止(如 docker stop)时才触发**。常见误解是以为只要加了 --restart=always 就万无一失,但实际它对 docker stop 或 docker kill -s SIGTERM 无效——这是设计行为,不是 bug。
验证当前容器的重启策略:docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' <container_name_or_id>
-
no:从不重启(默认) -
on-failure[:max-retries]:仅当退出码非 0 时重启,可选限制重试次数 -
always:无论退出码如何都重启(但跳过docker stop) -
unless-stopped:同always,但忽略已手动停止的容器(即宿主机重启后,它会启动;但若你执行过docker stop,它就不会再自启)
on-failure 和 always 怎么选?看服务类型和失败原因
无状态、可快速恢复的服务(如 Nginx、静态文件服务器)适合用 always;而有状态或依赖外部资源的服务(如数据库客户端、上游 API 调用失败导致崩溃),更适合 on-failure,避免因永久性错误(如配置错误、网络不可达)陷入无限重启循环。
- 用
on-failure:3表示最多重试 3 次,之后停住,方便人工介入排查 - 若容器因 OOM 被系统 kill,退出码为 137,
on-failure会捕获并重启;always同样适用 -
always在宿主机重启后也会拉起容器(前提是 Docker daemon 自启),而on-failure不保证这点——它只响应“本次运行周期内”的异常退出
启动时设置 restart 策略的三种写法,效果一致但场景不同
所有方式最终都写入容器的 HostConfig.RestartPolicy,没有功能差异,只有使用时机区别:
- 运行时指定:
docker run --restart=unless-stopped -d nginx:alpine - Compose 中配置(v3.8+):
services: web: image: nginx:alpine restart: unless-stopped - 已有容器修改(需先停止):
docker update --restart=on-failure:5 <container_id>(注意:不能对正在运行的容器实时更新 restart 策略,必须 stop 后 update 再 start)
重启延迟与冲突:别让容器抢端口或连不上依赖
Docker 本身不提供重启间隔控制(如“失败后等 5 秒再试”),on-failure 和 always 都是立即重启。如果容器启动依赖另一个服务(如 MySQL),而那个服务还没就绪,就会形成“启动→失败→重启→再失败”雪崩。
- 解决方案不是调
restart参数,而是改应用启动逻辑:用wait-for-it.sh、dockerize或健康检查 +depends_on:condition:service_healthy(Compose v2.3+) - 多个容器映射同一宿主机端口(如都用
-p 8080:80),重启时可能因端口被旧进程残留占用而失败,报错driver failed programming external connectivity—— 此时需确保容器干净退出,或加--rm配合always -
unless-stopped在宿主机 reboot 后自动启动,但如果镜像已更新或 volume 权限变化,可能启动失败却无提示,建议配合日志监控(docker logs -f)或健康检查告警
restart 是基础保障,不是兜底方案;真正健壮的自愈需要结合应用层健康探测、依赖等待和失败归因。


















