Docker Compose在开始Y

时间:2015-07-31 12:25:23

标签: docker-compose

我正在使用来自here的rabbitmq和一个简单的python示例 和docker-compose一起。我的问题是我需要等待rabbitmq完全启动。从我到目前为止的搜索结果来看,我不知道如何等待容器x(在我的情况下是工人)直到y(rabbitmq)开始。

我发现这个blogpost,他检查其他主机是否在线。 我还发现了docker command

  

等待

     

用法:docker等待CONTAINER [CONTAINER ...]

     

阻止容器停止,然后打印其退出代码。

等待容器停止可能不是我想要的但是如果 它是,是否可以在docker-compose.yml中使用该命令? 到目前为止,我的解决方案是等待几秒钟并检查端口,但这是实现此目的的方法吗?如果我不等,我会收到错误。

搬运工-compose.yml

worker:
    build: myapp/.
    volumes:
    - myapp/.:/usr/src/app:ro

    links:
    - rabbitmq
rabbitmq:
    image: rabbitmq:3-management

python hello sample(rabbit.py):

import pika
import time

import socket

pingcounter = 0
isreachable = False
while isreachable is False and pingcounter < 5:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect(('rabbitmq', 5672))
        isreachable = True
    except socket.error as e:
        time.sleep(2)
        pingcounter += 1
    s.close()

if isreachable:
    connection = pika.BlockingConnection(pika.ConnectionParameters(
            host="rabbitmq"))
    channel = connection.channel()

    channel.queue_declare(queue='hello')

    channel.basic_publish(exchange='',
                          routing_key='hello',
                          body='Hello World!')
    print (" [x] Sent 'Hello World!'")
    connection.close()

工人的Dockerfile:

FROM python:2-onbuild
RUN ["pip", "install", "pika"]

CMD ["python","rabbit.py"]

2015年11月更新

shell脚本或在程序中等待可能是一种可能的解决方案。但看到这个Issue后,我正在寻找docker / docker-compose本身的命令或功能。

他们提到了实施健康检查的解决方案,这可能是最佳选择。开放式TCP连接并不意味着您的服务已准备就绪或可能已准备就绪。除此之外,我需要在dockerfile中更改我的入口点。

所以我希望得到一个用docker-compose on board命令的答案,如果他们完成这个问题,希望就是这样。

2016年3月更新

有一个proposal用于提供内置方法来确定容器是否“活着”。所以docker-compose可以在不久的将来使用它。

2016年6月更新

健康检查似乎是版本1.12.0中的docker integrated

2017年1月更新

我找到了一个docker-compose解决方案,请参阅: Docker Compose wait for container X before starting Y

18 个答案:

答案 0 :(得分:202)

最后找到了一个使用docker-compose方法的解决方案。由于docker-compose文件格式2.1,您可以定义healthchecks

我是在example project中做到的 你需要安装至少docker 1.12.0+。 我还需要extend the rabbitmq-management Dockerfile,因为curl没有安装在官方图片上。

现在我测试rabbitmq-container的管理页面是否可用。如果curl使用exitcode 0完成,则将启动容器应用程序(python pika)并将消息发布到hello队列。它现在正在工作(输出)。

docker-compose(版本2.1):

version: '2.1'

services:
  app:
    build: app/.
    depends_on:
      rabbit:
        condition: service_healthy
    links: 
        - rabbit

  rabbit:
    build: rabbitmq/.
    ports: 
        - "15672:15672"
        - "5672:5672"
    healthcheck:
        test: ["CMD", "curl", "-f", "http://localhost:15672"]
        interval: 30s
        timeout: 10s
        retries: 5

<强>输出:

rabbit_1  | =INFO REPORT==== 25-Jan-2017::14:44:21 ===
rabbit_1  | closing AMQP connection <0.718.0> (172.18.0.3:36590 -> 172.18.0.2:5672)
app_1     |  [x] Sent 'Hello World!'
healthcheckcompose_app_1 exited with code 0

Dockerfile(rabbitmq + curl):

FROM rabbitmq:3-management
RUN apt-get update
RUN apt-get install -y curl 
EXPOSE 4369 5671 5672 25672 15671 15672

版本3不再支持depends_on的条件格式。 所以我从depends_on转移到重启失败。现在我的app容器将重启2-3次直到它正常工作,但它仍然是一个docker-compose功能而不会覆盖入口点。

docker-compose(第3版):

version: "3"

