Im Moment generieren unsere Jenkins-Agenten für jedes unserer Rails-Projekte eine docker-compose.yml und führen dann docker-compose up aus. Die Datei docker-compose.yml verfügt über einen Hauptcontainer "Web", in dem sich rbenv und alle anderen Rails-Abhängigkeiten befinden. Es ist mit einem DB-Container verknüpft, der die Test-Postgres-DB enthält.
Das Problem tritt auf, wenn wir die Tests tatsächlich ausführen und Exit-Codes generieren müssen. Unser CI-Server wird nur bereitgestellt, wenn das Testskript Exit 0 zurückgibt, Docker-Compose jedoch immer 0 zurückgibt, selbst wenn einer der Containerbefehle fehlschlägt.
Das andere Problem ist, dass der DB-Container unbegrenzt ausgeführt wird, auch nachdem der Webcontainer die Tests ausgeführt hat, und daher docker-compose up
niemals zurückkehrt.
Gibt es eine Möglichkeit, Docker-Compose für diesen Prozess zu verwenden? Wir müssten in der Lage sein, die Container auszuführen, aber nach Abschluss des Webcontainers beenden und den Exit-Code zurückgeben. Im Moment stecken wir manuell mit Docker fest, um den DB-Container hochzufahren und den Webcontainer mit der Option --link auszuführen.
quelle
docker-compose
Dies sollte der richtige Weg sein, wenn Sie 1.12.0 und höher verwenden. Vielleicht ist es auch dein Fall. Ein Beispiel könnte sein :docker-compose up --exit-code-from test-unit
. Beachten Sie, dass es bei mir nicht funktioniert hat, bis ichset -e
am Anfang meines Skripts ein hinzugefügt habe.--exit-code-from
funktioniert aber nicht mit-d
. Es wird diese Fehler werfen:using --exit-code-from implies --abort-on-container-exit
und--abort-on-container-exit and -d cannot be combined.
docker-compose run
ist der einfache Weg, um die gewünschten Exit-Status zu erhalten. Beispielsweise:Alternativ haben Sie die Möglichkeit, die toten Container zu inspizieren . Sie können das
-f
Flag verwenden, um nur den Exit-Status abzurufen.Was den
docker-compose up
Datenbankcontainer betrifft, der niemals zurückgegeben wird, müssen Sie diesen Container sigkill , wenn Sie ihn verwenden . das ist wahrscheinlich nicht was du willst. Stattdessen können Siedocker-compose up -d
Ihre Container dämonisiert ausführen und die Container nach Abschluss Ihres Tests manuell beenden.docker-compose run
sollte verknüpfte Container für Sie ausführen, aber ich habe auf SO ein Geschwätz über einen Fehler gehört, der verhindert, dass dies jetzt wie beabsichtigt funktioniert.quelle
docker-compose logs
-T
Aufbauend auf Kojiros Antwort:
docker-compose ps -q | xargs docker inspect -f '{{ .State.ExitCode }}' | grep -v '^0' | wc -l | tr -d ' '
Gibt zurück, wie viele Exit-Codes ungleich 0 zurückgegeben wurden. Wäre 0, wenn alles mit Code 0 beendet würde.
quelle
docker-compose ps
, zum Beispiel:docker-compose ps | grep -c "Exit 1"
gibt Ihnen die Anzahl an, bei der "Exit 1" in der Anzeige von übereinstimmtdocker-compose ps
(was eine hübsch gedruckte Übersichtstabelle der Ergebnisse liefert). Die Exit-Codes sind in der Spalte "Status" aufgeführt.Wenn Sie bereit sind,
docker-compose run
Ihre Tests manuell zu starten, führt das Hinzufügen des--rm
Flags seltsamerweise dazu, dass Compose den Exit-Status Ihres Befehls genau wiedergibt.Hier ist mein Beispiel:
quelle
(docker-compose run --rm ...) || exit $?
zur Kündigung im Fehlerfall. Nützlich in Bash-Skripten.Verwenden Sie
docker wait
, um den Exit-Code zu erhalten:foo
ist der "Projektname". Im obigen Beispiel habe ich es explizit angegeben, aber wenn Sie es nicht angeben, ist es der Verzeichnisname.bar
ist der Name, den Sie dem zu testenden System in Ihrer docker-compose.yml geben.Beachten Sie, dass
docker logs -f
dies auch das Richtige ist, wenn der Container stoppt. So können Sie setzenzwischen dem
docker-compose up
und dem,docker wait
damit Sie Ihre Tests laufen sehen können.quelle
--exit-code-from SERVICE
und arbeiten--abort-on-container-exit
Sie nicht in Szenarien, in denen Sie alle Container bis zur Fertigstellung ausführen müssen, sondern schlagen Sie fehl, wenn einer von ihnen vorzeitig beendet wird. Ein Beispiel könnte sein, wenn 2 Testanzüge gleichzeitig in verschiedenen Containern ausgeführt werden.Mit dem Vorschlag von @ spendhil können Sie
docker-compose
ein Skript einbinden , das fehlschlägt, wenn Container dies tun.Dann wechseln Sie auf Ihrem CI-Server einfach
docker-compose up
zu./docker-compose.sh up
.quelle
Mit Docker-Rails können Sie angeben, welcher Container-Fehlercode an den Hauptprozess zurückgegeben wird, damit Ihr CI-Server das Ergebnis ermitteln kann. Es ist eine großartige Lösung für CI und die Entwicklung von Schienen mit Docker.
Beispielsweise
In Ihrem
docker-rails.yml
Testament erhalten Sie denweb
Container-Exit-Code als Ergebnis des Befehlsdocker-rails ci test
.docker-rails.yml
ist nur ein Meta-Wrapper um den Standarddocker-compose.yml
, der Ihnen das Potenzial gibt, dieselbe Basiskonfiguration für verschiedene Umgebungen zu erben / wiederzuverwenden, dh Entwicklung gegen Test gegen parallele Tests.quelle
Falls Sie möglicherweise mehr Docker-Compose-Dienste mit demselben Namen auf einer Docker-Engine ausführen und den genauen Namen nicht kennen:
echo %?
- Gibt den Exit-Code vom Test-Chrome-Dienst zurückLeistungen:
quelle
Sie können den Exit-Status sehen mit:
quelle
docker-compose ps | grep servicename | grep -v 'Exit 0' && echo "Automation or integration tests failed." && exit 1