【问题标题】:Docker compose stop depending service when done [duplicate]完成后,Docker撰写停止依赖服务[重复]
【发布时间】:2021-11-08 07:10:14
【问题描述】:

我有这个 docker-compose.yml,它运行一个依赖于 Redis 的节点脚本。

version: "3.9"
services:
  redis:
    image: "redis:alpine"
    # restart: always
    ports:
      - "127.0.0.1:6379:6379"
    volumes:
      - ./docker/redis:/data
  node:
    image: "node:17-alpine"
    user: "node"
    depends_on:
      - redis
    environment:
      - NODE_ENV=production
      - REDIS_HOST_ENV=redis
    volumes:
      - ./docker/node/src:/home/node/app
      - ./docker/node/log:/home/node/log
    expose:
      - "8081"
    working_dir: /home/node/app
    command: "npm start"

当使用docker compose up 启动这个脚本时,两个服务都会启动。但是,当node 服务完成时,redis 服务会继续运行。有没有办法定义redis服务可以在节点服务完成时停止?

【问题讨论】:

标签: docker docker-compose


【解决方案1】:

我已经检查了Compose Spec 的文档,但我没有找到任何可以让您根据另一个容器的状态立即停止容器的内容。也许真的有办法,但你总是可以通过使用健康检查来控制 redis 服务的行为:

services:
  redis:
    image: "redis:alpine"
    # restart: always
    ports:
      - "127.0.0.1:6379:6379"
    volumes:
      - ./docker/redis:/data
    healthcheck:
      test: ping -c 2 mynode || kill 1
      interval: 5s
      retries: 1
      start_period: 20s
  node:
    image: "node:17-alpine"
    container_name: mynode
    user: "node"
    depends_on:
      - redis
    environment:
      - NODE_ENV=production
      - REDIS_HOST_ENV=redis
    volumes:
      - ./docker/node/src:/home/node/app
      - ./docker/node/log:/home/node/log
    expose:
      - "8081"
    working_dir: /home/node/app
    command: "npm start"

对于node 服务,我添加了container_name: mynode,这是redis 服务所必需的,以便与它联系。如果未使用 hostname 属性指定,则容器名称也将成为主机名。

redis 服务有一个 healthcheck 每 5 秒 ping 一次节点容器,从容器启动 30 秒后开始。如果 ping 成功,容器标记为healthy,否则标记为killed。

此解决方案可能适用于您的情况,但也有一些缺点:

  • 健康检查功能在这里被滥用了,如果你有另一个健康检查呢?
  • 您不能总是杀死init 进程,因为默认情况下是受保护的。对此有一些discussions,似乎最流行的决定是使用tini 作为初始化进程。幸运的是,在您使用的图像中,这是可能的。
  • redis 服务通过主机名联系node 服务,这意味着在您的情况下它们应该在同一个网络中。当前网络是大多数时候应该避免的默认桥接网络。我建议您声明一个自定义桥接网络。
  • 此解决方案基于轮询node 容器,这不是很优雅,首先因为您必须希望healthcheck 部分中基于时间的参数“足够好”。

【讨论】:

  • 感谢您的详细解答!为此目的使用 healthcheck 感觉有点奇怪。 cmets 中建议的命令docker-compose up --abort-on-container-exit 看起来是一个更合适的解决方案
  • 这确实很奇怪,但据我所知,它是您唯一的选择之一。 --abort-on-container-exit 不会让你控制每一个服务的行为,但我很高兴这对你来说已经足够了 :)
猜你喜欢
  • 2017-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多