Compose: Führen Sie nach dem Ausführen einen Befehl aus

Erstellt am 5. Aug. 2015  ·  131Kommentare  ·  Quelle: docker/compose

Hallo,

Es ist sehr hilfreich, so etwas wie "onrun" in der YAML zu haben, um Befehle nach dem Ausführen ausführen zu können. Ähnlich wie bei https://github.com/docker/docker/issues/8860

mongodb:
    image: mongo:3.0.2
    hostname: myhostname
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 
    onrun:
        - mongodump --host db2dump.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

Nach dem Start von mongodb wird db2dump.domain.lan ausgegeben und wiederhergestellt.

Wenn ich den Container stoppe und dann starte, wird kein laufender Teil ausgeführt, um die Idempotenz zu bewahren.

EDIT 15. Juni 2020

5 Jahre später will Compose die Spezifikationen nicht "standardisieren".
Bitte überprüfen Sie https://github.com/compose-spec/compose-spec/issues/84

Hilfreichster Kommentar

Um mein Docker zu verwalten, schlagen Sie mir vor, ein Skript oder ein Makefile zu verwenden. Warum wurde Compose erstellt?
? Wir können Container mit Skript || verwalten, skalieren usw. Docker-Datei?

Ok, ich nehme dieses Beispiel, es ist das, was ich verwendet habe, um meine Anwendungstestumgebung im CI-Prozess bereitzustellen.

rabbitmq:
    image: rabbitmq:3.5.1-management
    environment:
        RABBITMQ_NODENAME: rabbit
    hostname: rabbitmq
    domainname: domain.lan
    volumes:
        - /data/rabbitmq/db:/var/lib/rabbitmq
    ports:
        - "5672:5672" 
        - "15672:15672"
        - "25672:25672"
        - "4369:4369"

mongodb:
    image: mongo:3.0.2
    hostname: mongo
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 

appmaster:
    image: appmaster
    hostname: master
    domainname: domain.lan
    environment:
        ...
    ports:
        - "80:80" 
        - "8080:8080"
    links:
        - mongodb
        - rabbitmq

celery:
    image: celery
    hostname: celery
    domainname: domain.lan
    environment:
        ...
    links:
        - rabbitmq

Nach dem Start des Containers muss ich mongodb bereitstellen, die Warteschlange und das Konto in rabbitmq verwalten

Was ich heute mache, ist ein Skript mit:

#!/bin/bash
PROJECT=appmaster
docker-compose -f appmaster.yml -p appmaster up -d
docker exec appmaster_rabbitmq_1 rabbitmqctl add_user user password
docker exec appmaster_rabbitmq_1 rabbitmqctl add_vhost rabbitmq.domain.lan
docker exec appmaster_rabbitmq_1 rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"
docker exec appmaster_mongodb_1 mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
docker exec appmaster_mongodb_1 mongorestore -d database /data/mongodb/dumps/latest/database

Mit onrun Anweisungen kann ich direkt docker-compose -f appmaster.yml -p appmaster up -d
und die yml-Datei wird lesbarer

rabbitmq:
    ...
    onrun:
        - rabbitmqctl add_user user password
        - rabbitmqctl add_vhost rabbitmq.domain.lan
        - rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"

mongodb:
    ...
    onrun:
        - mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

Alle 131 Kommentare

Ich denke, das sollten Schritte in der Docker-Datei sein

FROM mongo:3.0.2
ADD data/mongodb/dumps/latest /data/mongodb/dumps/latest
RUN mongorestore -d database /data/mongodb/dumps/latest/database

Auf diese Weise wird es auch beim Neuerstellen zwischengespeichert.

Danke @dnephin.
Natürlich kann ich ein Dockerfile erstellen und es in Build anstelle von Images verwenden, oder ich kann Docker Exec verwenden.
MongoDB ist nur ein Beispiel. Sie können dieses Beispiel mit MySQL und Kontoerstellung oder mit Rabbitmq und Warteschlangenerstellung usw. haben.

onrun ermöglicht Flexibilität beim Verfassen von Orchestrierungen, beim Verfassen liest die Onrun-Liste und macht docker exec für jedes Element.

Der Punkt ist, dass das Setzen von Befehlen auf docker exec in docker-compose.yml nicht erforderlich ist, wenn Sie dies entweder in der Docker-Datei oder im Startskript des Containers tun können. Beides macht Ihren Container auch nützlicher, wenn _not_ wird mit Compose ausgeführt.

Alternativ können Sie Ihre App mit einem Shell-Skript oder Makefile starten, das die entsprechenden Befehle docker und docker-compose ausführt.

Die Funktionalität ist es nicht wert, zu Compose hinzugefügt zu werden, es sei denn, sie würde einen erheblichen Mehrwert gegenüber einer dieser Funktionen bieten, und ich denke nicht, dass dies für die von Ihnen genannten Anwendungsfälle der Fall wäre.

Um mein Docker zu verwalten, schlagen Sie mir vor, ein Skript oder ein Makefile zu verwenden. Warum wurde Compose erstellt?
? Wir können Container mit Skript || verwalten, skalieren usw. Docker-Datei?

Ok, ich nehme dieses Beispiel, es ist das, was ich verwendet habe, um meine Anwendungstestumgebung im CI-Prozess bereitzustellen.

rabbitmq:
    image: rabbitmq:3.5.1-management
    environment:
        RABBITMQ_NODENAME: rabbit
    hostname: rabbitmq
    domainname: domain.lan
    volumes:
        - /data/rabbitmq/db:/var/lib/rabbitmq
    ports:
        - "5672:5672" 
        - "15672:15672"
        - "25672:25672"
        - "4369:4369"

mongodb:
    image: mongo:3.0.2
    hostname: mongo
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 

appmaster:
    image: appmaster
    hostname: master
    domainname: domain.lan
    environment:
        ...
    ports:
        - "80:80" 
        - "8080:8080"
    links:
        - mongodb
        - rabbitmq

celery:
    image: celery
    hostname: celery
    domainname: domain.lan
    environment:
        ...
    links:
        - rabbitmq

Nach dem Start des Containers muss ich mongodb bereitstellen, die Warteschlange und das Konto in rabbitmq verwalten

Was ich heute mache, ist ein Skript mit:

#!/bin/bash
PROJECT=appmaster
docker-compose -f appmaster.yml -p appmaster up -d
docker exec appmaster_rabbitmq_1 rabbitmqctl add_user user password
docker exec appmaster_rabbitmq_1 rabbitmqctl add_vhost rabbitmq.domain.lan
docker exec appmaster_rabbitmq_1 rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"
docker exec appmaster_mongodb_1 mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
docker exec appmaster_mongodb_1 mongorestore -d database /data/mongodb/dumps/latest/database

Mit onrun Anweisungen kann ich direkt docker-compose -f appmaster.yml -p appmaster up -d
und die yml-Datei wird lesbarer

rabbitmq:
    ...
    onrun:
        - rabbitmqctl add_user user password
        - rabbitmqctl add_vhost rabbitmq.domain.lan
        - rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"

mongodb:
    ...
    onrun:
        - mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

Dies wäre ziemlich nützlich und löst einen Anwendungsfall.

: +1:

Dadurch wird die Verwendung von docker-compose für Gated-Tests als Teil einer CD-Pipeline praktikabler

: +1:

Dies ist ein Duplikat von # 877, # 1341, # 468 (und einigen anderen).

Ich denke, der richtige Weg, dies zu unterstützen, ist # 1510 und ermöglicht externen Tools, Operationen auszuführen, wenn Sie das gewünschte Ereignis treffen.

Schließen als Duplikat

Das wäre sehr nützlich. Ich verstehe das Argument "Oh, du könntest das mit einem Bash-Skript machen" nicht. Natürlich könnten wir es mit einem Bash-Skript machen. Ich könnte auch alles, was Docker-compose macht, mit einem Bash-Skript machen. Der Punkt ist jedoch, dass es eine einzige YAML-Datei gibt, die Ihre Testumgebung steuert und mit einem einfachen Befehl docker-compose up hochgefahren werden kann.

Es ist nicht die Aufgabe von Compose, alles zu tun, was mit einem Shell-Skript oder Makefile möglich ist - wir müssen irgendwo eine Linie ziehen, um ein Gleichgewicht zwischen Nützlichkeit und Vermeidung von Aufblähen zu finden.

Darüber hinaus ist eine wichtige Eigenschaft der Compose-Datei, dass sie auf allen Computern ziemlich portabel ist - sogar auf Mac-, Linux- und Windows-Computern. Wenn wir es Benutzern ermöglichen, beliebige Shell-Befehle in die Compose-Datei einzufügen, werden sie viel weniger portabel.

@aanand Um fair zu sein, bedeutet die Ausführung eines docker exec nicht automatisch eine Inkompatibilität mit x-plat.

Entschuldigung - Ich habe dieses Problem falsch verstanden, weil es darum geht, Befehle auf dem Host-Computer auszuführen. Trotzdem steht mein erster Punkt.

Ich verstehe deinen Standpunkt @aanand. Es scheint mir nicht unangebracht zu sein, da bereits docker-compose viele der gleichen Dinge tut, die die reguläre docker Engine bereits tut, wie command , expose , ports , build usw. Das Hinzufügen der exec -Funktionalität würde docker-compose mehr Leistung verleihen und es zu einem echten One-Stop-Shop für Einstellungen machen up dev Umgebungen.

@aanund das Hauptproblem für viele Entwickler und CI-Pipelines besteht darin, Daten zu haben, die sehr nahe an der Produktionsumgebung liegen. Wie ein Dump aus einer DB. Ich erstelle dieses Ticket vor 1 Jahr und nichts bewegt sich im Docker komponieren.

Sie schlagen also ein Makefile oder ein Bashcript vor, um etwas Exec https://github.com/docker/compose/issues/1809#issuecomment -128073224 auszuführen

Was ich ursprünglich vorschlage, sind onrun (oder oncreate), die die Idempotenz bewahren. Laufen Sie einfach beim ersten Start. Wenn der Container angehalten oder angehalten wird, wird der neue Start nicht onrun (oder oncreate) ausgeführt.

Schließlich habe ich in meinem Git-Repository eine Compose-Datei, eine Docker-Datei und ein Makefile mit Idempotenz-Management (möglicherweise kann Makefile eine Statefile erstellen). Genius!

Es gibt einen großen Unterschied zwischen command , expose usw. und exec . Die erste Gruppe sind Containeroptionen. exec ist ein Befehls- / API-Endpunkt. Es ist eine separate Funktion, keine Optionen für die Funktion zum Erstellen von Containern.

