容器重启策略配错会导致不重启或无限重启,关键在于选对类型:web服务用always,数据库用unless-stopped,批处理用no,worker用on-failure:5;须配合资源限制、healthcheck和退出码监控。
容器重启策略配错,不是不重启,就是无限重启——生产环境里最常踩的坑就在这儿。关键不在“设不设”,而在“设对没”:策略类型、触发条件、资源配合、日志可观测性,缺一不可。
重启策略选错:最典型误配场景
很多人把 always 当成“万能保险”,但其实它会在手动 stop 后自动拉起,导致运维停服务失败;而 unless-stopped 才是数据库、消息队列等需长期运行又允许人工干预的首选。
-
web 服务(Nginx/API):用
always,确保宿主机重启后自动恢复 -
MySQL/PostgreSQL:用
unless-stopped,避免误操作后无法真正停机 -
批处理任务或数据迁移脚本:明确写
restart: no,防止失败后反复重试掩盖错误 -
worker 类后台任务:用
on-failure:5,加delay:10s防雪崩,避免瞬时密集重启压垮依赖服务
策略生效但容器卡住不启动?查这三处
配置写了,docker ps -a 看到状态是 Exited (1),但没立即重启——不是策略失效,而是被底层机制拦住了。
-
Docker 守护进程负载高:执行
systemctl status docker和journalctl -u docker -n 20,看是否有调度延迟或 event queue 积压 -
容器启动耗时超默认超时:Docker 默认等待容器在 10 秒内进入 running 状态,否则标记为失败。若应用冷启慢(如 Java Spring Boot),需配合
healthcheck或调整启动逻辑 -
资源争抢未显式限制:OOM Killer 杀进程后,
on-failure会触发,但若内存持续不足,新实例仍秒退。务必配deploy.resources.limits.memory
验证与监控:不能只靠“看着像正常”
重启次数、退出码、健康状态,必须可量化。光看 docker ps 是盲人摸象。
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
- 查最近一次退出码:
docker inspect myapp --format='{{.State.ExitCode}}' - 查累计重启次数:
docker inspect myapp --format='{{.RestartCount}}' - 查是否处于健康状态:
docker inspect myapp --format='{{.State.Health.Status}}'(需定义 healthcheck) - 结合日志定位根本原因:
docker logs --since "10m" myapp | tail -20,重点搜OOM、Connection refused、timeout
生产环境黄金配置标准(Docker Compose v3.8+)
这不是模板拼凑,而是经高频故障反推的最小安全集:
- 所有长期服务必须声明
restart,禁用默认no行为 - 数据库类服务统一用
unless-stopped,并挂载外部 volume,禁止使用匿名卷 - 每个服务必须配
healthcheck,且start_period要大于应用实际冷启时间 - 强制设置
deploy.resources:至少限定memory,CPU 可选但建议设cpus: "0.5"防止单容器吃满核 - 日志统一配
logging.driver: "json-file"+options.max-size: "10m"+options.max-file: "3"
策略本身不复杂,但脱离资源约束、健康检查和可观测性,就是纸上谈兵。

















