Docker Compose 本身并不能识别异常的具体类型,它只是依据容器主进程的退出码以及 restart 重启策略来判断是否需要重新启动容器。其中,always 策略会无条件自动重启容器;unless-stopped 策略会排除手动停止的场景;on-failure 策略仅在退出码非 0(也就是程序异常退出)时才会重启,并且还支持限制重启次数;no 策略则表示容器退出后不自动重启。此外,还建议结合 healthcheck 健康检查来识别容器是否处于“假存活”状态,同时通过查看 logs 日志和执行 inspect 命令获取退出码(例如 137 通常表示内存不足导致 OOM),从而更准确地定位故障根因。

Docker Compose 自身并不会直接监控或干预容器内部的异常中断,例如应用 panic、段错误、空指针崩溃等问题。它主要依赖 Docker 引擎提供的重启策略(restart policy),在容器进程退出后决定是否进行自动恢复。也就是说,Compose 并不知道异常属于哪一种类型,它关注的重点只有两个:容器主进程是否退出,以及退出码是否满足预设的重启条件。
重启策略决定是否自动拉起容器实例
当容器中的应用崩溃并导致主进程退出时,Docker 守护进程会捕获退出状态,再根据你在 restart 字段中的配置决定是否重启容器:
- always:无论退出码是 0 还是非 0,都会立即重启,适用于需要持续运行的服务,例如 Nginx、Redis
- unless-stopped:与
always类似,但如果你手动执行过docker stop,容器就不会再被自动拉起——这是生产环境中非常常见的选择 - on-failure[:max]:仅在退出码非 0 时才重启,并可设置最多重试次数(如
on-failure:3),用于避免服务无限崩溃、无限重启 - no:默认策略,容器退出后不重启,更适合调试场景或一次性任务
需要配合健康检查提高异常识别能力
仅依赖进程退出码来判断容器状态存在明显局限:有些应用进程虽然没有退出,但实际上已经卡死、阻塞,或者无法正常响应请求,例如死锁、内存泄漏后的假活状态。此时仅靠 restart 策略通常无法自动恢复,建议在 Docker Compose 中配置 healthcheck 健康检查:
- 定义周期性探测命令(如
curl -f https://localhost/health || exit 1) - 设置超时时间、重试间隔以及失败阈值
- 当健康检查连续失败达到阈值后,Docker 会将容器状态标记为
unhealthy - 需要注意的是:健康检查状态本身不会直接触发容器重启,但可以结合外部工具(如 watchtower、自定义脚本)或上层编排平台(如 Swarm、K8s)执行进一步的自动恢复操作
日志和退出码是排查容器异常的重要依据
容器发生异常中断后,第一时间应查看日志和退出状态,以便快速定位问题根源:
docker compose logs -f可实时跟踪服务日志输出docker compose ps可查看当前容器状态以及退出码(Exit Code 列)- 退出码为非 0 时通常意味着异常退出,例如 137 表示 OOM Kill,139 表示 Segmentation Fault,可帮助快速判断故障类型
- 结合
docker inspect查看State.FinishedAt和State.ExitCode等信息,可进一步分析容器退出时机与原因
避免错误配置掩盖真正问题
如果盲目使用 restart: always,有时反而会让故障被“自动掩盖”:
- 应用持续崩溃又被反复重启,日志可能被轮转覆盖,导致首次异常信息难以追踪
- 资源类问题(如内存溢出、CPU 打满)可能引发连锁反应,频繁重启甚至会进一步加重系统压力
- 更合理的做法是结合资源限制(
deploy.resources.limits)、监控和告警体系,而不是只依赖自动重启机制