Es gibt bereits einige Möglichkeiten, dies mit Compose zu erreichen (https://github.com/docker/compose/issues/1809#issuecomment-128059030). onrun existiert bereits. Es ist command .

In Bezug auf das spezifische Problem des Dumpings oder Ladens von Daten aus einer Datenbank handelt es sich eher um Aufgaben vom Typ "Workflow" oder "Build Automation", die im Allgemeinen in einem Makefile ausgeführt werden. Ich habe ein Tool für genau diese Anwendungsfälle namens dobi entwickelt , das alle Aufgaben in Containern

@dnephin onrun ist kein einfaches command weil Sie nur die Idempotenz verpassen.

Stellen wir uns vor. create bei der Containererstellung und wird nie wieder ausgeführt (Dump & Restore).

exec:
    create:
        - echo baby
    destroy:
        - echo keny
    start:
        - echo start
    stop:
        - echo bye

Wenn Sie weitere Beispiele benötigen:

Vielen Dank für dobi, aber wenn Sie ein Werkzeug erstellen müssen, um das Verfassen zu verbessern, ist das Verfassen schlecht und es ist besser, ein leistungsfähigeres Werkzeug zu verwenden.

Wenn Sie jedoch ein Werkzeug erstellen müssen, um das Verfassen zu verbessern, ist das Verfassen schlecht und es ist besser, ein leistungsfähigeres Werkzeug zu verwenden.

Das ist so, als würde man sagen: "Wenn Sie Anwendungen benötigen, um Ihr Betriebssystem zu verbessern, ist Ihr Betriebssystem schlecht." Kein Werkzeug sollte alles tun. Die Unix-Philosophie ist , eins zu tun und es gut zu machen . Das machen wir hier. Compose macht das eine "Orchestrieren von Containern zum Ausführen einer Anwendung". Es ist kein Tool zur Build-Automatisierung.

Das ist so, als würde man sagen: "Wenn Sie Anwendungen benötigen, um Ihr Betriebssystem zu verbessern, ist Ihr Betriebssystem schlecht." Kein Werkzeug sollte alles tun. Die Unix-Philosophie ist, eins zu tun und es gut zu machen. Das machen wir hier.

Wow, ich denke, wir haben den besten bösen Glauben erreicht.

Leider ist eine einfache wiederverwendbare Komponente nicht der Ablauf der Dinge. Docker erstellt jetzt Tools zum Starten von Cloud-Servern, Clustering-Systeme und eine Vielzahl von Funktionen: Erstellen von Images, Ausführen von Images, Hochladen, Herunterladen und schließlich sogar Überlagern von Netzwerken, die alle in einer monolithischen Binärdatei kompiliert sind, die hauptsächlich als Root auf Ihrem Server ausgeführt wird . Das Standardcontainer-Manifest wurde entfernt. Wir sollten aufhören, über Docker-Container zu sprechen, und über die Docker-Plattform sprechen. Es wird nicht zu dem einfachen zusammensetzbaren Baustein, den wir uns vorgestellt hatten.

Sie können also garantieren, dass "Docker Compose" niemals in Go inside in der monolithischen Docker-Binärdatei geschrieben wird, um die Unix-Philosophie beizubehalten? https://www.orchardup.com/blog/orchard-is-joining-docker

Um dieses ursprüngliche Ziel zu erreichen, schließen wir uns Docker an. Unter anderem werden wir weiter daran arbeiten, Docker zum besten Entwicklungserlebnis zu machen, das Sie jemals gesehen haben - sowohl mit Fig als auch durch die Integration der besten Teile von Fig in Docker.

Kurz gesagt, es gibt keine Möglichkeit, Dinge wie das Laden von Fixtures mit Compose zu tun. Ich muss sagen, ich bin überrascht ..
Die offizielle Möglichkeit besteht darin, meinem Produktionscontainer das Laden von Vorrichtungen hinzuzufügen. Oder um ein Shell-Skript um meine Compose-Datei zu schreiben? Im späteren Fall könnte ich auch einfach 'Docker Run' ausführen, wie ich es zuvor getan habe.

@discordianfish , Wenn jemand irgendwie mit der Tatsache aufwachen würde, dass CI / CD-Ingenieure in der Lage sein müssen, Lebenszyklusereignisse und Orchestrierung zumindest auf einer sehr grundlegenden Ebene zu handhaben, dann kann es sein, wer Docker / Docker-Compose kennt Ausweg aus lokalen Entwicklungspipelines und Testinfrastrukturen und einen Platz in mehr Produktionsumgebungen finden. Ich bin zuversichtlich, dass jeder, der an den Stapeln arbeitet, diese Probleme angehen wird, aber ich werde meinen Atem nicht anhalten.

Schließlich kann das, was zur Erstellungszeit getan werden muss, anders sein als das, was zur Laufzeit benötigt wird, und wird zur Laufzeit benötigt, variiert häufig je nach Bereitstellungsumgebung ...

Es ist eine nervige Arbeit, meine externen Skripte darauf aufmerksam zu machen, ob ein Up Container erstellen oder starten wird ...

Und das sind Dinge, bei denen einige Lifecycle-Hooks + Befehle + Umgebungsvariablen helfen könnten.

Sie sehen es in Service-Management-Frameworks und anderen Orchestrierungs-Tools ... warum nicht in Docker-Compose?

Sie könnten an https://github.com/dnephin/dobi interessiert sein, einem Tool, an dem ich gearbeitet habe und das für diese Workflows entwickelt wurde.

@dnephin hör auf, dieses Problem mit deinen Tools zu

Vielen Dank für Ihren konstruktiven Kommentar. Ich wusste nicht, dass ich Dobi bereits vor 8 Monaten in diesem Thread erwähnt hatte.

Wenn Sie mit Makefile / Bash zufrieden sind, ist das großartig! Ich bin froh, dass Ihr Problem gelöst wurde.

Hier wurde ein Kommentar zu diesem Thema hinzugefügt: https://github.com/docker/compose/issues/1341#issuecomment -295300246

@dnephin für diesen kann mein Kommentar angewendet werden:

So traurig, dass dieses Problem wegen einiger Unbeständigkeit gegenüber der Evolution geschlossen wurde: enttäuscht:

Der größte Wert beim Erstellen von Docker ist die Standardisierung

Das ist der Punkt. Wenn wir "nur" eine .sh-Datei schreiben könnten oder was auch immer, um den Job ohne Docker Compose zu erledigen, warum gibt es Docker Compose? :verwirrt:

Wir können verstehen, dass dies eine große Aufgabe ist, wie @ shin sagte:

Es ist leider zu viel Belastung, um in dieser Phase des Projekts zu unterstützen

:Herz:

Aber Sie können nicht "Make a script" sagen, was bedeutet "Hey, das ist zu schwer, wir werden es nicht schaffen".

Wenn es schwierig ist, sagen Sie einfach: "Ihre Idee ist interessant und erfüllt einige Anforderungen, aber es ist wirklich schwierig, und wir haben derzeit keine Ressourcen dafür ... Vielleicht könnten Sie sie entwickeln und fragen eine Pull-Anfrage "oder so ähnlich: Glühbirne:

In # 1341 sehe ich "nur" eine Möglichkeit, docker-compose.yml Befehle wie nmp install zu schreiben, die vor oder nach einigen Ereignissen (wie der Containererstellung) ausgeführt werden, wie Sie es mit docker exec <container id> npm install tun würden

Anwendungsfall

Ich habe ein benutzerdefiniertes NodeJS-Image und möchte npm install in dem daraus erstellten Container mit einem docker-compose up --build ausführen.

Mein Problem ist: Der Anwendungscode wird nicht in den Container eingefügt, sondern mit einem Volume eingebunden, das in docker-compose.yml :

custom-node:
    build: ../my_app-node/
    tty: true
    #command: bash -c "npm install && node"
    volumes:
     - /var/www/my_app:/usr/share/nginx/html/my_app

Daher kann ich npm install in der Docker-Datei nicht ausführen, da der Anwendungscode zum Überprüfen von Abhängigkeiten benötigt wird. Ich habe das Verhalten hier beschrieben: http://stackoverflow.com/questions/43498098/what-is-the-order-of-events-in-docker-compose

Um npm install auszuführen, muss ich eine Problemumgehung verwenden, die command -Anweisung:

command: bash -c "npm install && node"

Das ist nicht wirklich sauber: enttäuscht: und das kann ich nicht auf Alpine-Versionen ausführen (sie haben kein Bash installiert).

Ich dachte, dass Docker Compose eine Möglichkeit bieten würde, Exec-Befehle auf Containern auszuführen, z.

custom-node:
    build: ../my_app-node/
    tty: true
    command: node
    volumes:
     - /var/www/my_app:/usr/share/nginx/html/my_app
    exec:
     - npm install

Aber es ist nicht und ich denke, es fehlt wirklich!

Ich habe erwartet, dass Compose zum Testen gedacht ist, aber ich irre mich wahrscheinlich und es ist eher für die lokale Entwicklung usw. gedacht. Ich bin auf einige andere Ecken und Kanten gestoßen, wie verwaiste Container und die unklare Beziehung zwischen Projektname, Pfad und der Art und Weise, wie es zur Identifizierung des Eigentums verwendet wird. Was passiert, wenn Sie mehrere Compose-Dateien im selben Verzeichnis haben usw. usw. Alles in allem scheint es also nicht gut für CI zu passen.
Stattdessen plane ich, meine Produktions-k8s-Manifeste in CI wiederzuverwenden, indem ich kubelet eigenständig ausführe. Dies erfordert auch viel Kleber, aber zumindest auf diese Weise kann ich die gleichen Deklarationen für dev, test und prod verwenden.

@ lucile-sticky können Sie sh -c in alpinen verwenden.

Es hört sich so an, als ob Sie "Build-Automatisierung" wollen, die nicht die Rolle von Docker-Compose ist. Hast du dir Dobi angesehen ?

Zwei Fragen:

  • Warum ist dies nicht die Rolle von Docker Compose?
  • Wenn es nur darum geht, nur ein Tool zu haben, um alle zu regieren, warum sollte ich dann ein anderes Tool verwenden, um eine Aufgabe zu erledigen, die Docker Compose nicht ausführen kann?

Diese Funktion wird dringend benötigt!

@ Lucile-Sticky

Warum ist dies nicht die Rolle von Docker Compose?

Weil die Rolle des Komponierens klar definiert ist und diese Funktionen nicht enthält.

Compose ist ein Tool zum Definieren und Ausführen von Docker-Anwendungen mit mehreren Containern. Mit Compose verwenden Sie eine Compose-Datei, um die Dienste Ihrer Anwendung zu konfigurieren. Anschließend erstellen und starten Sie mit einem einzigen Befehl alle Dienste in Ihrer Konfiguration

Wenn es nur darum geht, nur ein Tool zu haben, um alle zu regieren, warum sollte ich dann ein anderes Tool verwenden, um eine Aufgabe zu erledigen, die Docker Compose nicht ausführen kann?

Wir wollen nicht das einzige Werkzeug sein, das sie alle regiert. Wir folgen der UNIX-Philosophie und glauben daran, dass "jedes Programm eine Sache gut macht. Um einen neuen Job zu machen, erstellen Sie neue Programme neu, anstatt sie durch Hinzufügen neuer Funktionen zu komplizieren."
Es ist in Ordnung, dieser Philosophie nicht zuzustimmen, aber so entwickeln wir bei Docker Software.

Ich erstelle diese Ausgabe im August 2015. Jedes Jahr fügt jemand einen Kommentar hinzu und wir wiederholen dieselben Fragen mit denselben Antworten (und Sie werden sicher sehen, dass

@Schienbein-

Sie können "Build" und "Provisioning" in Orchestrierungs-Tools nicht trennen.

Mögen Sie zum Beispiel einen von ihnen kennen:

Wenn Sie einen Dienst konfigurieren, müssen Sie ihn bereitstellen. Wenn ich einen Tomcat bereitstelle, muss ich ihn mit einem Krieg versorgen. Wenn ich eine Datenbank erstelle, muss ich Daten usw. einfügen, unabhängig davon, wie der Container gestartet werden muss (lassen Sie ihn vom Image-Betreuer verwalten). Der Hauptzweck eines "Provisioners" im Compose-Fall besteht darin, Missverständnisse zwischen "Was startet mein Container?" Und "Welche Provisionierung" zu vermeiden.

Wie bereits in Ihrem Zitat im Compose-Dokument erwähnt: "Mit Compose verwenden Sie eine Compose-Datei, um die Dienste Ihrer Anwendung zu Anschließend erstellen und starten Sie mit einem einzigen Befehl alle Dienste aus Ihrer Konfiguration heraus."

Unix-Philosophie? Lass mich lachen. Ich verweise Sie auf dieselbe Antwort, die ich in dieser Ausgabe gegeben habe: https://github.com/docker/compose/issues/1809#issuecomment -237195021.
Mal sehen, wie sich "moby" in der Unix-Philosophie entwickeln wird.

@ shin-docker-compose hält sich in keiner Weise an die Unix-Philosophie. Wenn Docker-Compose der Unix-Philosophie folgt, gibt es diskrete Befehle für Build, Up, RM, Start, Stop usw. und sie haben jeweils ein verwendbares stdin, stdout und stderr, die sich konsistent verhalten. sagt der Unix-Systemadministrator mit über 20 Jahren Erfahrung, einschließlich System V, HP-UX, AIX, Solaris und Linux

Kehren wir zum Verfassen zur Übersicht zurück

Compose ist ein Tool zum Definieren und Ausführen von Docker-Anwendungen mit mehreren Containern. Mit Compose verwenden Sie eine Compose-Datei, um die Dienste Ihrer Anwendung zu konfigurieren. Anschließend erstellen und starten Sie mit einem einzigen Befehl alle Dienste in Ihrer Konfiguration.

Letztendlich ist Docker-Compose ein Orchestrierungswerkzeug zum Verwalten einer Gruppe von Diensten basierend auf Containern, die aus Docker-Images erstellt wurden. Die Hauptfunktionen sind das Erstellen, Starten, Stoppen, Skalieren und Entfernen von Diensten, die in einer docker-compose.yml-Datei definiert sind.

Bei vielen Diensten müssen während jedes dieser Lebenszyklusübergänge zusätzliche Befehle ausgeführt werden. Das Skalieren von Datenbankclustern erfordert häufig das Beitreten oder Entfernen von Mitgliedern aus einem Cluster. Für die Skalierung von Webanwendungen muss häufig ein Load Balancer benachrichtigt werden, dass Sie ein Mitglied hinzugefügt oder entfernt haben. Einige paranoide Systemadministratoren mögen es, ihre Datenbankprotokolle zwangsweise zu leeren und beim Herunterfahren ihrer Datenbanken Prüfpunkte zu erstellen.

Für die meisten Orchestrierungswerkzeuge ist es erforderlich, Maßnahmen zum Statusübergang zu ergreifen. Sie finden es in den Tools von AWS, den Tools von Google, dem Vorarbeiter, dem Koch usw. Die meisten Dinge, die in diesem Orchestrierungsbereich leben, haben eine Art Lebenszyklus-Hook.

Ich denke, dies liegt fest im Bereich von Docker-Compose, da es sich um ein Orchestrierungswerkzeug handelt und sich der Statusänderungen bewusst ist. Ich glaube nicht, dass Ereignisse oder externe Skripte zum Anwendungsfall passen. Sie sind nicht idempotent, es ist viel schwieriger, einen "zweiten" Dienst zu starten, um die Ereignisse zu verfolgen. Ob die Hooks innerhalb des Containers oder außerhalb des Containers verlaufen, ist ein Implementierungsdetail.

Letztendlich gibt es ein echtes Bedürfnis, das von Benutzern von Docker-Compose geäußert wird, und @aanand , @dnephin , @ shin scheinen es abzulehnen. Es wäre schön, wenn dies in einer Roadmap enthalten wäre.

Diese Art von Funktionalität blockiert derzeit die Einführung von Docker in meinen Test- und Produktionsproduktionsbereitstellungen. Ich würde wirklich gerne sehen, dass dies auf irgendeine Weise angesprochen wird, anstatt entlassen zu werden.

Ich denke das wird sehr nützlich sein!

Für mich ist das Problem, dass, wenn ein App-Container A den Dienst 'a' ausführt, abhängig vom Datenbankcontainer B der Dienst b ausgeführt wird. Dann schlägt ein Container fehl, es sei denn, sein b ist eingerichtet.
Ich würde es vorziehen, Docker-Hub-Images zu verwenden, anstatt meine eigenen Docker-Dateien neu zu schreiben. Dies bedeutet jedoch, dass A fehlschlägt und kein Container erstellt wird. Nur Option sonst ist zu

  1. Verwenden Sie B als Basis-Image und erstellen Sie meine eigene Docker-Datei.
  2. Lassen Sie A fehlschlagen und konfigurieren Sie b im Skript und starten Sie A neu.

Ich habe genau den gleichen Anwendungsfall wie @ lucile-sticky.

@lekhnath für meinen Fall habe ich es gelöst, indem ich die Option command in meinem docker-compose.yml bearbeitet habe:

command: bash -c "npm install && node"

Aber es ist soooo hässlich TT

@ lucile-sticky Es sollte jedoch beachtet werden, dass dies jeden Befehlssatz im Dockerfile des Containers außer Kraft setzt. Ich habe dies umgangen, indem ich ein benutzerdefiniertes Shell-Skript mit volumes gemountet habe, das command in meiner Docker Compose-Datei dieses Skript ausführen ließ und das ursprüngliche CMD aus dem Dockerfile in das Skript aufgenommen habe

Warum ist dieses Problem geschlossen? Schreiben Sie ein Bash-Skript oder verwenden Sie dieses Tool, das ich geschrieben habe. Dies ist kein gültiger Grund, um dieses Problem zu schließen.

Dies ist eine sehr hilfreiche und wichtige Funktion, die in vielen Anwendungsfällen erforderlich ist, in denen Compose verwendet wird.

@dnephin Denken Sie, dass das Ausführen von Init-Skripten außerhalb des Bereichs von containergestützten Anwendungsbereitstellungen liegt? Bei compose geht es schließlich darum, "Multi-Container-Anwendungen mit Docker zu definieren und auszuführen".

Habe jemand Dobi angeschaut, wenn du es nicht getan hast, bitte hier :)
image

Vermutlich ist damit nie etwas passiert. Ich würde gerne eine Art Funktionalität in der docker-compose -Datei sehen, in der wir schreiben könnten, wann ein Befehl ausgeführt werden soll, wie im Beispiel @ ahmet2mir .

Sehr traurig zu sehen, dass diese Funktion nicht implementiert wird.

Implementieren Sie diese Funktion bitte. Ich muss Dateien nach dem Erstellen des Dockers automatisch installieren, da die Ordner, in die die Datei kopiert werden muss, nach der Initialisierung der Container erstellt werden.
Vielen Dank

Es ist unglaublich, dass diese Funktion noch nicht implementiert ist!

Dies ist eine sehr schlechte Form von @dnephin. Sie haben die Implementierung eines so begehrten Features für scheinbar Eigenwerbung verhindert und sind nicht einmal bereit, das Gespräch fortzusetzen.

Es tut mir leid, ich könnte mir keine mildere Sprache vorstellen. Das Fehlen dieser Funktion hat unseren Workflow wie viele andere Entwickler und Teams um einen Bruchteil erweitert, und Sie waren ein Hindernis bei der Lösung dieses Problems.

Oh, machen wir es dann zum unix-way .
_Nur_ (dann Multiplex) Pipe docker-compose up stdin an die CMD jedes Containers?
So dass so eine Yaml-Datei

services:
  node:
    command: sh -

würde diese Arbeit machen: cat provision.sh | docker-compose up
Container sind für exec uting Dinge, ich bessere Nutzung von stdin nicht sehen , als entlang Befehle vorbei.

Eine Alternative könnte sein:

services:
  node:
    localscript: provision.sh

Obwohl ein bisschen Shell-zentriert, würde dies 99% der Anwendungsfälle für die Bereitstellung lösen.

Obwohl es gültige Anwendungsfälle gibt und viele positive Stimmen dazu ... wurde dies anscheinend immer noch abgelehnt. Schade, dass ich, wie viele andere hier, dies äußerst nützlich finden würde.

Hinzufügen meiner +1 zum großen Stapel vorhandener +

... noch +1 hier!

Ich denke, wenn es eine solche Anfrage für diese Funktion gibt, sollte sie implementiert werden. Tools helfen uns dabei, unsere Ziele zu erreichen, und wir sollten sie so gestalten, dass wir unser Leben nicht schwerer machen.
Ich verstehe die Philosophie, an die sich jemand hält, aber das Hinzufügen von "Hooks-Befehlen" sollte kein Problem sein.

+1 +1

Während ich auf diese Funktion warte, verwende ich das folgende Skript, um eine ähnliche Aufgabe auszuführen:

docker-start.sh

#!/usr/bin/env bash

set -e
set -x

docker-compose up -d
sleep 5

# #Fix1: Fix "iptable service restart" error

echo 'Fix "iptable service restart" error'
echo 'https://github.com/moby/moby/issues/16137#issuecomment-160505686'

for container_id in $(docker ps --filter='ancestor=reduardo7/my-image' -q)
  do
    docker exec $container_id sh -c 'iptables-save > /etc/sysconfig/iptables'
  done

# End #Fix1

echo Done

@ reduardo7 Dann kannst du Docker-Compose genauso gut ganz fallen lassen, auf diese Weise hast du eine Abhängigkeit weniger.

@omeid , du hast recht! Es ist eine Problemumgehung, eine ähnliche Aufgabe auszuführen, sorry!

@ reduardo7 Sie müssen sich nicht entschuldigen, was Sie gepostet haben, wird wahrscheinlich für einige Leute nützlich sein.
Ich habe nur darauf hingewiesen, dass die ursprüngliche Ausgabe noch besteht und nicht hätte geschlossen werden dürfen. :) :)

