Der Docker-Container stoppt automatisch nach "Docker-Lauf -d".

333

Laut dem Tutorial, das ich bisher gelesen habe, docker run -dstartet " " einen Container aus dem Image und der Container wird im Hintergrund ausgeführt. So sieht es aus, wir können sehen, dass wir bereits eine Container-ID haben.

root@docker:/home/root# docker run -d centos
605e3928cdddb844526bab691af51d0c9262e0a1fc3d41de3f59be1a58e1bd1d

Aber wenn ich " docker ps" lief , wurde nichts zurückgegeben.

Also habe ich versucht " docker ps -a", ich kann sehen, Container bereits verlassen:

root@docker:/home/root# docker ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                         PORTS               NAMES
605e3928cddd        centos:latest         "/bin/bash"         31 minutes ago      Exited (0) 31 minutes ago                          kickass_swartz

Was habe ich falsch gemacht? Wie kann ich dieses Problem beheben?

J John
quelle
1
"docker run hello-world" <== funktioniert einwandfrei, aber wenn ich "docker run -d hello-world" ausführe, kann ich immer noch keinen laufenden Container bekommen.
J John
5
Ich hatte ein ähnliches Problem, aber ich habe es zum Laufen gebracht, indem ich docker run -it -d <image> /bin/basheine Bash-Shell interaktiv gestartet und den Container nicht geschlossen habe, weil der Shell-Prozess aktiv ist.
Rtsne42

Antworten:

494

Die Docker-Datei centos verfügt über einen Standardbefehl bash.

Das heißt, wenn -ddie Shell im Hintergrund ( ) ausgeführt wird, wird sie sofort beendet.

Update 2017

Neuere Versionen von Docker berechtigen zum Ausführen eines Containers sowohl im getrennten Modus als auch im Vordergrundmodus ( -t, -ioder -it).

In diesem Fall benötigen Sie keinen zusätzlichen Befehl und dies reicht aus:

docker run -t -d centos

Die Bash wartet im Hintergrund.
Das war zunächst in berichtet kalyani-Chaudhari 's Antwort und detailliert in Jersey Bean ' s Antwort .

vonc@voncvb:~$ d ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
4a50fd9e9189        centos              "/bin/bash"         8 seconds ago       Up 2 seconds                            wonderful_wright

Beachten Sie, dass für alpine , Marinos Ein berichtet in den Kommentaren :

docker run -t -d alpine/githält den Prozess nicht aufrecht.
Musste tun:docker run --entrypoint "/bin/sh" -it alpine/git


Ursprüngliche Antwort (2015)

Wie in diesem Artikel erwähnt :

Anstatt mit zu laufen docker run -i -t image your-command, wird die Verwendung von -dempfohlen, da Sie Ihren Container mit nur einem Befehl ausführen können und das Terminal des Containers nicht durch Drücken von Ctrl+ P+ trennen müssen Q.

Es gibt jedoch ein Problem mit der -dOption. Ihr Container stoppt sofort, es sei denn, die Befehle werden nicht im Vordergrund ausgeführt .
Docker erfordert, dass Ihr Befehl weiterhin im Vordergrund ausgeführt wird. Andernfalls wird angenommen, dass Ihre Anwendungen den Container stoppen und herunterfahren.

Das Problem ist, dass einige Anwendungen nicht im Vordergrund ausgeführt werden. Wie können wir es einfacher machen?

In dieser Situation können Sie tail -f /dev/nullIhrem Befehl hinzufügen .
Selbst wenn Ihr Hauptbefehl im Hintergrund ausgeführt wird, stoppt Ihr Container auf diese Weise nicht, da der Schwanz weiterhin im Vordergrund ausgeführt wird.

Das würde also funktionieren:

docker run -d centos tail -f /dev/null

A docker pswürde zeigen, dass der Centos-Container noch läuft.

Von dort aus können Sie es anhängen oder von ihm trennen (oder docker execeinige Befehle).

VonC
quelle
Entschuldigung, noch eine Frage, ich muss ein Skript beim Start ausführen. Es sieht so aus, als ob /etc/rc.d/rc.local nicht mehr funktioniert (meine Denkweise behandelt Docker immer noch wie ein Betriebssystem). Ich gehe davon aus, dass Docker-Datei die bessere Option ist Fall?
J John
5
@ GuruprasadGV Das wird erwartet. Verwenden Sie anstelle von Docker Attach docker exec -it <yourContainer> bash.
VonC
3
Dies funktioniert auch, wenn Sie den Befehl tail am Ende einer Einstiegspunktdatei hinzufügen.
Yara
2
Ich habe sshd als meinen letzten (lang laufenden) Befehl verwendet. Sie können dann auch Ihren Container wie auf einer VM ssh (sobald Sie .ssh / authorized_keys usw. festgelegt haben) ... Sie können den Container auch mit ansible konfigurieren.
Andrew Pate
1
Am Ende habe ich dies getan, um meinen Befehl und den oben aufgeführten älteren Fix auszuführen: docker run image_name / bin / bash -c "mein / Befehl && tail -f / dev / null"
Geordie
58

