Ich habe eine Reihe von Tutorials gesehen, die anscheinend dasselbe tun, was ich versuche, aber aus irgendeinem Grund werden meine Docker-Container beendet. Grundsätzlich richte ich einen Webserver und einige Daemons in einem Docker-Container ein. Ich mache die letzten Teile davon durch ein Bash-Skript run-all.sh
, das CMD in meiner Docker-Datei durchläuft. run-all.sh
sieht aus wie das:
service supervisor start
service nginx start
Und ich starte es in meinem Dockerfile wie folgt:
CMD ["sh", "/root/credentialize_and_run.sh"]
Ich kann sehen, dass alle Dienste korrekt gestartet werden, wenn ich Dinge manuell ausführe (dh mit -i -t / bin / bash zum Image komme), und alles sieht so aus, als würde es korrekt ausgeführt, wenn ich das Image ausführe, aber es wird einmal beendet Damit ist der Start meiner Prozesse abgeschlossen. Ich möchte, dass die Prozesse unbegrenzt ausgeführt werden, und soweit ich weiß, muss der Container weiter ausgeführt werden, damit dies geschieht. Trotzdem sehe docker ps -a
ich beim Laufen :
➜ docker_test docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7706edc4189 some_name/some_repo:blah "sh /root/run-all.sh 8 minutes ago Exited (0) 8 minutes ago grave_jones
Was gibt? Warum ist es aufregend? Ich weiß, ich könnte einfach eine while-Schleife am Ende meines Bash-Skripts einfügen, um es aufrechtzuerhalten, aber wie kann ich verhindern, dass es beendet wird?
Antworten:
So sollten Sie Ihre Docker-Container nicht wirklich entwerfen.
Wenn Sie einen Docker-Container entwerfen, sollten Sie ihn so erstellen, dass nur ein Prozess ausgeführt wird (dh Sie sollten einen Container für Nginx und einen für Supervisord oder die App haben, die er ausführt). Außerdem sollte dieser Prozess im Vordergrund ausgeführt werden.
Der Container wird "beendet", wenn der Prozess selbst beendet wird (in Ihrem Fall ist dieser Prozess Ihr Bash-Skript).
Wenn Sie jedoch wirklich mehrere Dienste in Ihrem Docker-Container ausführen müssen (oder möchten), sollten Sie von "Docker Base Image" ausgehen , das
runit
als Pseudo-Init-Prozess verwendet wird (runit
bleibt online, während Nginx und Supervisor ausgeführt werden) im Vordergrund, während Ihre anderen Prozesse ihr Ding machen.Sie verfügen über umfangreiche Dokumente, sodass Sie in der Lage sein sollten, das, was Sie versuchen, relativ einfach zu erreichen.
quelle
--nodaemon
Option.Wenn Sie eine Docker-Datei verwenden, versuchen Sie:
(Dies ist natürlich nur für Entwicklungszwecke gedacht. Sie sollten einen Container nicht am Leben erhalten müssen, es sei denn, er führt einen Prozess aus, z. B. Nginx ...)
quelle
CMD["sleep", "1d"]
aber Ihre Lösung scheint besser zu seinCMD["sleep", "infinity"]
.exec tail -f /dev/null
aber die Verwendungtail
als Einstiegspunkt ist eine falsche Antwort.Ich hatte gerade das gleiche Problem und ich fand heraus , dass , wenn Sie Ihren Behälter mit dem laufen
-t
und-d
Flagge, es läuft weiter .Folgendes tun die Flags (laut
docker run --help
):Das wichtigste ist die
-t
Flagge.-d
Sie können den Container einfach im Hintergrund ausführen.quelle
docker logs <image>
, um sicherzustellen, dass es sich um einen Fehler handelt, der dazu führt, dass mein Docker-Container beendet wird. Der Exit-Status ist0
und die letzte Ausgabe ist die Bestätigung, dass meinlighttpd
Server läuft:[ ok ] Starting web server: lighttpd.
exec bash
oderexec sh
wenn bash nicht installiert ist, bis zum Ende von start.sh. Dann können Sie das Flag -tDer Grund dafür ist, dass das Shell-Skript zuerst als PID 1 ausgeführt wird. Wenn dies abgeschlossen ist, ist PID 1 nicht mehr vorhanden und Docker wird nur ausgeführt, solange PID 1 vorhanden ist.
Sie können Supervisor verwenden, um alles zu erledigen. Wenn Sie mit dem "-n" -Flag ausgeführt werden, wird angewiesen, nicht zu dämonisieren, sodass dies der erste Prozess bleibt:
Und deine Supervisord.conf:
Dann können Sie so viele andere Prozesse haben, wie Sie möchten, und der Supervisor übernimmt bei Bedarf den Neustart.
Auf diese Weise können Sie Supervisord in Fällen verwenden, in denen Sie möglicherweise Nginx und PHP5-Fpm benötigen, und es macht wenig Sinn, sie getrennt zu haben.
quelle
If the "init" process of a PID namespace terminates, the kernel terminates all of the processes in the namespace via a SIGKILL signal. This behavior reflects the fact that the "init" process is essential for the correct operation of a PID namespace.
Sie können
cat
ohne Argumente, wie von bro @ Sa'ad erwähnt, einfach ausgeführt werden, um den Container einfach am Laufen zu halten [eigentlich nur auf Benutzereingaben zu warten] (Jenkins 'Docker-Plugin macht dasselbe)quelle
cat
. Jenkins Docker-Plugin tut dies.daemon off;
Stellen Sie sicher, dass Sie nginx.conf hinzufügen oder esCMD ["nginx", "-g", "daemon off;"]
gemäß dem offiziellen nginx-Image ausführenVerwenden Sie dann Folgendes, um sowohl Supervisor als Service als auch Nginx als Vordergrundprozess auszuführen, um zu verhindern, dass der Container beendet wird
service supervisor start && nginx
In einigen Fällen müssen Sie mehr als einen Prozess in Ihrem Container haben, sodass das Erzwingen, dass der Container genau einen Prozess hat, nicht funktioniert und weitere Probleme bei der Bereitstellung verursachen kann.
Sie müssen also die Kompromisse verstehen und Ihre Entscheidung entsprechend treffen.
quelle
Erfassen Sie die PID des ngnix-Prozesses in einer Variablen (z. B. $ NGNIX_PID) und am Ende der Einstiegspunktdatei
Auf diese Weise sollte Ihr Container ausgeführt werden, bis ngnix aktiv ist. Wenn ngnix stoppt, stoppt auch der Container
quelle
Motivation:
Es ist nichts Falsches daran, mehrere Prozesse in einem Docker-Container auszuführen . Wenn man Docker gerne als leichte VM verwendet, dann soll es so sein. Andere teilen ihre Anwendungen gerne in Mikrodienste auf. Ich denke: Ein LAMPENstapel in einem Container? Einfach toll.
Die Antwort:
Halten Sie sich an ein gutes Basisbild wie das Phusionsbasisbild . Es kann andere geben. Bitte kommentieren.
Und dies ist nur ein weiteres Plädoyer für den Vorgesetzten. Weil das Phusionsbasis-Image neben einigen anderen Dingen wie der Einrichtung von Cron und Gebietsschema einen Supervisor bereitstellt. Dinge, die Sie gerne einrichten möchten, wenn Sie eine so leichte VM ausführen. Für das, was es wert ist, bietet es auch SSH-Verbindungen in den Container.
Das Phusions-Image selbst wird nur gestartet und läuft weiter, wenn Sie diese grundlegende Docker-Run-Anweisung ausgeben:
Oder ganz einfach:
Wenn ein Basis-Image nicht für Sie ist ... Damit das schnelle CMD es am Laufen hält, würde ich für bash Folgendes annehmen:
Oder dies für Busybox:
Das ist schön, weil es sofort auf einem beendet wird
docker stop
. Einfachsleep
odercat
dauert einige Sekunden, bis der Container austritt.quelle
Wie wäre es mit der Überwachungsform des Dienstes, falls verfügbar?
Service IHR_SERVICE beaufsichtigen
Spart das Erstellen eines
supervisord.conf
quelle