Ich verstehe die Stände von @dnephin , die hier genannten Funktionen können durch ausreichend unterschiedliche Funktionen ersetzt werden.

Wenn solche Muster jedoch häufig verwendet werden, wie wäre es dann mit der Präsentation eines Leitfadens (oder eines Tests), damit andere ihn problemlos verwenden können?

Es scheint keine Meinungsverschiedenheit darüber zu bestehen, dass dieses Muster häufig verwendet werden kann.

@MaybeS Die einzige Meinungsverschiedenheit ist, dass @dnephin sein blödes Tool eher

@omeid ja in der Tat.

Das heutige Beispiel dafür, wie man komponieren kann, um eine Form von onrun

version: "3.3"
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        # NOTE: this URL needs to be right both for users, and for the runner to be able to resolve :() - as its the repo URL that is used for the ci-job, and the pull url for users.
        external_url 'http://gitlab:9090'
        gitlab_rails['gitlab_shell_ssh_port'] = 2224
    ports:
      - '9090:9090'
      - '2224:22'
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock

und natürlich ist der Läufer nicht registriert - und dazu müssen wir

  1. Ziehen Sie das Token in Gitlab aus der Datenbank
  2. Run-Register im Runner-Container

Anstatt die Bereitstellung meiner Multi-Container-Anwendung in Docker-Compose zu definieren, muss ich einige sekundäre Mittel verwenden - in diesem Fall ... docs?