services:

  rabbitmq: # login guest:guest
    image: rabbitmq:management
    ports:
    - "4369:4369"
    - "5671:5671"
    - "5672:5672"
    - "25672:25672"
    - "15671:15671"
    - "15672:15672"
    healthcheck:
        test: ["CMD", "curl", "-f", "http://localhost:15672"]
        interval: 30s
        timeout: 10s
        retries: 5

  app:
    build: ./app/
    environment:
      - HOSTNAMERABBIT=rabbitmq
    restart: on-failure
    depends_on:
      - rabbitmq
    links: 
        - rabbitmq

答案 1 :(得分:68)

Natively that is not possible, yet. See also this feature request.

So far you need to do that in your containers CMD to wait until all required services are there.

In the Dockerfiles CMD you could refer to your own start script that wraps starting up your container service. Before you start it, you wait for a depending one like:

Dockerfile

FROM python:2-onbuild
RUN ["pip", "install", "pika"]
ADD start.sh /start.sh
CMD ["/start.sh"]

start.sh

#!/bin/bash
while ! nc -z rabbitmq 5672; do sleep 3; done
python rabbit.py

Probably you need to install netcat in your Dockerfile as well. I do not know what is pre-installed on the python image.

There are a few tools out there that provide easy to use waiting logic, for simple tcp port checks:

For more complex waits:

答案 2 :(得分:34)

使用restart: unless-stoppedrestart: always可以解决此问题。

如果当RabbitMQ没有准备好时工人container停止,它将重新启动,直到它为止。

答案 3 :(得分:28)

最近他们添加了depends_on feature

修改

从撰写版本2.1+开始,您可以将healthcheckversion: '2.1' services: web: build: . depends_on: db: condition: service_healthy redis: condition: service_started redis: image: redis db: image: redis healthcheck: test: "exit 0" 结合使用来实现此目的:

From the docs

depends_on

2.1版之前

您仍然可以使用version: '2' services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres ,但它只影响启动服务的订单 - 而不是在相关服务启动之前它们已准备就绪。

似乎至少需要1.6.0版本。

用法看起来像这样:

awk '{match($0, /[)] +([^ ]+)/, var);print var[1];}'

来自文档:

  

服务之间的快速依赖关系,它有两个影响:

     
      
  • docker-compose up将按依赖顺序启动服务。在以下示例中,将在web之前启动db和redis。
  •   
  • docker-compose up SERVICE将自动包含SERVICE的依赖项。在以下示例中,docker-compose up web还将创建并启动db和redis。
  •   

注意:据我所知,虽然这确实设置了容器的加载顺序。它不保证容器内的服务实际已加载。

例如,你的postgres 容器可能已启动。但postgres服务本身可能仍在容器内进行初始化。

答案 4 :(得分:14)

您也可以将其添加到命令选项中,例如。

