web-dev-qa-db-fra.com

Le conteneur Docker s'arrête automatiquement après "docker run -d"

Selon le tutoriel que j'ai lu jusqu'à présent, utilisez "docker run -d" pour démarrer un conteneur à partir de l'image et le conteneur s'exécutera en arrière-plan. Voici à quoi cela ressemble, nous pouvons voir que nous avons déjà un identifiant de conteneur.

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

Mais si j'ai exécuté "docker ps", rien n'a été renvoyé.

J'ai donc essayé "docker ps -a", je peux voir le conteneur déjà sorti:

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

Quelque chose que j'ai mal fait? Comment puis-je résoudre ce problème?

207
J John

Le centos dockerfile a une commande par défaut bash.

Cela signifie que, lorsqu'il est exécuté en arrière-plan (-d), le shell se ferme immédiatement.

Mise à jour 2017

Les versions plus récentes de docker autorisent l’exécution d’un conteneur à la fois en mode détaché et en mode avant-plan (-t, -i ou -it)

Dans ce cas, vous n'avez besoin d'aucune commande supplémentaire et cela suffit:

docker run -t -d centos

La bash attendra en arrière-plan.
Cela a été initialement signalé dans kalyani-chaudhari 's answer et détaillé dans jersey bean 's answer .

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

Notez que pour Alpine, Marinos Andans les commentaires :

docker run -t -d Alpine/git ne garde pas le processus.
Doit faire: docker run --entrypoint "/bin/sh" -it Alpine/git


Réponse originale (2015)

Comme mentionné dans cet article :

Au lieu d’exécuter avec docker run -i -t image your-command, il est recommandé d’utiliser -d car vous pouvez exécuter votre conteneur avec une seule commande sans avoir besoin de détacher le terminal du conteneur en appuyant sur Ctrl + P + Q.

Cependant, il existe un problème avec l'option -d. Votre conteneur s'arrête immédiatement sauf si les commandes ne sont pas exécutées au premier plan .
Docker a besoin de votre commande pour continuer à courir au premier plan. Sinon, vos applications s’arrêteront et arrêteront le conteneur.

Le problème est que certaines applications ne s'exécutent pas au premier plan. Comment pouvons-nous rendre les choses plus faciles?

Dans ce cas, vous pouvez ajouter tail -f /dev/null à votre commande.
Ce faisant, même si votre commande principale s’exécute en arrière-plan, votre conteneur ne s’arrête pas, car tail continue à s’exécuter au premier plan.

Donc, cela fonctionnerait:

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

Un docker ps indiquerait que le conteneur centos est toujours en cours d'exécution.

De là, vous pouvez y attacher ou en détacher (ou docker exec certaines commandes).

382
VonC

Selon cette réponse , l'ajout de l'indicateur -t empêchera le conteneur de se fermer lorsqu'il est exécuté en arrière-plan. Vous pouvez ensuite utiliser docker exec -i -t <image> /bin/bash pour accéder à une invite du shell.

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

Il semble que l'option -t n'est pas très bien documentée , même si l'aide indique qu'elle "alloue un pseudo-TTY".

46
cjsimon

Contexte

Un conteneur Docker exécute un processus (la "commande" ou "entrypoint") qui le maintient en vie. Le conteneur continuera à s'exécuter tant que la commande continue de s'exécuter.