Nach dieser Antwort-t verhindert das Hinzufügen des Flags, dass der Container beim Ausführen im Hintergrund beendet wird. Sie können dann verwenden docker exec -i -t <image> /bin/bash, um in eine Shell-Eingabeaufforderung zu gelangen.

docker run -t -d <image> <command>

Es scheint, dass die Option -t nicht sehr gut dokumentiert ist , obwohl die Hilfe besagt, dass sie "eine Pseudo-TTY zuweist".

cjsimon
quelle
10
Nett. Scheint weniger hacky als anhängentail -f /dev/null
Scarysize
Vielen Dank! Bei der geringen Chance, dass dies jemandem hilft, verhält sich dies in Emacs Eshell nicht gut.
Peter Becich
2
docker run -t -d --name mysql -p 3306:3306 mysql- funktioniert nicht für mich (Ubuntu 14.04.5): STATUS = Beendet (1) vor 4 Sekunden
Putnik
Ich habe festgestellt, dass Sie hier keinen <Befehl> benötigen, es sei denn, Sie möchten. Seltsamerweise funktioniert es auch, -t durch -i (interaktiv) zu ersetzen. Das Dokument erwähnt, dass die Kombination von -t und -i sich wie eine Shell verhält.
Jersey Bean
43

Hintergrund

Ein Docker-Container führt einen Prozess aus (den "Befehl" oder "Einstiegspunkt"), der ihn am Leben erhält. Der Container wird so lange ausgeführt, wie der Befehl ausgeführt wird.

In Ihrem Fall wird der Befehl ( /bin/bashstandardmäßig aktiviert centos:latest) sofort beendet (wie Bash, wenn er nicht mit einem Terminal verbunden ist und nichts auszuführen ist).

Wenn Sie einen Container im Daemon-Modus (mit -d) ausführen , führt der Container normalerweise eine Art Daemon-Prozess aus (wie httpd). In diesem Fall bleibt der Container am Leben, solange der httpd-Dämon ausgeführt wird.

Sie versuchen anscheinend, den Container am Leben zu erhalten, ohne dass ein Dämonprozess im Container ausgeführt wird. Dies ist etwas seltsam (weil der Container nichts Nützliches tut, bis Sie mit ihm interagieren, vielleicht mit docker exec), aber es gibt bestimmte Fälle, in denen es sinnvoll sein könnte, so etwas zu tun.

(Wollten Sie zu einer Bash-Eingabeaufforderung im Container gelangen? Das ist einfach! docker run -it centos:latest)

Lösung

Eine einfache Möglichkeit, einen Container im Dämonmodus unbegrenzt am Leben zu halten, besteht darin, ihn sleep infinityals Befehl des Containers auszuführen . Dies setzt nicht voraus, dass seltsame Dinge wie das Zuweisen eines TTY im Daemon-Modus ausgeführt werden. Obwohl es darauf ankommt, seltsame Dinge zu tun, wie die Verwendung sleepals primärer Befehl.

$ docker run -d centos:latest sleep infinity
$ docker ps
CONTAINER ID  IMAGE         COMMAND          CREATED       STATUS       PORTS NAMES
d651c7a9e0ad  centos:latest "sleep infinity" 2 seconds ago Up 2 seconds       nervous_visvesvaraya

Alternative Lösung

Wie von cjsimon angegeben, weist die -tOption eine "Pseudo-tty" zu. Diese Tricks führen dazu, dass die Ausführung auf unbestimmte Zeit fortgesetzt wird, da angenommen wird, dass sie mit einem interaktiven TTY verbunden ist (obwohl Sie keine Möglichkeit haben, mit diesem bestimmten TTY zu interagieren, wenn Sie nicht bestehen -i). Auf jeden Fall sollte dies auch den Trick tun:

$ docker run -t -d centos:latest

Nicht 100% sicher, ob -tandere seltsame Interaktionen hervorgerufen werden; Vielleicht hinterlassen Sie unten einen Kommentar, wenn dies der Fall ist.

