I' ve gesehen ein paar Tutorials, die scheinen, tun das gleiche, was I' m versucht zu tun, aber aus irgendeinem Grund meine Docker-Container beenden. Im Grunde bin ich einen Web-Server und ein paar Daemons innerhalb eines Docker-Containers einrichten. Die letzten Teile davon führe ich über ein Bash-Skript namens "run-all.sh" aus, das ich über CMD in meinem Dockerfile ausführe. run-all.sh" sieht wie folgt aus:
service supervisor start
service nginx start
Und ich starte es innerhalb meines Dockerfiles wie folgt:
CMD ["sh", "/root/credentialize_and_run.sh"]
Ich kann sehen, dass die Dienste alle korrekt starten, wenn ich die Dinge manuell ausführe (d.h. wenn ich das Image mit -i -t /bin/bash aufrufe), und alles sieht so aus, als ob es korrekt läuft, wenn ich das Image ausführe, aber es beendet sich, sobald es mit dem Starten meiner Prozesse fertig ist. Ich möchte, dass die Prozesse auf unbestimmte Zeit laufen, und soweit ich weiß, muss der Container weiterlaufen, damit das passiert. Dennoch, wenn ich docker ps -a
ausführe, sehe ich:
➜ 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 ist los? Warum bricht es ab? Ich weiß, ich könnte einfach eine while-Schleife am Ende meines Bash-Skripts einfügen, um es aufrechtzuerhalten, aber was ist der richtige Weg, um es vom Beenden abzuhalten?
So sollten Sie Ihre Docker-Container eigentlich nicht gestalten.
Wenn Sie einen Docker-Container entwerfen, sollten Sie ihn so bauen, dass nur ein Prozess läuft (d.h. Sie sollten einen Container für Nginx haben und einen für supervisord oder die Anwendung, die er ausführt); außerdem sollte dieser Prozess im Vordergrund laufen.
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 wollen), sollten Sie in Erwägung ziehen, mit "Docker Base Image" zu starten, das runit
als Pseudo-Init-Prozess verwendet (runit
bleibt online, während Nginx und Supervisor laufen), der im Vordergrund bleibt, während Ihre anderen Prozesse ihr Ding machen.
Es gibt eine umfangreiche Dokumentation, so dass Sie in der Lage sein sollten, das zu erreichen, was Sie versuchen, relativ leicht zu tun.
Der Grund, warum es beendet wird, ist, weil das Shell-Skript zuerst als PID 1 ausgeführt wird und wenn das abgeschlossen ist, ist PID 1 weg, und Docker läuft nur, solange PID 1 ist.
Sie können supervisor verwenden, um alles zu tun, wenn es mit dem "-n" Flag ausgeführt wird, wird ihm gesagt, nicht zu daemonisieren, so dass es als erster Prozess bleiben wird:
CMD ["/usr/bin/supervisord", "-n"]
Und Ihre supervisord.conf:
[supervisord]
nodaemon=true
[program:startup]
priority=1
command=/root/credentialize_and_run.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=false
startsecs=0
[program:nginx]
priority=10
command=nginx -g "daemon off;"
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.log
autorestart=true
Dann können Sie so viele andere Prozesse haben, wie Sie wollen, und supervisor kümmert sich bei Bedarf um den Neustart dieser Prozesse.
Auf diese Weise können Sie supervisord in Fällen verwenden, in denen Sie nginx und php5-fpm benötigen und es nicht viel Sinn macht, sie getrennt zu betreiben.
Stellen Sie sicher, dass Sie daemon off;
zu Ihrer nginx.conf hinzufügen oder führen Sie es mit CMD ["nginx", "-g", "daemon off;"]
wie im offiziellen nginx-Image
Verwenden Sie dann Folgendes, um sowohl supervisor als Dienst als auch nginx als Vordergrundprozess laufen zu lassen, um zu verhindern, dass der Container beendet wird
service supervisor start && nginx`
In einigen Fällen werden Sie mehr als einen Prozess in Ihrem Container benötigen. Den Container zu zwingen, genau einen Prozess zu haben, wird nicht funktionieren und kann zu weiteren Problemen bei der Bereitstellung führen.
Sie müssen also die Kompromisse verstehen und Ihre Entscheidung entsprechend treffen.