export GL_TOKEN=$(docker-compose exec -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"')
docker-compose exec gitlab-runner gitlab-runner register -n \
  --url http://gitlab:9090/ \
  --registration-token ${GL_TOKEN} \
  --executor docker \
  --description "Docker Runner" \
  --docker-image "docker:latest" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock \
  --docker-network-mode  "network-based-on-dirname-ew_default"

mmm, ich könnte in der Lage sein, etwas zu hacken, wobei ich einen anderen Container habe, der die Docker-Buchse hat, und docker exec's

Was gibt es zu wetten, es gibt einen Weg ...

Zum Beispiel kann ich hinzufügen:

  gitlab-initializer:
    image: docker/compose:1.18.0
    restart: "no"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./gitlab-compose.yml:/docker-compose.yml
    entrypoint: bash
    command: -c "sleep 200 && export GL_TOKEN=$(docker-compose -p sima-austral-deployment exec -T -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c \"SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1\"') && docker-compose exec gitlab-runner gitlab-runner register -n --url http://gitlab:9090/ --registration-token ${GL_TOKEN} --executor docker --description \"Docker Runner\" --docker-image \"docker:latest\" --docker-volumes /var/run/docker.sock:/var/run/docker.sock --docker-network-mode  \"simaaustraldeployment_default\""

zu meiner Compose-Datei - obwohl ich eine Art Loop / Wait brauche, da Gitlab nicht sofort fertig ist - sleep 200 möglicherweise nicht genug.

Also - Sie können eine Art Muster wie dieses direkt in einem docker-compose.yml hacken - aber persönlich wäre mir eine sauberere Unterstützung viel lieber :)

@SvenDowideit onrun existiert bereits, es ist entrypoint oder cmd .

Das Einstiegspunktskript für dieses Bild bietet sogar einen Haken für Sie. $GITLAB_POST_RECONFIGURE_SCRIPT kann auf den Pfad eines Skripts festgelegt werden, das ausgeführt wird, nachdem das gesamte Setup abgeschlossen ist (siehe /assets/wrapper im Bild). Setzen Sie die env-Variable auf den Pfad Ihres Skripts, das das psql + -Register ausführt, und schon sind Sie fertig.

Selbst wenn das Bild diesen Haken nicht bietet, kann es durch Erweitern des Bildes relativ einfach hinzugefügt werden.

obwohl ich eine Art Schleife / Warten brauche, da Gitlab nicht sofort fertig ist - Schlaf 200 reicht möglicherweise nicht aus.

Dies wäre auch bei einer Option "Exec-After-Start" erforderlich. Da das Entrypoint-Skript tatsächlich einen Hook bereitstellt, denke ich, dass dies bei dieser Lösung wahrscheinlich nicht erforderlich ist.

Nein, ich denke, Sie haben einen Teil des Problems verpasst, das ich zeige:

In meinem Fall brauche ich Zugriff auf beide Container, nicht nur auf einen - also gibt mir der Einstiegspunkt / Befehl diesen nicht.

GL_TOKEN stammt aus dem Gitlab-Container und wird dann im Gitlab-Runner-Container zur Registrierung verwendet.

Der Hack, den ich mache, verwendet das Bild docker/compose , um einen dritten Container hinzuzufügen. Dies ist nichts, wofür Sie die Konfiguration / den Einstiegspunkt / die Einstellungen eines Containers ändern können, und ist ein (triviales) Beispiel für a Multi-Container-Koordination, die mehr braucht.

Ich habe an Dingen gearbeitet, um sie etwas magischer zu machen - was im Grunde bedeutet, dass mein Initialisierungscontainer einige Schlafschleifen hat, da es einige Zeit dauert, bis sich gitlab selbst initiiert.

TBH, ich fange an zu glauben, dass die Verwendung eines Skripts, das in einem Init-Container ausgeführt wird, der die Compose-Datei selbst und das Docker / Compose-Image verwendet, der richtige Weg ist, um diese Art von Komplexität zu verbergen - für den Nicht-Produktions-Versuch mich raus, und es wird einfach funktionieren "Situationen wie diese.

_IF_ ich sollte etwas seltsamen syntaktischen Zucker in Betracht ziehen, um zu helfen, vielleicht würde ich mich für etwas entscheiden wie:

