Docker Compose Warten Sie auf Container X, bevor Sie Y starten

323

Ich verwende Rabbitmq und eine einfache Python-Probe von hier zusammen mit Docker-Compose. Mein Problem ist, dass ich warten muss, bis rabbitmq vollständig gestartet ist. Nach dem, was ich bisher gesucht habe, weiß ich nicht, wie ich mit Container x (in meinem Fallbearbeiter) warten soll, bis y (rabbitmq) gestartet wird.

Ich habe diesen Blogpost gefunden, in dem er überprüft, ob der andere Host online ist. Ich habe auch diesen Docker-Befehl gefunden :

warten

Verwendung: Docker warten CONTAINER [CONTAINER ...]

Blockieren Sie, bis ein Container stoppt, und drucken Sie dann seinen Exit-Code.

Das Warten auf das Stoppen eines Containers ist vielleicht nicht das, wonach ich suche, aber wenn ja, ist es möglich, diesen Befehl in der Datei docker-compose.yml zu verwenden? Meine bisherige Lösung besteht darin, einige Sekunden zu warten und den Port zu überprüfen. Ist dies jedoch der Weg, um dies zu erreichen? Wenn ich nicht warte, erhalte ich eine Fehlermeldung.

docker-compose.yml

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

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

Python Hallo Probe (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 für Arbeiter:

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

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

Update November 2015 :

Ein Shell-Skript oder das Warten in Ihrem Programm ist möglicherweise eine mögliche Lösung. Aber nachdem ich dieses Problem gesehen habe, suche ich nach einem Befehl oder einer Funktion von Docker / Docker-Compose selbst.

Sie erwähnen eine Lösung für die Durchführung eines Gesundheitschecks, die möglicherweise die beste Option ist. Eine offene TCP-Verbindung bedeutet nicht, dass Ihr Dienst bereit ist oder möglicherweise bereit bleibt. Außerdem muss ich meinen Einstiegspunkt in meiner Docker-Datei ändern.

Ich hoffe also auf eine Antwort mit Docker-Compose-On-Board-Befehlen, die hoffentlich der Fall sein wird, wenn sie dieses Problem lösen.

Update März 2016

Es gibt einen Vorschlag für die Bereitstellung einer integrierten Methode, um festzustellen, ob ein Container "lebt". Docker-Compose kann es also möglicherweise in naher Zukunft nutzen.

Update Juni 2016

Es scheint , dass der Gesundheitscheck wird integriert in Version 1.12.0 in Docker

Update Januar 2017

Ich habe eine Docker-Compose-Lösung gefunden, siehe: Docker Compose Warten Sie auf Container X, bevor Sie Y starten

Svenhornberg
quelle
2
Die Verwendung von Healthchecks in wurde in Docker-Compose 2.3 nicht mehr empfohlen, um die Fehlertoleranz verteilter Systeme zu fördern. Siehe: docs.docker.com/compose/startup-order
Kmaid

Antworten:

281

Endlich eine Lösung mit einer Docker-Compose-Methode gefunden. Seit Docker-Compose-Dateiformat 2.1 können Sie Healthchecks definieren .

Ich habe es in einem Beispielprojekt gemacht, für das Sie mindestens Docker 1.12.0+ installieren müssen. Ich musste auch die Docker-Datei für das Rabbitmq-Management erweitern , da Curl nicht auf dem offiziellen Image installiert ist.

Jetzt teste ich, ob die Management-Seite des rabbitmq-Containers verfügbar ist. Wenn Curl mit Exitcode 0 endet, wird die Container-App (Python Pika) gestartet und eine Nachricht in der Hallo-Warteschlange veröffentlicht. Es funktioniert jetzt (Ausgabe).

Docker-Compose (Version 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

Ausgabe:

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

Version 3 unterstützt die Bedingungsform abhängige_on nicht mehr . Also bin ich von abhängigen_on umgezogen, um bei einem Fehler neu zu starten. Jetzt wird mein App-Container 2-3 Mal neu gestartet, bis er funktioniert, aber es handelt sich immer noch um eine Docker-Compose-Funktion, ohne den Einstiegspunkt zu überschreiben.

Docker-Compose (Version 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
Svenhornberg
quelle
6
@svenhornberg pingverwendet ICMP und unterstützt daher keine TCP-Ports. Vielleicht ncum einen TCP-Port zu testen. Wahrscheinlich besser, psql -h localhost -p 5432etwas zu verwenden und abzufragen.
Matt
36
"hängt davon ab" wurde in Version 3 docs.docker.com/compose/compose-file/#dependson
nha
48
@nha Es sieht so aus, als ob die conditionForm von depends_onentfernt wurde, aber es depends_ongibt sie immer noch in v3
akivajgordon
14
Wie können Healthchecks weiterhin verwendet werden, um die Startreihenfolge zu steuern, wenn depends_onwith conditionentfernt wurde?
Franz
41
Kaum zu glauben, dass dies immer noch so ein Schmerz ist
npr
71

Nativ ist das noch nicht möglich. Siehe auch diese Funktionsanforderung .

Bisher müssen Sie dies in Ihren Containern tun, um CMDzu warten, bis alle erforderlichen Dienste vorhanden sind.

In Dockerfiles können CMDSie auf Ihr eigenes Startskript verweisen, das den Start Ihres Containerservices abschließt. Bevor Sie es starten, warten Sie auf eine abhängige wie:

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

Wahrscheinlich müssen Sie netcat auch in Ihrem installieren Dockerfile. Ich weiß nicht, was auf dem Python-Image vorinstalliert ist.

Es gibt einige Tools, die eine benutzerfreundliche Wartelogik für einfache TCP-Port-Überprüfungen bieten:

Für komplexere Wartezeiten:

0x7d7b
quelle
Können Sie erklären, was Sie unter CMD verstehen? Bedeutet das, dass mein Programm es tun muss, wie ich es mit einer Portprüfung getan habe? Oder meinst du dafür eine bestimmte CMD von zB Linux?
Svenhornberg
Vielen Dank für die Erklärung, ich stimme Ihrer Antwort zu. Aber ich denke, die bevorstehende Feature-Anfrage wäre die richtige Antwort auf meine Frage, also lasse ich sie bisher unbeantwortet.
Svenhornberg
44

Verwenden restart: unless-stoppedoder restart: alwayskann dieses Problem lösen.

Wenn der Worker containerstoppt, wenn rabbitMQ nicht bereit ist, wird er neu gestartet, bis er fertig ist.

Toilette
quelle
3
Ich mag diese Lösung für diesen Fall, aber sie funktioniert nicht für Container, die nicht beendet werden, wenn einer der ausgeführten Unterprozesse fehlschlägt. Beispielsweise würde ein Tomcat-Container auch dann weiter ausgeführt, wenn ein von ihm ausgeführtes Java-Servlet keine Verbindung zu einem Datenbankserver herstellen würde. Zugegeben, Docker-Container machen Servlet-Container wie Tomcat größtenteils unnötig.
Derek Mahar
@DerekMahar, wenn Sie eine Java-basierte Webanwendung haben, die nur REST-Aufrufe unterstützt, was verwenden Sie anstelle von Jetty / Tomcat?
JoeG
2
@ JoeG, ich meinte Tomcat den Servlet-Container, der viele Anwendungen hosten kann, nicht eingebettetes Tomcat. Docker macht Ersteres größtenteils unnötig, während Letzteres beispielsweise für Microservices populärer wird.
Derek Mahar
35

Vor kurzem haben sie die depends_onFunktion hinzugefügt .

Bearbeiten:

Ab Compose Version 2.1+ können Sie dies depends_onin Verbindung mit verwenden healthcheck, um dies zu erreichen:

Aus den Dokumenten :

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"

Vor Version 2.1

Sie können weiterhin verwenden depends_on, dies wirkt sich jedoch nur auf die Reihenfolge aus, in der die Dienste gestartet werden - nicht, wenn sie vor dem Start des abhängigen Dienstes bereit sind.

Es scheint mindestens Version 1.6.0 zu erfordern.

Die Verwendung würde ungefähr so ​​aussehen:

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

Aus den Dokumenten:

Expressabhängigkeit zwischen Diensten, die zwei Auswirkungen hat:

  • Docker-Compose Up startet Dienste in Abhängigkeitsreihenfolge. Im folgenden Beispiel werden db und redis vor dem Web gestartet.
  • Docker-Compose-up-SERVICE enthält automatisch die Abhängigkeiten von SERVICE. Im folgenden Beispiel erstellt und startet Docker-Compose-Up-Web auch DB und Redis.

Hinweis: Soweit ich weiß, wird hierdurch die Reihenfolge festgelegt, in der Container geladen werden. Es kann nicht garantiert werden, dass der Dienst im Container tatsächlich geladen wurde.

Beispielsweise ist Ihr Postgres- Container möglicherweise aktiv. Möglicherweise wird der Postgres-Dienst selbst noch im Container initialisiert.

toast38coza
quelle
10
dnephin hat geschrieben: abhängige_on bestellt nur. Um das Starten eines anderen Containers tatsächlich zu verzögern, müsste es eine Möglichkeit geben, zu erkennen, wann ein Prozess die Initialisierung abgeschlossen hat.
Svenhornberg
15
"Version 3 unterstützt die Bedingungsform von nicht mehr depends_on." docs.docker.com/compose/compose-file/#dependson
akauppi
depends_onwartet nicht, bis sich der Container im readyStatus befindet (was auch immer das in Ihrem Fall bedeuten kann). Es wird nur gewartet, bis sich der Container im Status "Ausführen" befindet.
Htyagi
19

Sie können es auch einfach zur Befehlsoption hinzufügen, z.

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

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

Um auf einen Port zu warten, können Sie auch so etwas verwenden

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

Um die Wartezeit zu verlängern, können Sie ein bisschen mehr hacken:

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"
AmanicA
quelle
13

restart: on-failure habe den Trick für mich gemacht ... siehe unten

---
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"
Edwin Ikechukwu Okonkwo
quelle
12

Für Containerbestellung verwenden

depends_on:

Verwenden Sie zum Warten auf den vorherigen Container-Start das Skript

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

Dieser Artikel hilft Ihnen https://docs.docker.com/compose/startup-order/

Verlassen
quelle
5
@svenhornberg im Kommentar, den Sie verlinken, gibt es keine Erklärung für die Funktion wait-for-it.sh.
Beenden Sie den
7

Sie können dieses Problem auch lösen, indem Sie mithilfe von netcat (mithilfe des Docker-Wait- Skripts) einen Endpunkt festlegen, der darauf wartet, dass der Dienst aktiv ist . Ich mag diesen Ansatz, da Sie immer noch einen sauberen commandAbschnitt in Ihrem haben docker-compose.ymlund Ihrer Anwendung keinen Docker-spezifischen Code hinzufügen müssen:

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

Dann ist dein 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

Dies ist heutzutage in der offiziellen Docker-Dokumentation dokumentiert .

PS: Sie sollten netcatin Ihrer Docker-Instanz installieren, wenn dies nicht verfügbar ist. Fügen Sie dazu Folgendes zu Ihrer DockerDatei hinzu:

RUN apt-get update && apt-get install netcat-openbsd -y 
maerteijn
quelle
4

Es gibt ein gebrauchsfertiges Dienstprogramm namens " Docker-Wait ", das zum Warten verwendet werden kann.

Adrian Mitev
quelle
1
Vielen Dank, aber es ist nur ein Shell-Skript, also ist es wie eine h3nrik-Antwort oder das Warten in Python. Es ist keine Funktion von Docker-Compose. Mögen Sie einen Blick auf github.com/docker/compose/issues/374 werfen. Sie planen, einen Healthcheck durchzuführen, der der beste Weg wäre. Eine offene TCP-Verbindung bedeutet nicht, dass Ihr Dienst bereit ist oder möglicherweise bereit bleibt. Außerdem muss ich meinen Einstiegspunkt in meiner Docker-Datei ändern.
Svenhornberg
3

Versuchte viele verschiedene Möglichkeiten, mochte aber die Einfachheit: https://github.com/ufoscout/docker-compose-wait

Die Idee, dass Sie ENV-Variablen in der Docker-Erstellungsdatei verwenden können, um eine Liste von Diensthosts (mit Ports) zu senden, auf die wie folgt "gewartet" werden sollte : WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017.

Nehmen wir also an, Sie haben die folgende Datei docker-compose.yml (Kopie / Vergangenheit von Repo 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

Damit die Dienste warten können, müssen Sie Ihren Docker-Dateien die folgenden zwei Zeilen hinzufügen (in die Docker-Datei der Dienste, die auf den Start anderer Dienste warten sollen):

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

Das vollständige Beispiel einer solchen Beispiel-Docker-Datei (wieder aus dem Projekt-Repo 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

Weitere Einzelheiten zur möglichen Verwendung finden Sie unter README

Evereq
quelle
Ich suchte nach einer ähnlichen Antwort. Ich habe normalerweise mit hub.docker.com/r/dadarek/wait-for-dependencies gearbeitet, da Netcat darunter verwendet wird. Die von Ihnen bereitgestellte ist Rust-basiert. Ich kann Ihre Qualität nicht kommentieren, aber für mich ist keine zusätzliche Schicht ein definitiver Profi.
Filip Malczak
1
Ich empfehle aus Sicherheitsgründen dringend davon ab. Sie führen eine beliebige ausführbare Datei über einen Hyperlink aus. Eine bessere Lösung wäre, dasselbe mit einem statischen Skript zu tun, das mit COPY
Paul K
@PaulK Natürlich ist es verständlich, dass das Ausführen von Hyperlinks nicht sicher ist, aber es ist nur eine Demo darüber, wie die https://github.com/ufoscout/docker-compose-waitBibliothek funktioniert :) Die Art und Weise, wie Sie diese Bibliothek verwenden, ändert nichts an der Antwort, dass Sie eine Bibliothek verwenden können. Sicherheit ist ein komplexes Thema, und wenn wir weit gehen, sollten wir überprüfen, was diese Bibliothek ohnehin tut, auch wenn wir sie KOPIEREN :) Um es genauer zu sagen: "Ich empfehle dringend, diese Bibliothek nicht zu verwenden." vom Hyperlink ". Hoffe du stimmst zu, danke für einen Hinweis!
Evereq
2

basierend auf diesem Blog-Beitrag https://8thlight.com/blog/dariusz-pasciak/2016/10/17/docker-compose-wait-for-dependencies.html

Ich habe meine docker-compose.ymlwie unten gezeigt konfiguriert :

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: {}

Dann mache ich für run =>:

docker-compose up start_dependencies

rabbitmqDer Dienst wird im Daemon-Modus gestartet und start_dependenciesdie Arbeit beendet.

Igor Komar
quelle
lol, machen Sie eine Abfrage, über die Sie "curl", "-f", "http://localhost:15672"das managementPlugin installieren müssen, und verwenden Sie den bereits veralteten Healthcheck - die beste Antwort. Einfaches Arbeitsbeispiel mit Check via ncits - downvote. ha, ok ...
Igor Komar
Die Antwort verwendet keine native Docker-Funktion. Sie ist irrelevant, wenn Sie Curl, NC oder andere Tools verwenden. während! nc ist dasselbe wie bereits in anderen Antworten gepostet.
Svenhornberg
1
@IgorKomar, danke Mann, du hast meinen Tag gerettet! : 3 Ich habe fast dieselbe Mechanik verwendet, um zu überprüfen, ob der MySQL-Server bereit ist, bevor die eigentliche Anwendung gestartet wird. ;) Ich docker-compose run --name app-test --rm "app" bash -l -c 'echo Waiting for mysql service start... && while ! nc -z db-server 3306; do sleep 1; done && echo Connected! && /bin/bash /script/ci_tests.sh'
gebe einen
1

In Version 3 einer Docker Compose-Datei können Sie RESTART verwenden .

Zum Beispiel:

docker-compose.yml

worker:
    build: myapp/.
    volumes:
    - myapp/.:/usr/src/app:ro
    restart: on-failure
    depends_on:
    - rabbitmq
rabbitmq:
    image: rabbitmq:3-management

Beachten Sie, dass ich abhängige_on anstelle von Links verwendet habe, da letztere in Version 3 veraltet sind.

Obwohl es funktioniert, ist es möglicherweise nicht die ideale Lösung, da Sie den Docker-Container bei jedem Fehler neu starten.

Schauen Sie sich auch RESTART_POLICY an. Damit können Sie die Neustartrichtlinie optimieren.

Wenn Sie Compose in der Produktion verwenden, empfiehlt es sich, die Neustartrichtlinie zu verwenden:

Angeben einer Neustartrichtlinie wie Neustart: Immer um Ausfallzeiten zu vermeiden

Mathieu Gemard
quelle
0

Eine der alternativen Lösungen ist die Verwendung einer Container-Orchestrierungslösung wie Kubernetes. Kubernetes unterstützt Init-Container, die vollständig ausgeführt werden, bevor andere Container gestartet werden können. Hier finden Sie ein Beispiel für den Linux-Container SQL Server 2017, in dem der API-Container den Init-Container zum Initialisieren einer Datenbank verwendet

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

Nilesh Gule
quelle
0

Hier ist das Beispiel, in dem der mainContainer wartet, workerwenn er auf Pings reagiert:

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

Der richtige Weg ist jedoch die Verwendung von healthcheck(> = 2.1).

Kenorb
quelle
0

Nicht für ernsthafte Bereitstellungen empfohlen, aber hier ist im Wesentlichen ein Befehl "Warten x Sekunden".

Mit der docker-composeVersion wurde 3.4eine start_periodAnweisung hinzugefügthealthcheck . Dies bedeutet, dass wir Folgendes tun können:

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

Was hier passiert ist, dass das healthchecknach 5 Sekunden aufgerufen wird. Dies ruft das status.shSkript auf, das immer "Kein Problem" zurückgibt. Wir haben gerade den zmq_clientContainer 5 Sekunden warten lassen, bevor wir anfangen!

Hinweis: Es ist wichtig, dass Sie haben version: "3.4". Wenn das .4nicht da ist, beschwert sich Docker-Compose.

NumesSanguis
quelle
1
Als naive "Wait 5s" -Lösung ist diese ziemlich genial. Ich würde upvoten, aber ich werde nicht, weil dies nicht wirklich mit prod-ähnlichen Setups funktioniert und ich befürchte, dass jemand die Anzahl der Stimmen prüfen würde, anstatt sorgfältig zu lesen. Trotzdem wollte ich sagen "Mann, das ist klug";)
Filip Malczak
PS. Für kompliziertere Lösungen siehe die Antwort des Evereq
Filip Malczak
Das ist nicht was start_period. Diese Konfiguration bedeutet, dass es eine Nachfrist gibt, in der fehlgeschlagene Integritätsprüfungen nicht als Wiederholungsversuche gelten. Wenn es früh gelingt, gilt es als gesund. Nach der Startperiode zählt ein Fehler als erneuter Versuch. Siehe docs.docker.com/engine/reference/builder/#healthcheck
Capi Etheriel
-4

Ich habe nur 2 Compose-Dateien und beginne eine erste und eine zweite später. Mein Skript sieht so aus:

#!/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
Benjamin Grašič
quelle
Dies wird nicht als gute Praxis angesehen. Sie können dann die Lösung, die aus mehreren Conatinern besteht, nicht aus einer Compose-Datei liefern.
Juergi