Using version ^3.0 for behat/behat
Using version ^1.7 for behat/mink
Using version ^2.1 for behat/mink-extension
Using version ^1.0 for laracasts/behat-laravel-extension
./composer.json has been updated
> php artisan clear-compiled
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: don't install behat/behat v3.0.15
    - Conclusion: don't install behat/behat v3.0.14
    - Conclusion: don't install behat/behat v3.0.13
    - Conclusion: don't install behat/behat v3.0.12
    - Conclusion: don't install behat/behat v3.0.11
    - Conclusion: don't install behat/behat v3.0.10
    - Conclusion: don't install behat/behat v3.0.9
    - Conclusion: don't install behat/behat v3.0.8
    - Conclusion: don't install behat/behat v3.0.7
    - behat/mink-extension v2.1.0 requires behat/behat ~3.0,>=3.0.5 -> satisfiable by behat/behat[v3.0.10, v3.0.11, v3.0.12, v3.0.13, v3.0.14, v3.0.15, v3.0.5, v3.0.6, v3.0.7, v3.0.8, v3.0.9].
    - Conclusion: don't install behat/behat v3.0.6
    - Installation request for behat/mink-extension ^2.1 -> satisfiable by behat/mink-extension[v2.1.0].
    - Conclusion: remove symfony/yaml v3.0.1
    - Conclusion: don't install symfony/yaml v3.0.1
    - behat/behat v3.0.5 requires symfony/yaml ~2.1 -> satisfiable by symfony/yaml[v2.1.0, v2.1.1, v2.1.10, v2.1.11, v2.1.12, v2.1.13, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.1.6, v2.1.7, v2.1.8, v2.1.9, v2.2.0, v2.2.1, v2.2.10, v2.2.11, v2.2.2, v2.2.3, v2.2.4, v2.2.5, v2.2.6, v2.2.7, v2.2.8, v2.2.9, v2.3.0, v2.3.1, v2.3.10, v2.3.11, v2.3.12, v2.3.13, v2.3.14, v2.3.15, v2.3.16, v2.3.17, v2.3.18, v2.3.19, v2.3.2, v2.3.20, v2.3.21, v2.3.22, v2.3.23, v2.3.24, v2.3.25, v2.3.26, v2.3.27, v2.3.28, v2.3.29, v2.3.3, v2.3.30, v2.3.31, v2.3.32, v2.3.33, v2.3.34, v2.3.35, v2.3.36, v2.3.37, v2.3.4, v2.3.5, v2.3.6, v2.3.7, v2.3.8, v2.3.9, v2.4.0, v2.4.1, v2.4.10, v2.4.2, v2.4.3, v2.4.4, v2.4.5, v2.4.6, v2.4.7, v2.4.8, v2.4.9, v2.5.0, v2.5.1, v2.5.10, v2.5.11, v2.5.12, v2.5.2, v2.5.3, v2.5.4, v2.5.5, v2.5.6, v2.5.7, v2.5.8, v2.5.9, v2.6.0, v2.6.1, v2.6.10, v2.6.11, v2.6.12, v2.6.13, v2.6.2, v2.6.3, v2.6.4, v2.6.5, v2.6.6, v2.6.7, v2.6.8, v2.6.9, v2.7.0, v2.7.1, v2.7.2, v2.7.3, v2.7.4, v2.7.5, v2.7.6, v2.7.7, v2.7.8, v2.7.9, v2.8.0, v2.8.1, v2.8.2].
    - Can only install one of: symfony/yaml[v2.1.0, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.1, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.10, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.11, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.12, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.13, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.2, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.3, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.4, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.5, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.6, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.7, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.8, v3.0.1].
    - Can only install one of: symfony/yaml[v2.1.9, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.0, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.1, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.10, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.11, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.2, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.3, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.4, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.5, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.6, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.7, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.8, v3.0.1].
    - Can only install one of: symfony/yaml[v2.2.9, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.0, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.1, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.10, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.11, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.12, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.13, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.14, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.15, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.16, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.17, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.18, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.19, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.2, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.20, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.21, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.22, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.23, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.24, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.25, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.26, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.27, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.28, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.29, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.3, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.30, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.31, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.32, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.33, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.34, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.35, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.36, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.37, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.4, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.5, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.6, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.7, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.8, v3.0.1].
    - Can only install one of: symfony/yaml[v2.3.9, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.0, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.1, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.10, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.2, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.3, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.4, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.5, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.6, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.7, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.8, v3.0.1].
    - Can only install one of: symfony/yaml[v2.4.9, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.0, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.1, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.10, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.11, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.12, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.2, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.3, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.4, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.5, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.6, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.7, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.8, v3.0.1].
    - Can only install one of: symfony/yaml[v2.5.9, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.0, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.1, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.10, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.11, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.12, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.13, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.2, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.3, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.4, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.5, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.6, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.7, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.8, v3.0.1].
    - Can only install one of: symfony/yaml[v2.6.9, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.0, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.1, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.2, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.3, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.4, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.5, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.6, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.7, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.8, v3.0.1].
    - Can only install one of: symfony/yaml[v2.7.9, v3.0.1].
    - Can only install one of: symfony/yaml[v2.8.0, v3.0.1].
    - Can only install one of: symfony/yaml[v2.8.1, v3.0.1].
    - Can only install one of: symfony/yaml[v2.8.2, v3.0.1].
    - Installation request for symfony/yaml == 3.0.1.0 -> satisfiable by symfony/yaml[v3.0.1].


Installation failed, reverting ./composer.json to its original content.

https://github.com/docker/compose/issues/374#issuecomment-156546513

在端口上等待你也可以使用这样的东西

command: bash -c "sleep 5; start.sh"

增加等待时间,你可以更多地进行攻击:

command: bash -c "while ! curl -s rabbitmq:5672 > /dev/null; do echo waiting for xxx; sleep 3; done; start.sh"

答案 5 :(得分:8)

对于容器开始订购使用

depends_on:

等待上一个容器启动使用脚本

entrypoint: ./wait-for-it.sh db:5432

本文将为您提供帮助 https://docs.docker.com/compose/startup-order/

答案 6 :(得分:6)

restart: on-failure 为我做了诀窍......见下文

---
version: '2.1'
services:
  consumer:
    image: golang:alpine
    volumes:
      - ./:/go/src/srv-consumer
    working_dir: /go/src/srv-consumer
    environment:
      AMQP_DSN: "amqp://guest:guest@rabbitmq:5672"
    command: go run cmd/main.go
    links:
          - rabbitmq
    restart: on-failure

  rabbitmq:
    image: rabbitmq:3.7-management-alpine
    ports:
      - "15672:15672"
      - "5672:5672"