gitlab-initializer:
    image: docker/compose:1.18.0
    restart: "no"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./gitlab-compose.yml:/docker-compose.yml
    entrypoint: ['/bin/sh']
    command: ['/init-gitlab.sh']
    file:
      path: /init-gitlab.sh
      content: |
            for i in $(seq 1 10); do
                export GL_TOKEN=$(docker-compose -f gitlab-compose.yml -p sima-austral-deployment exec -T -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"')
                echo "$i: token($?) == $GL_TOKEN"
                ERR=$?

                if [[ "${#GL_TOKEN}" == "20" ]]; then
                    break
                fi
                sleep 10
            done
            echo "GOT IT: token($ERR) == $GL_TOKEN"

            for i in $(seq 1 10); do
                if  docker-compose -f gitlab-compose.yml  -p sima-austral-deployment exec -T gitlab-runner \
                    gitlab-runner register -n \
                    --url http://gitlab:9090/ \
                    --registration-token ${GL_TOKEN} \
                    --executor docker \
                    --description "Docker Runner" \
                    --docker-image "docker:latest" \
                    --docker-volumes '/var/run/docker.sock:/var/run/docker.sock' \
                    --docker-network-mode  "simaaustraldeployment_default" ; then
                        echo "YAY"
                        break
                fi
                sleep 10
            done

dh wie cloud-init: http://cloudinit.readthedocs.io/en/latest/topics/examples.html#writing -out-beliebige-Dateien

Aber wenn es darauf ankommt, haben wir eine Lösung, um komplizierte Dinge mit mehreren Containern aus einem Docker-Compose-Yml heraus zu koordinieren.

Wenn Sie ein vordefiniertes Token festlegen können, können Sie dies über ein Einstiegspunktskript in gitlab-runner tun. Gibt es keine Möglichkeit, diesen Kopf der Zeit festzulegen?

@dnephin In dem Moment, in dem Sie das Skript erwähnen, sind Sie um ein Lichtjahr daneben und noch einige mehr.

onrun ist nicht dasselbe wie entrypoint oder cmd .

Das entrypoint / cmd dient zum Konfigurieren der ausführbaren Datei, die als Container init / PID 1 ausgeführt wird.

Die in diesem und vielen verwandten Themen erwähnte Idee betrifft ungefähr init scripts , was sich von init im Zusammenhang mit dem Booten unterscheidet, und handelt von Anwendungsinitiierungsskripten, denken Sie an die Datenbankeinrichtung.

@dnephin Es wäre wahrscheinlich nützlicher, wenn Sie sich auf die allgemeine Problemgruppe konzentrieren würden, als zu versuchen, die Probleme einer bestimmten Containergruppe zu umgehen.

Nach allem, was ich gesehen habe, ist es ein generiertes Geheimnis - aber in Wirklichkeit ist dies nicht die einzige Koordinierungsanforderung für mehrere Container, die selbst in diesem kleinen Spielsystem wahrscheinlich vorhanden ist - es ist nur die schnellste für mich Prototyp in der Öffentlichkeit.

Wie ist es möglich, dass wir seit Version 1 (https://docs.docker.com/compose/compose-file/compose-file) entrypoint und command in einer Compose-Datei überschreiben können? -v1 / # entrypoint) und haben noch keine Anweisung wie onrun , um einen Befehl auszuführen, wenn die Container aktiv sind?

TBH, ich denke nicht wirklich, dass onrun plausibel ist - Docker oder der Orchestrator weiß nicht, was "Container sind alle oben" bedeutet - in einem meiner Fälle schlägt der GESUNDHEITSPRÜFUNG fehl, bis ich es tue einige zusätzliche "Sachen", bei denen ich Informationen aus einem Container erhalte und damit einige andere Dinge in anderen Containern kicke.

Und wenn ich richtig arbeite, bedeutet dies, dass ich im Grunde genommen einen Operator-Container benötige, der Code enthält, der erkennt, wann einige Teile des Mehrcontainersystems bereit genug sind, um einen Teil der Arbeit zu erledigen (spülen und wiederholen), bis Entweder hat es seine Arbeit erledigt und beendet es oder es überwacht oder repariert es sogar.

Und das fühlt sich für mich wie ein Job an, der am besten (in Docker-Compose) durch einen Docker-Compose-Container mit Code gelöst wird.

Ich werde wahrscheinlich damit spielen, wie man diesen Operator dann in etwas konvertiert, das mit Docker-Schwarmstapeln umgehen kann (aufgrund anderer Projektanforderungen).

Ich bin mir nicht ganz sicher, ob es viel syntaktischen Zucker gibt, der Docker-Compose hinzugefügt werden könnte, es sei denn, es ist so etwas wie das Markieren eines Containers als "Dies ist ein Operator, geben Sie ihm magische Fähigkeiten".

Es ist deutlich zu sehen, dass Entwickler nicht auf Benutzer hören wollen. Ich werde mir ein anderes Tool ansehen. Docker-Compose ist ein großer Schmerz. Ich verstehe nicht, warum Sie nicht verstehen können, dass dies das einzig Nützliche ist, das kommt von Docker-Composer ist ein Build-Tool ... Ich habe viel Zeit damit verbracht zu suchen, wie ich den Befehl SIMPLE ausführen kann, um aktiven Benutzern Berechtigungen innerhalb eines Containers hinzuzufügen.

Es scheint, dass der Docker-Komponist einfach NICHT fertig ist ...

Ich möchte auch etwas, das onrun in meiner Erstellungsdatei enthält

__BUT__, weder Container noch Compose haben eine Möglichkeit zu wissen, was onrun bedeutet. Aus diesem Grund existiert das Operatormuster und ich habe die Beispiele in https://github.com/docker/compose/issues/1809#issuecomment -362126930 erstellt

Dies ist heute möglich. Im Wesentlichen fügen Sie einen onrun -Dienst hinzu, der wartet, bis alle anderen Dienste tatsächlich zur Interaktion bereit sind (im Fall von gitlab dauert dies einige Zeit), und dann tun Sie dies was auch immer Sie tun müssen, um die Dinge zu koordinieren.

Wenn es etwas gibt, das damit nicht funktioniert, sagen Sie es uns bitte und wir werden sehen, ob wir etwas herausfinden können!

Ich möchte auch etwas, das in meiner Erstellungsdatei ausgeführt wird

ABER weder Container noch Compose können wissen, was Onrun bedeutet.

Aus meiner Sicht bedeutet onrun pro Service, wann der erste Containerprozess startet. In einer größeren Anzahl von Fällen führt der Container ohnehin nur einen Prozess aus, da dies die empfohlene Methode zum Ausführen von Containern ist.

Das Problem der plattformübergreifenden Unterstützung wurde bereits früher gelöst, da der Befehl über docker exec vollständig betriebssystemunabhängig sein kann, genauso wie RUN in Dockerfile keinen Linux-Befehl bedeuten muss.
https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/manage-windows-dockerfile

Ich warte immer noch auf die Funktion onrun

Ich brauche diese onrun -Funktionen auch, ich dachte, es wäre in diesem Tool. Aufgrund dieser fehlenden Funktion muss ich jetzt 2 Skripte man pflegen.

Leute, was wäre, wenn ich diese docker-compose und diese onrun -Funktion zulassen würde? Würdet ihr es benutzen?

@ Wongjiahau kann so etwas sein? https://github.com/docker/compose/issues/1809#issuecomment -348497289

@ reduardo7 Ja, ich dachte daran, es in ein Skript namens docker-composei und mit dem docker-composei.yml verpacken, das das Attribut onrun .
Übrigens bedeutet docker-composei docker-compose improved .

Die eigentliche Lösung besteht wahrscheinlich darin, ein 'Orchestrator'-Image zu erstellen, das die' App Images '(möglicherweise mithilfe von Docker) intern ausführt und verwaltet (über Bash-Skripte). Andernfalls werden wir immer nach mehr Funktionen für ein Tool fragen, das "nicht das tun soll, was wir wollen".

Wir sollten also sogar Docker in Docker in Betracht ziehen ...

Nur um meine Unterstützung für diese vorgeschlagene Funktion hinzuzufügen. onrun macht zwar Sinn, aber um den potenziellen Nutzen zu erweitern und ihn ein wenig zukunftssicher zu machen, muss sich vielleicht jemand eine umfassendere "onevent" -Architektur ansehen, von denen eine onrun wäre.

In Anbetracht der vorherrschenden Richtung, in der Container in sich geschlossen sein müssen, ein Service pro Container, muss der Container im Hinblick auf sein Bewusstsein für den Betriebskontext autark sein. Was daraus resultiert, sollte die Compose-Datei das Medium sein, um das zu definieren, nicht Bolt-On-Skripte. Es ist schwer, dagegen zu argumentieren, es sei denn, Sie sind ein selbstsüchtiger Eiferer.

In meinem Fall laden meine Redis-Container Lua-Skripte, nachdem der Redis-Server gestartet wurde. In einer normalen Umgebung ohne Container kann systemd ein Skript nach dem Start ausführen. Einfach und konsistent mit der Systemarchitektur. Ein ähnliches Prinzip sollte für das Verfassen existieren, da es beim Einrichten des Kontexts für die Ausführung der Container eine Rolle spielt.

Als allgemeinen Rat an die Instandhalter sollten Sie sich auf bewährte Funktionsprinzipien konzentrieren, nicht auf persönliche Vorlieben.

Die Lösung (nachdem Sie diesen ganzen Thread gelesen haben) besteht darin, ein Bash-Skript zu verwenden, um die Arbeit zu erledigen. In diesem Fall entferne ich Docker-Compose (wir können alles mit dem Docker-Cmd machen ...).

thx dev, um Leuten zuzuhören, die deine Sachen benutzen :)

Wenn ich sehe, wie viele Nachrichten Argumente und Gegenargumente enthalten, die gegen einfache Aussagen kämpfen (z. B. ein

Bitte lassen Sie uns Open Source wirklich _open_ machen.

Gibt es Updates zu dieser Funktion? worin besteht das Problem?

@ v0lume Ich

Es scheint immer noch keine Lösung zu geben ... Ich möchte jedoch eine hackige Problemumgehung teilen.
Durch Angabe der Version "2.1" in der Datei docker-compose.yml können Sie den Healthcheck-Test missbrauchen, um beim Start zusätzlichen Code im Image auszuführen. Hier ist ein Beispiel:

version: '2.1'
services:
    elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:5.4.3
        healthcheck:
            test: |
                curl -X PUT elasticsearch:9200/scheduled_actions -H "ContentType: application/json" -d '{"settings":{"index":{"number_of_shards":'1',"number_of_replicas":'0'}}}' &&
                curl --silent --fail localhost:9200/_cat/health ||
                exit 1
            interval: 11s 
            timeout: 10s 
            retries: 3
        environment:
            - discovery.type=single-node
            - ES_JAVA_OPTS=-Xms1g -Xmx1g
            - xpack.security.enabled=false
    main:
        image: alpine
        depends_on:
            elasticsearch:
                condition: service_healthy

Wenn das von Ihnen geschriebene Healthcheck-Test-Skript mit Code> = 1 beendet wird, wird es möglicherweise mehrmals ausgeführt.
Der Integritätscheck eines Dienstes wird nur ausgeführt, wenn ein anderer Dienst davon abhängt und die im Beispiel gezeigte Bedingung service_healthy angibt.

Ich mag den @ T-vK-Ansatz und habe ihn bereits erfolgreich eingesetzt. Aber ich würde gerne noch einen ... Hack teilen:

# Run Docker container here

until echo | nc --send-only 127.0.0.1 <PORT_EXPOSED_BY_DOCKER>; do
  echo "Waiting for <YOUR_DOCKER> to start..."
  sleep 1
done

# Do your docker exec stuff here

+1
Ich stimme dem voll und ganz zu, da die Funktion benötigt wird und bereits von anderen Docker-Orchestratoren wie Kubernetes implementiert wurde. Es verfügt bereits über Lifecycle-Hooks für Container und ist hier dokumentiert.

Aber lassen Sie mich einen Anwendungsfall beisteuern, den Sie mit Dockerfiles nicht lösen können.

Angenommen, Sie müssen zur Laufzeit ein Volume bereitstellen und eine symbolische Verknüpfung von Ihrem Container zum Volume erstellen, ohne zuvor den genauen Namen des Verzeichnisses zu kennen. Ich hatte den Fall, dass der Verzeichnisname abhängig von der Umgebung, in der ich ihn bereitstellte, dynamisch war und ich ihn als Variable übergab.

Sicher habe ich eine Problemumgehung gefunden, um dieses Problem zu lösen, und es gibt mehr als eine. Auf der anderen Seite würden Hooks mir die Flexibilität und einen besseren Ansatz geben, um dynamisch Änderungen vorzunehmen, ohne den Drang, Dinge zu hacken und die Docker-Datei zu ersetzen.

Ich bin froh, dieses Problem gefunden zu haben. Ich spiele seit ein paar Jahren mit Docker und Docker Compose. Jetzt hoffte ich ernsthaft, es als Werkzeug zu verwenden, um mit der Skalierung eines Systems zu beginnen. Ich werde jedes oder jedes zweite Jahr wiederkommen, aber basierend auf der Einstellung der Projektbetreuer werde ich einfach entweder Skripte oder ein anderes Tool verwenden. Ich bin froh, nicht viel Zeit investiert zu haben und habe dies früh herausgefunden.

Pro-Tipp: Wenn jemand, der gerade erst anfängt, seinen Workflow auf diese Art von Tool umzustellen, bereits die hier beschriebenen Informationen benötigt, sollten Sie sich überlegen, warum Sie dies erstellen. Ja, Sie sind erfolgreich, aber es liegt daran, dass die Leute das Ding an erster Stelle benutzt haben und Sie wahrscheinlich sehr offen dafür waren, ihnen das zu geben, was sie brauchten.

Alles Gute.

Ich kann dir geben, was du willst (außer meiner Freundin), wenn diese Funktion implementiert ist und ich werde die glücklichste Person im ganzen Universum sein :)

Nur um meine Unterstützung für diese vorgeschlagene Funktion hinzuzufügen. onrun macht zwar Sinn, aber um den potenziellen Nutzen zu erweitern und ihn ein wenig zukunftssicher zu machen, muss sich vielleicht jemand eine umfassendere "onevent" -Architektur ansehen, von denen eine onrun wäre.

Das wäre schön

Um dies zu ergänzen, geben Sie Folgendes an:

services:
    web:
        image: node:8-alpine
        depends_on:
            - db
    db:
        image: postgres:alpine
        onrun: "echo hi"

Wäre es zu viel, ereignisübergreifende Skripte hinzuzufügen?

    web:
        events:
            db_onrun: "connectAndMigrate.sh"

Meiner Meinung nach ist es unkompliziert, dies zu Docker-Compose hinzuzufügen, nicht nur Sie, die Compose-Datei und Compose-Stack verwenden, sondern auch andere Entwickler in Ihrem Team.

  • Verwendung separater Container - Jeder sollte wissen, dass er sie ausführen sollte.
  • Schreiben Sie eine benutzerdefinierte Docker-Datei - wir haben ungefähr 20 Dienste und für jeden Dienst sollte ich Docker-Datei überschreiben, um einen Befehl auszuführen.

Wir müssen beispielsweise mkcert in jeder Umgebung installieren und konfigurieren, um vertrauenswürdige Zertifikate zu haben. Es ist kein Bestandteil von Container oder Dockerfile, da es auf der Bühne / Produktion nicht benötigt wird. Was ist hier der richtige Ansatz, um das Tool zu installieren, und jeder, der Compose File verwendet, hat überhaupt keine Ahnung, was sich hinter den Kulissen abspielt?

Hinzufügen eines weiteren Anwendungsfalls:

Benötigte eine WordPress-Instanz. Schrieb meine docker-compose.yaml. docker-compose up - Ups! Müssen die Dateiberechtigungen des Plugins-Verzeichnisses festlegen ... Ich kann keinen anderen Weg finden, um es zum Laufen zu bringen. Ich muss die Berechtigungen festlegen, nachdem der Container ausgeführt wird, da ich einige Dateien vom Host binde und dies der einzige Weg zu sein scheint Um die fs-Berechtigungen zu korrigieren, müssen Sie chown -Rf www-data.www-data /var/www/wp-content aus dem Container heraus ausführen. Schreibe meine eigene Dockerfile und baue, nur dafür? Das kommt mir dumm vor.

Zum Glück konnte ich dies mit dem oben angegebenen healthcheck -Hack implementieren. Ich sehe andere Seiten im Web, die über das Problem der Einstellungsberechtigungen für Docker-Volumes sprechen, aber die vorgeschlagenen Lösungen haben nicht funktioniert.

Ich bin froh zu sehen, dass diese Gatekeeper, @dnephin , @aanand , @ shin-, eine Menge Wärme dafür bekommen. Es spricht wirklich Bände, wenn eine ganze Community so laut wie möglich schreit und die Kernentwickler sich einfach zurücklehnen, sich behaupten und sich weigern, zuzuhören. So typisch auch. Zählen wir nicht nur die Anzahl der Daumen hoch, sondern auch die 34 Benutzer, die geantwortet haben, dass dies erforderlich ist:
01) sshishov
02) Fescobar
03) sandor11
04) web-ted
05) v0lume
06) Webpolis
07) Skull0ne
08) usergoodvery
09) wongjiahau
10) MFQ
11) yosefrow
12) Bagermen
13) daqSam
14) omeid
15) Dantebarba
16) Willyyang
17) SharpEdgeMarshall
18) verlorener Träger
19) Geist
20) rodrigorodriguescosta
21) datatypevoid
22) Dextermb
23) Lekhnath
24) lucile-klebrig
25) rav84
26) Dopry
27) ahmet2mir
28) montera82
29) Zwietracht
30) jasonrhaas
31) fferraris
32) hypergig
33) sonnenseitig
34) sthulb

