Docker Compose дождитесь контейнера X перед запуском Y



Я использую rabbitmq и простой пример python из здесь
вместе с Докером-сочинять. Моя проблема заключается в том, что мне нужно дождаться полного запуска rabbitmq. Из того, что я искал до сих пор, я не знаю, как ждать с контейнером x ( в моем случае worker), пока не будет запущен y (rabbitmq).



Я нашел это blogpost, где он проверяет, если другой узел онлайн.
Я также нашел это команду docker:




ждать



использование: докер ждать контейнер [контейнер...]



блокируйте контейнер до тех пор, пока он не остановится, а затем распечатайте его код выхода.




ожидание остановки контейнера, возможно, не то, что я ищу, но если
возможно ли использовать эту команду внутри docker-compose.в формате YML ?
Мое решение до сих пор состоит в том, чтобы подождать несколько секунд и проверить порт, но это способ достичь этого?. Если я не буду ждать, я получу ошибка.



docker-compose.в формате YML



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

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


python привет образец (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:



сценарий оболочки или ожидание внутри вашей программы, возможно, является возможным решением. Но увидев это вопрос Я ищу команду или функцию docker/docker-compose себя.



они упоминают решение для реализации проверки состояния здоровья, которое может быть лучшим вариантом. Открытое tcp-соединение не означает, что ваша служба готова или может оставаться готовой. В дополнение к этому мне нужно изменить мою точку входа в моем dockerfile.



поэтому я надеюсь на ответ с помощью команд docker-compose на борту, которые, надеюсь, будут иметь место, если они закончат эту проблему.



Обновление Марта 2016



есть предложение для обеспечения встроенного способа определения того, является ли контейнер "живым". Так что docker-compose может использовать его в ближайшем будущем.



Обновление Июня 2016



похоже, что проверка здоровья будет встроенный в настройки в версии 1.12.0



Обновление Januar 2017



Я нашел решение docker-compose см.:
Docker Compose дождитесь контейнера X перед запуском Y

832   10  

10 ответов:

наконец-то найдено решение с помощью метода docker-compose. Поскольку docker-compose File format 2.1 вы можете определить healthchecks.

Я сделал это в пример проекта вам нужно установить хотя бы докер 1.12.0+. Мне тоже нужно было расширить RabbitMQ-management Dockerfile, потому что curl не установлен на официальном образе.

теперь я проверяю, доступна ли страница управления RabbitMQ-контейнером. Если завиток заканчивается 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 к перезапуску при неудаче. Теперь мой контейнер приложения перезапустится 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

изначально это пока невозможно. Смотрите также это запрос.

до сих пор вам нужно сделать это в ваших контейнерах CMD ждать, пока все необходимые услуги.

на Dockerfiles CMD вы можете обратиться к своему собственному сценарию запуска, который обертывает запуск службы контейнеров. Прежде чем начать его, вы ждете зависимости один например:

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

вероятно, вам нужно установить netcat в вашем Dockerfile как хорошо. Я не знаю, что предварительно установлено на образе python.

есть несколько инструментов, которые обеспечивают простую в использовании логику ожидания, для простых проверок портов tcp:

для более сложных ожидания:

используя restart: unless-stopped или restart: always может решить эту проблему.

Если работник container останавливается, когда rabbitMQ не готов, он будет перезапущен, пока он не будет готов.

совсем недавно они добавили depends_on характеристика.

Edit:

начиная с версии compose 2.1+ вы можете использовать depends_on в сочетании с healthcheck для достижения этого:

документы:

version: '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"

до версии 2.1

вы все еще можете использовать depends_on, но это только эффекты ордер в каких службах запускаются-нет, если они готовы раньше запускается зависимая служба.

кажется, требуется по крайней мере версия 1.6.0.

использование будет выглядеть так:

version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres 

документы:

выраженная зависимость между службами, которая имеет два эффекта:

  • docker-compose up запустит службы в порядке зависимости. В следующем примере db и redis будут запущены до web.
  • докер-составить сервис будет автоматически включать зависимости сервиса. В следующем примере docker-compose up web также создаст и запустит db и redis.

Примечание: как я понимаю, хотя это устанавливает порядок, в котором загружаются контейнеры. Это не гарантирует, что служба внутри контейнера действительно загрузилась.

например, вы postgres контейнер может быть. Но сама служба postgres все еще может быть инициализация в контейнере.

вы также можете просто добавить его в команду, например.

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

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

ждать на порт, вы также можете использовать что-то вроде этого

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

чтобы увеличить время ожидания вы можете взломать немного подробнее:

command: bash -c "for i in {1..100} ; do if ! curl -s rabbitmq:5672 > /dev/null ; then echo waiting on rabbitmq for $i seconds; sleep $i; fi; done; start.sh"

вы также можете решить эту проблему, установив конечную точку, которая ждет службы, чтобы быть с помощью netcat (с помощью докер-ждать сценарий). Мне нравится этот подход, так как у вас все еще есть чистый в своем 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=
postgres_port=
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

это в настоящее время задокументировано в официальном докер документации.

PS: вы следует установить netcat в вашем экземпляре docker, если это недоступно. Для этого добавьте это в ваш Docker file:

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

есть готовая к использованию утилита под названием"докер-ждать " это может быть использовано для ожидания.

для контейнера начните приказывать пользу

depends_on:

для ожидания предыдущего запуска контейнера используйте скрипт

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

эта статья поможет вам https://docs.docker.com/compose/startup-order/

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"

основываясь на этом сообщении в блоге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 =>:

docker-compose up start_dependencies

rabbitmq сервис запустится в режиме демона,start_dependencies закончит работу.

    Ничего не найдено.

Добавить ответ:
Отменить.