Docker Compose 重启策略不生效?排查与正确配置指南

主题: docker-compose-restart-policy-not-working更新于: 2026/7/9作者:AgentFactory 技术团队

快速答案

  • 核心结论:Docker Compose 重启策略不生效通常由三个原因导致:YAML 中 restart: no 被解析为布尔值 false、在非 Swarm 模式下使用了 deploy.restart_policy、或容器运行时间不足 10 秒的“稳定窗口”。
  • 第一检查项:确认你的 docker-compose.ymlrestart 属性写在顶层服务定义中(而非 deploy 下),且 restart: no 必须用引号包裹为 restart: "no"
  • 最小修复命令:将 restart: no 改为 restart: "no",或根据需求使用 restart: always / restart: unless-stopped,然后执行 docker-compose up --detach --build 重新部署。
  • 适用环境:Docker Compose v2/v3 均支持顶层的 restart 属性;deploy.restart_policy 仅适用于 Docker Compose v3 的 Swarm 模式(docker stack deploy)。

它解决什么问题 / 适用场景

Docker Compose 的重启策略用于定义容器在退出或崩溃后的自动恢复行为。它适用于:

  • 微服务架构:确保 API 服务、消息队列消费者等关键服务在异常退出后自动恢复。
  • 后台任务处理系统:如定时任务、数据同步脚本,避免因单次失败导致服务永久停止。
  • 开发环境:减少手动重启容器的操作,提升开发效率。

与 Kubernetes 的 restartPolicy 相比,Docker Compose 的重启策略更轻量,适合单机或小规模集群,无需额外的编排层。

核心配置 / 参数说明

以下参数均定义在 docker-compose.yml 的服务级别(顶层 restart)或 deploy 块下(Swarm 模式)。

顶层 restart 属性(普通模式)

参数值行为描述适用场景
"no"容器退出后不自动重启(默认行为)一次性任务、手动管理的服务
always无论退出码如何,总是重启容器;Docker 守护进程重启后也会重启Web 服务器、API 服务等需要持续运行的服务
unless-stopped总是重启,除非用户手动 docker stop 停止容器数据库、有状态服务,避免意外重启
on-failure仅在容器以非零退出码退出时重启批处理任务、数据迁移脚本
on-failure:5同上,但最多尝试重启 5 次需要限制重启次数的任务

Swarm 模式下的 deploy.restart_policy(仅 docker stack deploy 生效)

参数说明示例
condition重启条件:noneon-failureany(默认)condition: on-failure
delay重启尝试之间的等待时间delay: 5s
max_attempts最大重启尝试次数max_attempts: 3
window判断重启是否成功的窗口时间window: 120s

重要deploy.restart_policy 在普通 docker-compose up 中会被完全忽略,必须使用 docker stack deploy 部署到 Swarm 集群。

常见报错与排查

1. restart: no 被解析为布尔值 false

现象:容器退出后没有按预期不重启,或者重启策略完全失效。

根因:YAML 解析器将 no 视为布尔值 false,导致重启策略被设置为默认行为(即 restart: "no" 的等价效果),但实际行为可能因版本而异。

解决:始终使用引号包裹 "no"

YAML
services:
  my-service:
    image: my-image
    restart: "no"  # 必须用引号

2. 容器运行时间不足 10 秒

现象:容器启动后立即崩溃,但重启策略未生效,容器保持退出状态。

根因:Docker 的重启策略有一个 10 秒的“稳定窗口”——容器必须成功运行至少 10 秒后,重启策略才会被激活。如果容器在 10 秒内崩溃,Docker 认为这是启动失败,不会触发重启。

解决

  1. 检查容器日志:docker logs <container-name>
  2. 修复导致崩溃的代码或配置(如环境变量缺失、端口冲突、依赖服务未就绪)
  3. 如果依赖其他服务,使用 depends_on 并配合健康检查:
YAML
services:
  app:
    image: my-app
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

3. 在非 Swarm 模式下使用 deploy.restart_policy

现象:配置了 deploy.restart_policy,但容器崩溃后没有自动重启。

根因deploy 块下的配置仅适用于 Docker Compose v3 的 Swarm 模式。普通 docker-compose up 会忽略 deploy 下的所有配置。

解决:将重启策略移到顶层 restart 属性:

YAML
# 错误(非 Swarm 模式)
services:
  app:
    image: my-app
    deploy:
      restart_policy:
        condition: on-failure

# 正确(普通模式)
services:
  app:
    image: my-app
    restart: on-failure

4. 容器重启循环导致 Docker 保护模式

现象:容器反复重启,系统日志显示 Docker 进入“重启循环”保护模式,停止自动重启。

根因:Docker 内置防重启循环机制——如果容器在短时间内频繁崩溃,Docker 会逐渐增加重启间隔,最终停止重启。

解决

  1. 立即停止重启:docker update --restart=no <container-name>
  2. 检查容器日志,修复根本问题
  3. 使用 on-failure:3 限制最大重启次数,避免无限循环

生产环境实践与注意事项

重启策略选择建议

服务类型推荐策略原因
无状态 Web 服务always即使正常退出也应重启,确保持续可用
有状态数据库unless-stopped手动停止后不重启,避免数据损坏
批处理任务on-failure:3限制重启次数,避免无限重试
一次性初始化脚本"no"执行完成后不应重启

避免重启循环

  • 为关键服务设置 healthcheck,确保容器在依赖就绪后才启动
  • 使用 on-failure 并指定 max-retries,避免无限重启
  • 在 Swarm 模式下设置 delaywindow,错开重启时间

安全性建议

  • 不要对数据库等有状态服务使用 restart: always:如果数据文件损坏,容器会不断重启,可能导致数据丢失。使用 unless-stopped 并配合外部备份机制。
  • 避免资源竞争:多个容器同时重启可能导致 CPU/内存/端口冲突。在 Swarm 模式下使用 delay 参数错开重启时间。
  • 监控重启次数:使用 docker events 或监控工具跟踪容器重启事件,及时发现异常。

常见问题 FAQ

Q: 为什么我设置了 restart: always,但手动 docker stop 容器后,它没有立即重启?

A: 这是 Docker 的设计行为。当用户手动停止容器时,Docker 会尊重用户意图,不会立即重启。但是,当 Docker 守护进程重启(例如主机重启)时,always 策略会生效并重启容器。如果你希望容器在手动停止后也不重启,应使用 unless-stopped 策略。

Q: on-failurealways 策略在容器退出码为 0 时有什么区别?

A: 当容器退出码为 0(正常退出)时,on-failure 策略不会重启容器,而 always 策略会重启容器。因此,对于需要持续运行的服务(如 Web 服务器),即使正常退出也应重启,应使用 always。对于一次性任务(如数据库迁移),正常退出后不应重启,应使用 on-failure"no"

Q: 如何在 Docker Compose 中设置重启的最大尝试次数?

A: 在普通模式下,可以使用 restart: on-failure:5 来设置最大重启次数为 5 次。在 Swarm 模式下,可以使用 deploy.restart_policy.max_attempts: 5 来设置。注意,on-failure 后的数字是可选参数,如果不指定,Docker 会无限尝试重启。

相关深度解决方案

在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Docker Compose 环境变量配置实战:三种方式与避坑指南

在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 多阶段构建 Docker 镜像体积过大?从 1.2GB 到 150MB 的实战优化