答案 7 :(得分:5)

您还可以通过使用netcat(使用docker-wait脚本)设置等待服务启动的端点来解决此问题。我喜欢这种方法,因为您在command中仍然有一个干净的docker-compose.yml部分,并且您不需要在您的应用中添加特定于Docker的代码:

version: '2'
services:
  db:
    image: postgres
  django:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    entrypoint: ./docker-entrypoint.sh db 5432
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

然后是您的docker-entrypoint.sh

#!/bin/sh

postgres_host=$1
postgres_port=$2
shift 2
cmd="$@"

# wait for the postgres docker to be running
while ! nc $postgres_host $postgres_port; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"

# run the command
exec $cmd

现在官方docker documentation中记录了这一点。

PS:如果没有,请在您的docker实例中安装netcat。为此,请将其添加到Docker文件中:

RUN apt-get update && apt-get install netcat-openbsd -y 

答案 8 :(得分:4)

有一个名为“docker-wait”的可立即使用的实用程序,可用于等待。

答案 9 :(得分:2)

基于此博文https://8thlight.com/blog/dariusz-pasciak/2016/10/17/docker-compose-wait-for-dependencies.html

我配置了docker-compose.yml,如下所示:

version: "3.1"

services:
  rabbitmq:
    image: rabbitmq:3.7.2-management-alpine
    restart: always
    environment:
      RABBITMQ_HIPE_COMPILE: 1
      RABBITMQ_MANAGEMENT: 1
      RABBITMQ_VM_MEMORY_HIGH_WATERMARK: 0.2
      RABBITMQ_DEFAULT_USER: "rabbitmq"
      RABBITMQ_DEFAULT_PASS: "rabbitmq"
    ports:
      - "15672:15672"
      - "5672:5672"
    volumes:
      - data:/var/lib/rabbitmq:rw

  start_dependencies:
    image: alpine:latest
    links:
      - rabbitmq
    command: >
      /bin/sh -c "
        echo Waiting for rabbitmq service start...;
        while ! nc -z rabbitmq 5672;
        do
          sleep 1;
        done;
        echo Connected!;
      "

volumes:
  data: {}

然后我做run =&gt;:

docker-compose up start_dependencies

rabbitmq服务将以守护进程模式启动,start_dependencies将完成工作。

答案 10 :(得分:2)

如果您只想在其他服务成功完成后启动服务(例如迁移、数据填充等),docker-compose 1.29 版附带 build in functionality for this - service_completed_successfully

depends_on:
  <service-name>:
    condition: service_completed_successfully

根据specification

<块引用>

service_completed_successfully - 指定依赖项在启动依赖项服务之前应该运行到成功完成

答案 11 :(得分:0)

替代解决方案之一是使用容器编排解决方案,例如Kubernetes。 Kubernetes支持init容器,该容器可以在其他容器可以启动之前运行完成。您可以在此处找到SQL Server 2017 Linux容器的示例,其中API容器使用init容器初始化数据库

https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html

答案 12 :(得分:0)

在此示例中,main容器在开始响应ping时等待worker

version: '3'
services:
  main:
    image: bash
    depends_on:
     - worker
    command: bash -c "sleep 2 && until ping -qc1 worker; do sleep 1; done &>/dev/null"
    networks:
      intra:
        ipv4_address: 172.10.0.254
  worker:
    image: bash
    hostname: test01
    command: bash -c "ip route && sleep 10"
    networks:
      intra:
        ipv4_address: 172.10.0.11
networks:
  intra:
    driver: bridge
    ipam:
      config:
      - subnet: 172.10.0.0/24

但是,正确的方法是使用healthcheck(> = 2.1)。

答案 13 :(得分:0)

尝试了许多不同的方法,但是喜欢这种方法的简单性:https://github.com/ufoscout/docker-compose-wait

您可以在docker compose文件中使用ENV vars来提交服务主机(带有端口)列表的想法,应该像这样WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017。“

因此,假设您有以下docker-compose.yml文件(从仓库README复制/粘贴):

version: "3"

services:

  mongo:
    image: mongo:3.4
    hostname: mongo
    ports:
      - "27017:27017"

  postgres:
    image: "postgres:9.4"
    hostname: postgres
    ports:
      - "5432:5432"

  mysql:
    image: "mysql:5.7"
    hostname: mysql
    ports:
      - "3306:3306"

  mySuperApp:
    image: "mySuperApp:latest"
    hostname: mySuperApp
    environment:
      WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017

接下来,为了等待服务,您需要在Dockerfiles中添加以下两行(在应等待其他服务启动的服务的Dockerfile中):

ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.0/wait /wait
RUN chmod +x /wait