mkasberg
quelle
Beachten Sie, dass dies auf alpinen Gebieten nicht funktioniert, da der Schlaf von BusyBox dies nicht akzeptiert infinity.
John Kugelman
Dies hat mir bei der Fehlerbehebung bei einem Amazon-Linux-Image geholfen. Vielen Dank
einflussreich
18

Hallo, dieses Problem liegt daran, dass Docker-Container beendet werden, wenn im Container keine Anwendung ausgeführt wird.

-d 

Option ist nur, einen Container im Deamon-Modus auszuführen.

Der Trick, um Ihren Container kontinuierlich auszuführen, besteht darin, auf eine Shell-Datei im Docker zu verweisen, die Ihre Anwendung am Laufen hält. Sie können es mit einer start.sh-Datei versuchen

Eg: docker run -d centos sh /yourlocation/start.sh

Diese start.sh sollte auf eine nie endende Anwendung verweisen.

Falls Sie nicht möchten, dass eine Anwendung ausgeführt wird, können Sie eine Installation installieren, monitdie Ihren Docker-Container am Laufen hält. Bitte lassen Sie uns wissen, ob diese beiden Fälle für Sie funktioniert haben, um Ihren Container am Laufen zu halten.

Alles Gute

Pratik
quelle
12

Sie können erreichen, was Sie wollen:

docker run -t -d <image-name>

oder

docker run -i -d <image-name>

oder

docker run -it -d <image-name>

Der von anderen Antworten vorgeschlagene Befehlsparameter (z. B. tail -f / dev / null) ist vollständig optional und NICHT erforderlich, damit Ihr Container im Hintergrund ausgeführt wird.

Beachten Sie auch, dass in der Docker-Dokumentation vorgeschlagen wird, dass das Kombinieren der Optionen -i und -t dazu führt, dass es sich wie eine Shell verhält.

Sehen:

https://docs.docker.com/engine/reference/run/#foreground

Jersey Bohne
quelle
9

Ich habe dieses Code-Snippet aus dem ENTRYPOINTin meiner Docker-Datei ausgeführt:

while true
do
    echo "Press [CTRL+C] to stop.."
    sleep 1
done

Führen Sie das erstellte Docker-Image wie folgt aus:

docker run -td <image name>

Melden Sie sich bei der Container-Shell an:

docker exec -it <container id> /bin/bash
Binita Bharati
quelle
Ist dies die Lösung, für die Sie eine Endlosschleife erstellt haben? : D
Muhammad SaLman
8

Führen Sie den Befehl wie folgt aus:

docker run -t -d <image-name>

Wenn Sie den Port angeben möchten, geben Sie den folgenden Befehl ein:

docker run -t -d -p <port-no> <image-name>

Überprüfen Sie den laufenden Container mit dem folgenden Befehl:

docker ps
kalyani chaudhari
quelle
Ich mag diese Antwort am liebsten, weil die beliebteste Antwort darauf hindeutet, dass Sie einen Befehl benötigen (dh tail -f / dev / null). Der Befehl ist völlig optional. Der Schlüssel hier ist, -t zu verwenden. Ich habe auch festgestellt, dass -i anstelle von -t funktioniert, oder Sie können auch beide -it kombiniert verwenden (wie aus der Dokumentation hervorgeht, wird es als Shell ausgeführt).
Jersey Bean
Gibt es einen Vorteil von -t -dvs -i -d? Beides hält den Container am Laufen.
wisbucky
5

Docker erfordert, dass Ihr Befehl weiterhin im Vordergrund ausgeführt wird. Andernfalls wird angenommen, dass Ihre Anwendungen den Container stoppen und herunterfahren.

Wenn es sich bei Ihrem Docker-Eingabeskript also um einen Hintergrundprozess wie den folgenden handelt:

/usr/local/bin/confd -interval=30 -backend etcd -node $CONFIG_CENTER &

Das '&' bewirkt, dass der Container stoppt und beendet wird, wenn später kein anderer Vordergrundprozess ausgelöst wird. Die Lösung besteht also darin, einfach das '&' zu entfernen oder ein anderes CMD im Vordergrund zu verwenden , z

tail -f server.log
Peiming Hu
quelle
Vielleicht möchten Sie zuerst touchdiese Datei, falls Sie keine Protokolldatei finden konnten.
Samuel Elh
Normalerweise handelt es sich bei der Protokolldatei I Tail um das aktuelle Serverprotokoll oder die aktuelle Umleitungsausgabe, die bereits nach dem Start des Prozesses vorhanden sein sollte.
Peiming Hu
4

Der Docker-Container wird beendet, wenn die darin enthaltene Aufgabe erledigt ist. Wenn Sie ihn also am Leben erhalten möchten, auch wenn er keinen Job hat oder bereits erledigt ist, können Sie dies tun docker run -di image. Nachdem Sie dies getan haben, werden docker container lsSie sehen, wie es läuft.