Und die Nummer, die nein sagte? Eine satte 3:
01) Dnephin
02) aanand
03) shin-

Hmmm ... 34 bis 3 ...

@ rm-rf-etc gute analytik ... Ich glaube nicht einmal mehr, dass @aanand an Docker-Compose arbeiten. Mit etwas Glück plant Docker, das Komponieren zugunsten von Stacks zu verwerfen, und es wird kein Team mehr geben, über das man sich beschweren kann, und wir werden wieder Fortschritte beim Produkt sehen.

Hinzufügen eines weiteren Anwendungsfalls:

Benötigte eine WordPress-Instanz. Schrieb meine docker-compose.yaml. docker-compose up - Ups! Müssen die Dateiberechtigungen des Plugins-Verzeichnisses festlegen ... Ich kann keinen anderen Weg finden, um es zum Laufen zu bringen. Ich muss die Berechtigungen festlegen, nachdem der Container ausgeführt wird, da ich einige Dateien vom Host binde und dies der einzige Weg zu sein scheint Um die fs-Berechtigungen zu korrigieren, müssen Sie chown -Rf www-data.www-data /var/www/wp-content aus dem Container heraus ausführen.

In diesem Fall können Sie auch die Eigenschaft user in Ihrer Compose-Datei

Schreibe meine eigene Dockerfile und baue, nur dafür? Das kommt mir dumm vor.

Scheint, als hätten Sie sich eine starke Meinung gebildet; Aber realistisch gesehen wäre es nichts "Dummes", eine Docker-Datei zu schreiben, um ein Basis-Image an Ihre Bedürfnisse anzupassen. Das ist die ursprüngliche Absicht aller Basisbilder.

Zum Glück konnte ich dies mit dem oben angegebenen healthcheck -Hack implementieren. Ich sehe andere Seiten im Web, die über das Problem der Einstellungsberechtigungen für Docker-Volumes sprechen, aber die vorgeschlagenen Lösungen haben nicht funktioniert.

Ich bin froh zu sehen, dass diese Gatekeeper, @dnephin , @aanand , @ shin-, eine Menge Wärme dafür bekommen.

Ja, gute Einstellung Kumpel. : D.


@ rm-rf-etc gute analytik ... Ich glaube nicht einmal mehr, dass @aanand an Docker-Compose arbeiten.

Ja, es ist jetzt ein paar Jahre her - es ist nicht nötig, sie bei alten Themen weiter anzupingen.

Mit etwas Glück plant Docker, das Komponieren zugunsten von Stacks zu verwerfen, und es wird kein Team mehr geben, über das man sich beschweren kann, und wir werden wieder Fortschritte beim Produkt sehen.

🙄

@ shin- aber du hast es gerade mit dieser Antwort gepingt

Ich bin kürzlich erneut auf dieses Problem gestoßen, und obwohl dies wie in meiner Problemumgehung beschrieben möglich ist , funktioniert dies nur, wenn Sie 2.1 angeben, was imo stinkt.

Es ist einfach umwerfend für mich, dass die offizielle Haltung zu sein scheint, dass Sie Ihre eigenen Docker-Bilder für alles erstellen sollten.
Für mich ist das wörtlich so, als würde man sagen "Wenn Sie eine Einstellung in einem Programm ändern möchten, müssen Sie den Quellcode ändern und neu kompilieren."
Jedes Mal, wenn Sie einen neuen Dienst hinzufügen oder auf eine neuere Version von .. aktualisieren möchten, z. B. das MongoDB- oder MySQL Docker-Image, müssen Sie eine neue Docker-Datei erstellen, diese erstellen und möglicherweise in Ihre Registrierung übertragen.
Dies ist eine massive Zeit- und Ressourcenverschwendung im Vergleich dazu, wenn Sie in Ihrer docker-compose.yml einfach image: mongo:3.0.2 in image: mongo:3.0.3 ändern könnten.
Ich schimpfe nicht über lange Erstellungszeiten, ich schimpfe über die Tatsache, dass Sie sich mit Dockerfiles und docker build wenn Sie nur einen Parameter eines Dienstes aktualisieren oder ändern möchten, der möglicherweise nicht einmal ist soll als Basisbild verwendet werden.

Und das Argument, dass jede Anwendung nur eines und nur eines tun sollte, stinkt auch wirklich. Hier geht es nicht einmal darum, eine völlig neue Funktion zu implementieren, sondern nur darum, einen anderen Parameter an docker . Es stellt sich auch die Frage, warum docker run , docker build , docker exec , docker pull usw. alle Teil derselben Anwendung sind. Das Argument klingt jetzt irgendwie scheinheilig, nicht wahr?

@ shin-, ich bin Ihrem Link gefolgt und sehe nicht, wie wichtig die Benutzereigenschaft für das Festlegen des Besitzers eines gebundenen Verzeichnisses ist. Scheint mit Ports verbunden zu sein.

Betreff: Einstellung: Es sieht so aus, als ob die Leute mir zustimmen, also nimm es als starkes Feedback. Es tut mir leid, wenn Ihnen nicht gefällt, wie ich das ausdrücke, aber es scheint wirklich, dass die Benutzeranforderungen ignoriert werden. Was erwarten Sie also noch?

Ich bin hierher gekommen, in der Hoffnung auf die Funktionalität wie den Onrun: vorgeschlagen zu werden, da ich erst zwei Tage in der Verwendung von Compose bin und für mich ein Tool wie dieses diese Funktionalität haben sollte.

Es scheint überflüssig, zu meinen Docker-Dateien zurückzukehren, um sie jeweils mit einem separaten Skript für die Funktionen zu aktualisieren. Ich möchte lediglich ein Token aus einem anderen Container in eine Umgebungsvariable einfügen, in der meine Docker-Datei zuvor flexibel war. Jetzt ist sie für einen einfachen Zweck eng mit der Docker-Composer.yml und der Lösung verbunden.

Verdammt, ich habe den gesamten Thread gelesen, um die Antwort zu finden: "Okay Leute, wir haben endlich erkannt, dass das cool ist und wir werden es implementieren." Traurig zu sehen, dass dies nicht vorwärts ging.
+1 zum Laufen!

@fabiomolinar , Es gibt eine Art von Lösung, die wir ausgiebig in unseren Produktionsschwärmen verwenden, aber es ist nicht ganz so schön wie eine Veranstaltung.

Wir verwenden den folgenden Anker

#### configure a service to run only a single instance until success
x-task: &task
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: on-failure
    replicas: 1
  # for compose (not supported by stack)
  restart: on-failure

Aufgaben zu wiederholen, bis sie erfolgreich sind. Wir erstellen Container für Migrationen und Setup-Aufgaben mit idempotenten Ergebnissen und führen sie so in unserer lokalen Komposition und in unseren Stacks aus.

Der Dienst, der von der Aufgabe abhängt, muss ordnungsgemäß ausgeführt werden, wenn die Konfigurationsarbeiten nicht abgeschlossen sind. In den meisten Fällen erhalten Sie eine mögliche Konsistenz, die in den meisten Umgebungen gut funktioniert, solange Sie mit einigen Fehlern für Endbenutzer einverstanden sind.

Es wird auch davon ausgegangen, dass Ihre Service-Container sowohl mit Status vor als auch nach Abschluss der Aufgabe arbeiten können. In Anwendungsfällen wie Datenbankmigrationen sollten abhängige Dienste sowohl mit Schemata vor als auch nach der Migration arbeiten können. Natürlich müssen einige Überlegungen zur Entwicklungs- und Bereitstellungskoordination angestellt werden, aber das ist eine allgemeine Tatsache für jeden, der dies tut fortlaufende Aktualisierungen von Diensten durchführen.

@fabiomolinar , hier ist ein Beispiel, wie wir diesen Ansatz in unseren Compose-Services verwenden ...

#### configure a service to run only a single instance until success
x-task: &task
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: on-failure
    replicas: 1
  # for compose (not supported by stack)
  restart: on-failure

#### configure a service to always restart
x-service: &service
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: any
  # for compose (not supported by stack)
  restart: always

services: 
  accounts: &accounts
    <<: *service
    image: internal/django
    ports:
      - "9000"
    networks:
      - service
    environment:
      DATABASE_URL: "postgres://postgres-master:5432/accounts"
      REDIS_URL: "hiredis://redis:6379/"

  accounts-migrate:
    <<: *accounts
    <<: *task
    command: ./manage.py migrate --noinput