Dans votre cas, la commande (/bin/bash, par défaut, sur centos:latest) se ferme immédiatement (comme le fait bash quand il n'est pas connecté à un terminal et qu'il n'a rien à exécuter).

Normalement, lorsque vous exécutez un conteneur en mode démon (avec -d), le conteneur exécute une sorte de processus démon (comme httpd). Dans ce cas, tant que le démon httpd est en cours d'exécution, le conteneur reste actif.

Ce que vous semblez essayer de faire est de garder le conteneur en vie sans qu'un processus démon ne s'exécute à l'intérieur du conteneur. C'est un peu étrange (car le conteneur ne sert à rien tant que vous n'interagissez pas avec lui, peut-être avec docker exec), mais dans certains cas, il peut être judicieux de procéder de la sorte.

(Vouliez-vous vous rendre à l'invite bash à l'intérieur du conteneur? C'est facile! docker run -it centos:latest)

Solution

Un moyen simple de garder un conteneur actif en mode démon indéfiniment consiste à exécuter sleep infinity en tant que commande du conteneur. Cela ne consiste pas à faire des choses étranges, comme allouer un TTY en mode démon. Bien que cela repose sur des choses étranges, comme utiliser sleep comme commande principale.

$ 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

Solution alternative

Comme indiqué par cjsimon, l'option -t attribue un "pseudo-tty". Cette astuce consiste à continuer à fonctionner indéfiniment, car elle pense être connectée à un téléscripteur interactif (même si vous n'avez aucun moyen d'interagir avec ce téléscripteur particulier si vous ne passez pas -i). Quoi qu'il en soit, cela devrait faire l'affaire aussi:

$ docker run -t -d centos:latest

Pas tout à fait sûr que -t produira d’autres interactions étranges; peut-être laisser un commentaire ci-dessous si c'est le cas.

22
mkasberg

Bonjour, Ce problème est dû au fait que les conteneurs Docker se terminent s'il n'y a aucune application en cours d'exécution dans le conteneur.

-d 

l’option est juste d’exécuter un conteneur en mode démon.

Donc, le truc pour rendre votre conteneur continuellement actif est de pointer sur un fichier Shell dans docker qui gardera votre application en marche. Vous pouvez essayer avec un fichier start.sh.

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

Ce fichier start.sh devrait pointer vers une application sans fin.

Si vous ne voulez pas qu'une application soit en cours d'exécution, vous pouvez installer monit qui gardera votre conteneur docker en cours d'exécution . Merci de nous indiquer si ces deux cas ont fonctionné pour que votre conteneur reste actif.

Bonne chance

14
Pratik

Vous pouvez accomplir ce que vous voulez avec:

docker run -t -d <image-name>

ou

docker run -i -d <image-name>

ou

docker run -it -d <image-name>

Le paramètre de commande suggéré par d’autres réponses (par exemple, tail -f/dev/null) est complètement facultatif et n’EST PAS requis pour que votre conteneur continue de fonctionner en arrière-plan. 

Notez également que la documentation de Docker suggère que la combinaison des options -i et -t le fera se comporter comme un shell.

Voir:

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

7
jersey bean

exécuter la commande comme suit:

docker run -t -d <image-name>

si vous voulez spécifier le port, alors commande comme ci-dessous:

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

vérifiez le conteneur en cours d'exécution à l'aide de la commande suivante:

docker ps
6

Docker a besoin de votre commande pour continuer à courir au premier plan. Sinon, vos applications s’arrêteront et arrêteront le conteneur.

Donc, si votre script d'entrée docker est un processus en arrière-plan comme suit:

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

Le '&' force le conteneur à s'arrêter et à sortir s'il n'y a pas d'autre processus de premier plan déclenché ultérieurement. Donc, la solution est simplement supprimez le '&' ou laissez un autre CMD d’avant-plan le suivre , tel que

tail -f server.log
4
Peiming Hu

Peut-être que c'est juste moi, mais sur CentOS 7.3.1611 et Docker 1.12.6, mais j'ai finalement dû utiliser une combinaison des réponses postées par @VonC & @Christopher Simon pour que cela fonctionne de manière fiable. Rien de ce que je faisais auparavant n'empêcherait le conteneur de quitter après avoir exécuté CMD avec succès. Je commence Oracle-xe-11Gr2 et 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

Puis en ajoutant -d -t et -i pour lancer

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 

Enfin, après des heures passées à me cogner la tête contre le mur

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

Pour une raison quelconque, ce qui précède se fermera après l'exécution de CMD si la queue -f est supprimée ou si l'une des options -t -d -i est omise.

1
steven87vt

J'ai eu le même problème, juste ouvrir un autre terminal avec une bash ça a fonctionné pour moi:

créer un conteneur:

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

commencer le conteneur:

docker start 52bbc9b30557

lancez bash pour que le conteneur continue de fonctionner:

docker exec -it 52bbc9b30557 bash

processus de démarrage dont vous avez besoin:

docker exec -it 52bbc9b30557 /path_to_cool_your_app
1
Steef

J'ai l'extrait de code exécuté à partir de la variable ENTRYPOINT dans mon fichier de menu fixe:

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

Exécutez l'image du menu fixe intégré en tant que:

docker run -td <image name>

Connectez-vous au conteneur Shell:

docker exec -it <container id> /bin/bash
0
Binita Bharati

Si vous utilisez CMD à la fin de votre fichier Docker, vous pouvez simplement ajouter le code à la fin. Cela ne fonctionnera que si votre menu fixe est construit sur Ubuntu ou sur tout système d'exploitation pouvant utiliser bash.

&& /bin/bash

En bref, la fin de votre fichier Dockerfile ressemblera à quelque chose comme ça.

...

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

Donc, si quelque chose tourne automatiquement après avoir exécuté votre image de menu fixe, et lorsque la tâche est terminée, le terminal bash sera actif dans votre menu fixe. Ainsi, vous pouvez entrer vos commandes Shell.

0
Ekin

Je l'ai expliqué dans le post suivant qui a la même question.

Comment conserver le conteneur Alpine docker après l'utilisation de "exit"?

0
vimal krishna