Vrangz
quelle
3

Vielleicht bin ich es nur, aber unter CentOS 7.3.1611 und Docker 1.12.6 musste ich eine Kombination der Antworten von @VonC & @Christopher Simon verwenden, damit dies zuverlässig funktioniert. Nichts, was ich zuvor getan habe, würde das Beenden des Containers verhindern, nachdem CMD erfolgreich ausgeführt wurde. Ich starte oracle-xe-11Gr2 und sshd.

Dockerfile

...
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && systemctl enable sshd
...
CMD /etc/init.d/oracle-xe start && /sbin/sshd && tail -f /dev/null

Fügen Sie dann -d -t und -i hinzu, um auszuführen

docker run --shm-size=2g --name oracle-db -d -t -i -p 5022:22 -p 5080:8080 -p 1521:1521 centos-oracle:7.3.1611 

Endlich, nachdem ich stundenlang meinen Kopf gegen die Wand geschlagen hatte

ssh -v [email protected] -p 5022
...
[email protected]'s password: 
debug1: Authentication succeeded (password).

Aus irgendeinem Grund wird das Obige nach dem Ausführen von CMD beendet, wenn das Ende -f entfernt wird oder eine der Optionen -t -d -i weggelassen wird.

steven87vt
quelle
1

Ich hatte das gleiche Problem, nur ein anderes Terminal mit einem Schlag darauf zu öffnen, funktionierte für mich:

Container erstellen:

docker run -d mcr.microsoft.com/mssql/server:2019-CTP3.0-ubuntu
containerid=52bbc9b30557

Container starten:

docker start 52bbc9b30557

Starten Sie die Bash, um den Container am Laufen zu halten:

docker exec -it 52bbc9b30557 bash

Starten Sie den Prozess, den Sie benötigen:

docker exec -it 52bbc9b30557 /path_to_cool_your_app
Steef
quelle
1

Wenn Sie CMD am Ende Ihrer Docker-Datei verwenden, können Sie den Code am Ende hinzufügen. Dies funktioniert nur, wenn Ihr Docker auf Ubuntu oder einem anderen Betriebssystem basiert, das Bash verwenden kann.

&& /bin/bash

Kurz gesagt, das Ende Ihrer Docker-Datei sieht ungefähr so ​​aus.

...

CMD ls && ... && /bin/bash

Wenn also nach dem Ausführen Ihres Docker-Images automatisch etwas ausgeführt wird und die Aufgabe abgeschlossen ist, ist das Bash-Terminal in Ihrem Docker aktiv. Dabei können Sie Ihre Shell-Befehle eingeben.

Ekin
quelle
1

Das Ausführen von Docker im interaktiven Modus kann das Problem beheben.

Hier ist das Beispiel für das Ausführen von Bildern mit und ohne interaktiven Modus

chaitra @ RSK-IND-BLR-L06: ~ / Docker $ sudo docker run -d -t -i test_again1.0 b6b9a942a79b1243bada59db19c7999cfff52d0a8744542fa843c95354966a18

chaitra @ RSK-IND-BLR-L06: ~ / dockers $ sudo docker ps

BEHÄLTER-ID BILDBEFEHL ERSTELLTE STATUS-PORTS-NAMEN

chaitra @ RSK-IND-BLR-L06: ~ / dockers $ sudo docker run -d -t -i test_again1.0 bash c3d6a9529fd70c5b2dc2d7e90fe662d19c6dad8549e9c812fb2b7ce2105d7ff5

chaitra @ RSK-IND-BLR-L06: ~ / dockers $ sudo docker ps

CONTAINER ID IMAGE COMMAND ERSTELLTER STATUS PORTS NAMES c3d6a9529fd7 test_again1.0 "bash" vor 2 Sekunden Up 1 Sekunde awesome_haibt

Chaitra
quelle
0

Wenn Sie den Container bearbeiten möchten, müssen Sie ihn im Vordergrund ausführen, um ihn am Leben zu erhalten.

lwpro2
quelle
-1

Die Reihenfolge der Argumente ist wichtig

Die Antwort von Jersey Beans (alle 3 Beispiele) hat bei mir funktioniert. Nach einigem Ausprobieren wurde mir klar, dass die Reihenfolge der Argumente wichtig ist.

Lässt den Container im Hintergrund laufen: docker run -t -d <image-name>

Lässt den Container im Vordergrund laufen: docker run <image-name> -t -d

Es war mir nicht klar, ob ich einen Powershell-Hintergrund hatte.

HVL71
quelle