Vielen Dank für den Hinweis auf @dopry. Aber mein Fall war etwas einfacher. Ich musste meinen Server zum Laufen bringen und erst, nachdem er betriebsbereit war, einige Bereitstellungsaufgaben ausführen. Heute habe ich einen Weg gefunden, dies zu tun, indem ich ein kleines Prozessmanagement innerhalb einer einzigen CMD -Zeile durchgeführt habe. Stellen Sie sich vor, der Server- und der Bereitstellungsprozess heißen server bzw. deploy . Ich habe dann verwendet:

CMD set -m; server $ deploy && fg server

In der obigen Zeile wird der Monitor-Modus von bashes aktiviert. Anschließend wird der server -Prozess im Hintergrund gestartet. Anschließend wird der deploy -Prozess ausgeführt und schließlich der server -Prozess zum wieder im Vordergrund, um zu vermeiden, dass Docker den Container tötet.

Während wir darüber diskutieren, hat jemand einen Tipp, wie man einen Befehl auf dem Container oder dem Host ausführt, wenn docker-compose up ?

Ich verstehe, dass das Ausführen eines Befehls auf dem Host die Sicherheitsebenen gefährden würde, aber ich möchte nur ein Verzeichnis vor oder während des Starts eines Containers rm . Auf das Verzeichnis kann sowohl auf dem Host als auch auf dem Container zugegriffen werden. Ich möchte kein benutzerdefiniertes Docker-Image erstellen oder ein Skript haben, das zuerst rm und dann docker-compose .

Vielen Dank!

@fabiomolinar , Der von Ihnen vorgeschlagene Ansatz verstößt gegen einige 12-Faktor-App- Prinzipien. Wenn Sie Ihre Infrastruktur containerisieren, würde ich dringend empfehlen, diese genau einzuhalten.

Einige Probleme, die sich aus Ihrem Ansatz ergeben könnten

  1. langsamer Start des Containers.
  2. Wenn Sie einen Dienst mit dem Container skalieren, wird die Bereitstellung für jede Instanz einmal ausgeführt, was möglicherweise zu interessanten Problemen bei der Parallelität führt.
  3. Es ist schwieriger, Protokolle aus der 'Aufgabe' und dem Dienst für die Verwaltung und das Debuggen zu sortieren.

Ich habe den Ansatz, den ich empfehle, zunächst als kontraintuitiv empfunden. In unseren lokalen Entwicklungsumgebungen unter Docker-Compose, Docker-Schwärmen und Mesos / Marathon-Clustern hat es in der Praxis gut funktioniert. Es wurde auch effektiv um das Fehlen von "Onrun" herum gearbeitet.

Der Ansatz, den ich verwendet habe, ist in der Tat sehr hässlich. Ich habe es eine Weile benutzt, um meine Entwicklungsumgebung zum Laufen zu bringen. Aber ich habe das bereits geändert, um Einstiegspunktskripte und den Befehl at zu verwenden, um Skripte auszuführen, nachdem der Server betriebsbereit ist. Jetzt läuft mein Container mit dem richtigen Prozess als PID 1 und reagiert auf alle Signale richtig.

Das brauchen wir noch. Ich kann keinen Weg finden, wie ich meine Datenbank-Rollups ausführen kann, nachdem der Container erfolgreich gestartet wurde, ohne ihn in einer Reihe von Makefiles zu erstellen.

@ victor-perov erstellt einen weiteren Container für die Rollup-Aufgabe und führt ihn als separaten Service aus

Hier sind einige Ausschnitte aus einem unserer Projekte, die einen Task-Service zum Ausführen einer Datenbankmigration zeigen.

x-task: &task
  # run once deploy policy for tasks
  deploy:
    restart_policy: 
      condition: none
    replicas: 1

service:
  automata-auth-migrate:
    <<: *automata-auth
    <<: *task
    # without the sleep it can't lookup the host postgres.  maybe the command is ran before the network set is complete.
    command: sleep 5 && python /code/manage.py migrate --noinput

Nun, dies ist das vierte Jahr, auf das diese Diskussion ausgedehnt wurde. Lassen Sie mich also meine +1 zu diesem Anwendungsfall hinzufügen, wenn onrun . PS: Ich hätte Popcorn für den ganzen Thread kaufen sollen.

Ich würde auch denken, dass onrun oder ein gleichwertiger

IMO Docker Compose war ein großartiger MVP für die Container-Orchestrierung, um die Leute davon zu überzeugen, dass die Verwaltung von Containern einfach sein kann. Vielleicht sollten wir, die Community, davon ausgehen, dass es sich im "Wartungsmodus" befindet, da sich produktionsbereite Orchestrierungslösungen (dh Kubernetes) vermehrt haben. Wenn Sie erweiterte Funktionen wie Containerabhängigkeiten haben, kombiniert mit fehlenden Funktionen wie "Dieses Ding ausführen, nachdem der Container hochgefahren ist", scheint es der Erzählung zu entsprechen, dass das Entwicklungstempo einfach ein Plateau erreicht hat. Zumindest ist es nicht offensichtlich, dass diese Funktion als außerhalb des Geltungsbereichs liegend betrachtet werden sollte.

Mit Dockerfile können Sie nicht alles einfach machen. Angenommen, Sie möchten einem Container ein eigenes Skript hinzufügen.
Nehmen Sie zum Beispiel den Container mysql und versuchen Sie, ein einfaches Skript hinzuzufügen, um im Falle eines Ereignisses eine API aufzurufen.
Sie können es entweder tun durch:

  • Ändern Sie die Dockerfile von MySQL und fügen Sie dem Container vor dem Einstiegspunkt ein eigenes Skript hinzu. Sie können dem Dockerfile kein CMD hinzufügen, da dies ein Argument für das ENTRYPOINT .
  • Sie können den Container ausführen und dann Ihr Skript in den laufenden Container kopieren und ausführen [ docker cp , docker exec ].

Deshalb denke ich auch, dass eine Funktion wie onrun Vorteil ist, da das Ändern der Docker-Datei nicht immer ausreicht.

Dump, warum ist das geschlossen? Betrachten Sie die Situation, wenn Sie ein offizielles Docker-Image wie Cassandra verwenden und das Schema nach dem Start laden müssen ... Sie müssen hierfür Ihre eigene Bash-Skriptlösung implementieren ... ugh, das ist hässlich

@somebi sieht aus wie komponiert ist geschlossen ...

Nur meine zwei Cent: Ich bin hier gelandet, weil ich derzeit jedes Mal, wenn ich den Container starte, Apache-Module manuell aktivieren muss (SSL ist im Docker Hub-Image wordpress nicht standardmäßig aktiviert). Nicht das Ende der Welt, aber ich hatte gehofft, ein paar Befehle ausführen zu können, wenn es hoch geht, damit ich die Container nahtlos auf und ab bringen kann, ohne sie einschlagen zu müssen.

Nur meine zwei Cent: Ich bin hier gelandet, weil ich derzeit jedes Mal, wenn ich den Container starte, Apache-Module manuell aktivieren muss (SSL ist im Docker Hub-Image wordpress nicht standardmäßig aktiviert). Nicht das Ende der Welt, aber ich hatte gehofft, ein paar Befehle ausführen zu können, wenn es hoch geht, damit ich die Container nahtlos auf und ab bringen kann, ohne sie einschlagen zu müssen.

Nun, dies könnte leicht behoben werden, wenn Sie ein neues Image basierend auf dem WordPress-Image erstellen, in dem die benötigten Module aktiviert sind. Verwenden Sie das stattdessen für z. B. eine Docker-Datei:

FROM wordpress:php7.1
RUN a2enmod ssl

Eine andere Lösung wäre, die WordPress-Docker-Datei herunterzuladen und die Modulaktivierung hinzuzufügen. Erstellen Sie dann mit Docker Build ein neues Image für sich. Zum Beispiel ist dies die Dockerfile für WordPress 5.2 mit PHP 7.1:

WordPress Dockerfile

Sie können weitere Module in Zeile 63 aktivieren oder die SSL-Generierung ausführen.

All dies ist nicht der Fall, über den wir hier diskutieren. Das Problem besteht darin, dynamische Hooks im Container-Lebenszyklus zu erstellen, z. B. wenn der Start endet usw.

Dies wäre eine schöne Ergänzung zu Docker-Compose!

Antworten wie die in diesem Thread sind der Grund, warum Kubernetes "das ganze" Geld behält, das Docker (Technologie) produziert, und es ist keine schlechte Sache, hoffentlich wird jemand bald Docker (Unternehmen) kaufen und die Art und Weise ändern, wie Community-Vorschläge / -Anfragen willkommen sind / analysiert ...

Antworten wie die in diesem Thread sind der Grund, warum Kubernetes _ "all" _ das Geld behält, das Docker (Technologie) produziert, und es ist keine schlechte Sache, hoffentlich wird jemand Docker (Unternehmen) bald kaufen und die Art und Weise ändern, wie Community-Vorschläge / -Anfragen sind willkommen / analysiert ...

Ich schrieb einen ähnlichen Kritiker, ohne beleidigende Aussage (es war im Sinne von Open-Source-Projekten, die nicht vollständig Open Source sind und deren Betreuer Argumente trotzig ignorieren, ohne zu zeigen, wie viel technisches Argon sie besitzen), es erhielt viel Unterstützung und die Nachricht wurde entfernt.

Das zeigt, welche arroganten Personen dahinter stehen.

Wenn Ihre Community 4 Jahre lang etwas verlangt und Sie (Docker) Ihre Augen schließen, zeigt dies, dass Sie nicht in die gleiche Richtung schauen wie sie: /

Und jetzt gab Docker auf und war ausverkauft.
Weil sie nicht zuhören konnten ... haben sie verloren.

Schade - aber hey ho.

Es ist wirklich schade, dass so etwas nicht existiert. Ich hätte gerne onFailure Hooks erstellen können, die stattfinden könnten, wenn die Gesundheitsprüfungen fehlschlagen.

dh

services:
  app:
    image: myapp:latest
    hooks:
      onFailure:
        - # Call a monitoring service (from the host machine) to tell it that the service is offline.

Dies ist nützlich, wenn die Anwendung nicht an einen Socket / Port gebunden ist. Kubernetes ist hier wahrscheinlich der richtige Weg, aber dies ist eine ziemlich große Änderung der Infrastruktur und ein Overkill für eine sehr kleine Umgebung.

Bearbeiten:
Um dies zu umgehen, habe ich den Einstiegspunkt meines Containers aktualisiert, um die Überwachungsfunktionalität zu "verpacken". dh

# /app/bin/run_with_monitor
#!/bin/bash
set -eE

