Docker 容器重启策略 restart 详解
1. 核心概念
-
“容器退出”:当容器内的主进程(PID 1)终止时(正常退出或崩溃),容器会停止运行。
-
“重启策略”:定义 Docker 引擎在容器退出后是否自动重新启动容器。
2. restart
的四种策略
策略 | 行为 | 适用场景 |
---|---|---|
no (默认) |
不重启 | 临时测试容器,无需自动恢复 |
always |
无条件重启(无论退出代码是什么) | 必须保持长期运行的服务(如 Nginx) |
on-failure |
仅在失败时重启(退出代码非 0) | 需要故障恢复的后台任务 |
unless-stopped |
总是重启,除非手动停止(即使宿主机重启也会自动启动) | 生产环境的持久化服务(如数据库) |
3. 重点解释 always
-
触发条件:
只要容器停止(无论是因为进程正常结束、崩溃、系统重启,还是手动docker stop
后又被启动),Docker 都会立即尝试重启它。 -
典型用例:
services: nginx: image: nginx restart: always # Nginx 必须持续运行
-
如果 Nginx 崩溃(或被
docker kill
),Docker 会自动重新创建容器。 -
注意:如果容器因配置错误无法启动(如端口冲突),Docker 会无限重试(可能导致日志爆炸)。
-
4. 与其他策略的对比
-
on-failure
vsalways
-
on-failure
只在程序异常退出(非 0 状态码)时重启,适合批处理任务。 -
always
即使程序正常退出(如exit 0
)也会重启,适合守护进程。
-
-
unless-stopped
vsalways
-
两者都会在崩溃时重启,但
unless-stopped
会记住手动停止的状态:docker stop my-container # 手动停止后,即使宿主机重启也不会自动启动
-
5. 实际示例
场景:一个可能崩溃的 Python Web 应用
services:
webapp:
image: python-app
restart: on-failure # 仅在崩溃时重启
environment:
- MAX_RETRIES=3
db:
image: postgres
restart: unless-stopped # 持久化服务,避免手动停止后被意外启动
6. 查看重启状态
docker inspect --format='{{.RestartCount}}' <容器名> # 查看重启次数
docker inspect --format='{{.State.Status}}' <容器名> # 查看当前状态
7. 注意事项
-
无限重启风险:如果容器因配置错误无法启动,
always
会导致频繁重启(可通过docker logs
排查)。 -
Swarm 模式:在集群中需使用
deploy.restart_policy
替代restart
。 -
资源占用:频繁重启可能消耗 CPU/内存,建议结合
deploy.resources.limits
限制资源。
通过合理选择重启策略,可以显著提升容器化服务的可靠性! 🚀
郭慕荣博客园