此类示例Dockerfile的完整示例(同样来自项目仓库README):

FROM alpine

## Add your application to the docker image
ADD MySuperApp.sh /MySuperApp.sh

## Add the wait script to the image
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.0/wait /wait
RUN chmod +x /wait

## Launch the wait tool and then your application
CMD /wait && /MySuperApp.sh

有关可能用法的其他详细信息,请参见README

答案 14 :(得分:0)

不建议用于严重的部署,但这实际上是一个“ wait x seconds”命令。

使用docker-compose3.4start_period instruction has been added to healthcheck。这意味着我们可以执行以下操作:

docker-compose.yml

version: "3.4"
services:
  # your server docker container
  zmq_server:
    build:
      context: ./server_router_router
      dockerfile: Dockerfile

  # container that has to wait
  zmq_client:
    build:
      context: ./client_dealer/
      dockerfile: Dockerfile
    depends_on:
      - zmq_server
    healthcheck:
      test: "sh status.sh"
      start_period: 5s

status.sh

#!/bin/sh

exit 0

这里发生的是healthcheck在5秒钟后被调用。这将调用status.sh脚本,该脚本始终返回“没问题”。 我们只是让zmq_client容器在开始前等待5秒钟!

注意:拥有version: "3.4"很重要。如果.4不存在,则docker-compose抱怨。

答案 15 :(得分:0)

在Docker Compose文件的第3版中,您可以使用RESTART

例如:

docker-compose.yml

std::vector<std::pair<const C, int>> values {
    std::make_pair(C{}, 0)
};
std::unordered_map<C, int, Hash> map(values.cbegin(), values.cend());

请注意,我使用depends_on而不是links,因为后者在版本3中已弃用。

尽管它可以工作,但它并不是理想的解决方案,因为每次发生故障时都要重新启动Docker容器。

也请看RESTART_POLICY。它可以让您调整重启策略。

答案 16 :(得分:0)

我只有2个撰写文件,然后第一个和第二个开始。我的脚本如下所示:

#!/bin/bash
#before i build my docker files
#when done i start my build docker-compose
docker-compose -f docker-compose.build.yaml up
#now i start other docker-compose which needs the image of the first
docker-compose -f docker-compose.prod.yml up

答案 17 :(得分:0)

我目前还具有在启动其他服务之前等待某些服务启动并运行的要求。另外,请在这里和其他地方阅读建议。但是它们中的大多数要求docker-compose.yml的一些方法必须稍作更改。 因此,我开始研究一个解决方案,我认为它是围绕docker-compose本身的业务流程层,最后我想到了一个名为docker-compose-profile的shell脚本。 即使服务没有直接向主机公开任何端口,它也可以等待与特定容器的tcp连接。我使用的技巧是在堆栈中启动另一个docker容器,然后从那里我可以(通常)连接到每个服务(只要不应用其他网络配置)。 还有一种等待方法,当心某些日志消息。 可以将服务分组在一起以在一个步骤中启动,然后触发另一步骤来启动。 您也可以排除某些服务而无需列出所有其他要启动的服务(例如,可用服务的集合减去某些排除的服务)。 可以将这种配置捆绑到配置文件中。 有一个名为dcp.yml的Yaml配置文件(暂时),该文件必须放在docker-compose.yml文件旁边。

对于您的问题,它看起来像:

command:
  aliases:
    upd:
      command: "up -d"
      description: |
        Create and start container. Detach afterword.

profiles:
  default:
    description: |
      Wait for rabbitmq before starting worker.
    command: upd
    steps:
      - label: only-rabbitmq
        only: [ rabbitmq ]
        wait:
          - 5@tcp://rabbitmq:5432
      - label: all-others

您现在可以通过调用来启动堆栈

dcp -p default upd

甚至只是

dcp

因为只有默认配置文件才能运行up -d

有一个小问题。我当前的版本不(还)支持像ony这样的特殊等待条件 您实际需要的。因此,没有测试可以向兔子发送消息。

我已经在考虑一种进一步的等待方法,以便在主机上或作为Docker容器运行某个命令。 比我们可以通过类似的方式扩展该工具

...
        wait:
          - service: rabbitmq
            method: container
            timeout: 5
            image: python-test-rabbit
...

有一个名为python-test-rabbit的泊坞窗映像来进行检查。

这将带来的好处是,不再需要不需要将等待的部分带给您的工人。 将被隔离并保留在业务流程层中。

可能有人觉得这有用。任何建议都非常欢迎。

您可以在https://gitlab.com/michapoe/docker-compose-profile

找到该工具