updateMonitoringSystem() {
 # do something here... This is run from the container, though, unfortunately.
 if [[ $? -eq 1 ]]; then
  # Failed!
 else
  # All is good!
 fi
}

trap 'updateMonitoringSystem' EXIT

$@
# Dockerfile
....
CMD ["/app/bin/run_with_monitor", "./my-app"

Trotzdem wäre es schön, dies zu tun, ohne das Bild ändern zu müssen.

: man_shrugging: Ich habe nach dieser grundlegenden Funktionalität gesucht, die der Konkurrent (Kubernetes) hat, und stattdessen habe ich ein Müllcontainerfeuer gefunden.

Es ist eine echte Schande, jetzt muss ich separate Docker-Images für lokale Tests verwalten.

Frohes neues Jahr: roll_eyes:

image

@LukeStonehm gleich hier. Musste EINEN Befehl ausführen, nachdem der Container aufgestanden war, aber stattdessen mit heißem Müll behandelt wurde. Ich habe wirklich keine Lust, meine eigenen Bilder und Docker-Dateien zu verwalten, wenn ein offizielles Bild mich zu 90% oder mehr dorthin bringt.

Eine erhebliche Anzahl von Programmen ist darauf angewiesen, dass bestimmte Dienste beim Start vorhanden sind. Zum Beispiel eine MySQL- oder MongoDB-Datenbank.

Daher gibt es in diesen Fällen keine vernünftige Möglichkeit, docker-compose zu verwenden.

Stattdessen wird von den Benutzern Folgendes erwartet:

  • Erfahren Sie, wie Sie Dockerfiles schreiben (und programmieren)
  • Erfahren Sie, wie Sie Docker images erstellen
  • Erstellen Sie Dockerfiles das von den Originalbildern erbt, und fügen Sie Code hinzu, um sicherzustellen, dass die Container aufeinander warten
  • Überprüfen Sie die Basisimages regelmäßig auf Sicherheitsupdates
  • Ändern Sie regelmäßig Dockerfiles , um die Updates anzuwenden
  • Bauen Sie regelmäßig Docker images aus diesen Dockerfiles

Und das ist scheiße, weil:

  • Sie verschwenden viel Zeit damit, Dinge zu lernen, die Sie sonst vielleicht gar nicht brauchen
  • Sie verschwenden regelmäßig Hardwareressourcen, um Docker images selbst zu erstellen und zu speichern oder sogar um sie hochzuladen / herunterzuladen (ziehen / pushen)
  • Sie verschwenden regelmäßig Zeit damit, diese Dockerfiles zu schreiben, zu erstellen, zu testen, zu reparieren usw.
  • Sie gefährden möglicherweise die Sicherheit Ihrer Bilder, weil Sie nicht wissen, was Sie tun
  • Sie verlieren die Fähigkeit, nur offiziell verifizierte / signierte Docker images auszuführen

Wenn wir eine Startprüfung hätten, wäre dies alles nicht notwendig und wir könnten einfach image: mysql:8.0.18 in image: mysql:8.0.19 ändern, wann immer wir wollen und fertig sind!

Realistisch gesehen geschieht dies derzeit in der realen Welt:

  • Die Leute erstellen ihre eigenen Dockerfiles und nehmen Änderungen vor, damit sie mit docker-compose
  • Sie bauen ihre Bilder einmal
  • Und patchen Sie sie nicht regelmäßig
  • Hacker werden glücklich

Und man kann nicht sagen, dass docker-compose nur "eins tun" soll, weil es schon so ziemlich alles macht. Noch wichtiger ist das Abrufen und Erstellen von Bildern sowie das Festlegen von Abhängigkeiten mithilfe der Eigenschaft depends_on . Hier geht es nicht einmal darum, eine völlig neue Funktion zu implementieren, sondern nur darum, einen anderen Parameter an docker .

@ binman-Docker @crosbymichael @dmcgowan @ebriney @ehazlett @eunomie @guillaumerose @jeanlaurent @justincormack @lorenrh @manishtomar @olegburov @routelastresort @spencerhcheng @StefanScherer @thaJeztah @tonistiigi @ulyssessouza @aiordache @ chris-Crone @ndeloof
Bitte überdenken Sie diese Funktion oder lassen Sie uns zumindest eine angemessene Diskussion darüber führen.

Die task service -Technik funktioniert zu diesem Zeitpunkt ziemlich gut für mich, hat aber ihre Eigenheiten. Wir haben das Muster in unseren Compose-Dateien für Migrationen und Anwendungsinitialisierung ausführlich angewendet. Aber ich bin damit einverstanden, dass ein besseres 'Depends_on', das auf einen erfolgreichen Healthcheck oder einen erfolgreichen Exit / Task-Abschluss gewartet hat, viele Aufgaben einfacher und zuverlässiger machen würde.

Dies wäre wirklich eine hilfreiche Ergänzung.

Ich denke, es ist hervorzuheben, dass Kubernetes diese Funktionalität über den Lebenszyklus nach dem Start hat.

k8s! = Docker-Compose. Falscher Kanal

Es tut mir leid, dass ich nicht klar bin, aber mein Punkt war: Kubernetes unterstützt dies, und da Kubernetes und Docker Compose viele der gleichen Anwendungsfälle / Zwecke haben, wäre dies ein Argument dafür, dass es komponiert wird. Entschuldigung, wenn ich unklar war.

Gute Nachrichten!!

Ich denke, Docker hat uns gehört (zu diesem Thema und einigen anderen). https://www.docker.com/blog/announcing-the-compose-specification/

Versuchen wir, dort an der Spezifikation zu arbeiten, um die Anforderungen der Community zu erfüllen. Wir können versuchen, dies mit diesem Neustart zu einer offenen und freundlichen Community zu machen.

Gute Nachrichten!!

Ich denke, Docker hat uns gehört (zu diesem Thema und einigen anderen). https://www.docker.com/blog/announcing-the-compose-specification/

Versuchen wir, dort an der Spezifikation zu arbeiten, um die Anforderungen der Community zu erfüllen. Wir können versuchen, dies mit diesem Neustart zu einer offenen und freundlichen Community zu machen.

Hat jemand diese Änderung schon vorgeschlagen? Die Mailingliste ist noch nicht verfügbar, daher denke ich, dass der nächstbeste Ort hier ist: https://github.com/compose-spec/compose-spec

Ich sehe kein Problem, das dieses Problem beschreibt, bin mir aber nicht sicher, ob dies der richtige Ort ist ...

Bearbeiten: Ich habe ein Problem unter https://github.com/compose-spec/compose-spec/issues/84 geöffnet

Sie können den HEALTHCHECK verwenden , um etwas anderes wie das folgende Beispiel zu tun:

Code

Dockerfile

FROM ubuntu

COPY healthcheck.sh /healthcheck.sh
RUN chmod a+x /healthcheck.sh

HEALTHCHECK --interval=5s CMD /healthcheck.sh

CMD bash -c 'set -x; set +e; while true; do cat /test.txt; sleep 3; done'

healthcheck.sh

#/usr/bin/env bash

set -e

FIRST_READY_STATUS_FLAG='/tmp/.FIRST_READY_STATUS_FLAG'

# Health check

echo 'Run command to validate the container status HERE'

# On success
if [ ! -f "${FIRST_READY_STATUS_FLAG}" ]; then
  # On first success...
  touch "${FIRST_READY_STATUS_FLAG}"

  # Run ON_RUN on first health check ok
  if [ ! -z "${DOCKER_ON_RUN}" ]; then
    eval "${DOCKER_ON_RUN}"
  fi
fi
  1. Führen Sie den _Health Check_ aus.

    • Wenn dies fehlschlägt, wird das Skript mit dem Exit-Code 1 .

    • Wenn die Gesundheitsprüfung in Ordnung ist, wird das Skript fortgesetzt.

  2. Wenn es die erste _Health-Prüfung OK_ ist und die Umgebungsvariable DOCKER_ON_RUN vorhanden ist, führen Sie sie aus.

Beispiel

docker-compose.yml

version: "3.7"

services:
  test:
    build:
      context: .
    image: test/on-run
    environment:
      DOCKER_ON_RUN: echo x >> /test.txt

Sie können die Umgebungsvariable DOCKER_ON_RUN , um einen benutzerdefinierten Befehl zu übergeben, der nach der Ausführung ausgeführt werden soll.

Ausführungsergebnis

docker-compose build
docker-compose up

Ausgabe:

Creating network "tmp_default" with the default driver
Creating tmp_test_1 ... done
Attaching to tmp_test_1
test_1  | + set +e
test_1  | + true
test_1  | + cat /test.txt
test_1  | cat: /test.txt: No such file or directory
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | cat: /test.txt: No such file or directory
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
  • Sie können den Fehler cat: /test.txt: No such file or directory bis der _Health Check_ fertig ist.
  • Sie können nach dem Lauf nur ein x in /test.txt .

Hoffe das kann jemandem helfen.

Bearbeiten 1

Wenn Sie keine Gesundheitsprüfung benötigen, können Sie den Rest des Skripts verwenden.

@ reduardo7
Vielen Dank für Ihre Problemumgehung.
Sie möchten nur hinzufügen, falls Sie den ersten Befehl ausführen müssen, z. B. für die Benutzererstellung usw., können Sie das Volume für touch "${FIRST_READY_STATUS_FLAG}"

Viele dieser Lösungen sind gültige Problemumgehungen für dieses Problem. Zum Beispiel könnte das Erstellen eines Einstiegspunktskripts auch Folgendes beheben:
ENTRYPOINT ["./entrypoint.sh"]

Dies beinhaltet eine komplexere Logik, bevor der eigentliche Dienst oder Prozess ausgeführt wird.
Dies ist jedoch immer noch kein Haken, der es uns ermöglichen würde, Logik in den Container-Lebenszyklus einzufügen:

  • vor dem Erstellen
  • bevor es losgeht
  • nach dem Start
  • vor der Zerstörung
  • auch nach der Zerstörung
  • usw ...

Ich weiß, dass nicht alle oben genannten Punkte von Bedeutung sind, aber ich hoffe, dass Sie sich ein Bild machen, denn das ist der Punkt.
Dies könnte auch in docker-compose mit einer Direktive wie der folgenden enthalten sein:

lifecycle:
    before_start: "./beforeStartHook.sh"
    after_destroy: "./afterDestroyHook.sh"

oder sogar so:

hooks:
    before_destroy: "./beforeDestroyHook.sh"
    before_create: "./fixFsRights.sh"

Ich kann keine Datei überschreiben, für die eine Root-Berechtigung mithilfe eines Hook-Skripts oder eines Bootstrap-Skript-Ansatzes erforderlich ist, da wir den Container als Nicht-Root-Benutzer starten

Wow, so eine Grundfunktionalität und noch nicht implementiert.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen