El contenedor Docker se detendrá automáticamente después de "docker run -d"

333

De acuerdo con el tutorial que leí hasta ahora, el uso " docker run -d" iniciará un contenedor desde la imagen y el contenedor se ejecutará en segundo plano. Así es como se ve, podemos ver que ya tenemos la identificación del contenedor.

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

Pero si corrí " docker ps", no se devolvió nada.

Así que probé " docker ps -a", puedo ver que el contenedor ya salió:

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

¿Algo que hice mal? ¿Cómo puedo solucionar este problema?

J John
fuente
1
"docker run hello-world" <== funciona perfectamente, pero si ejecuto "docker run -d hello-world", todavía no puedo obtener un contenedor en ejecución.
J John
55
Tuve un problema similar pero lo puse a funcionar al usar docker run -it -d <image> /bin/bashesto inicia un shell bash de forma interactiva y no cierra el contenedor porque el proceso del shell está activo.
Rtsne42

Respuestas:

495

El centos dockerfile tiene un comando predeterminado bash.

Eso significa que, cuando se ejecuta en segundo plano ( -d), el shell sale inmediatamente.

Actualización 2017

Las versiones más recientes de Docker autorizan a ejecutar un contenedor tanto en modo separado como en modo de primer plano ( -t, -io -it)

En ese caso, no necesita ningún comando adicional y esto es suficiente:

docker run -t -d centos

La fiesta esperará en el fondo.
Que se informó inicialmente en kalyani-chaudhari 's respuesta y detallados en frijol maillot ' s respuesta .

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

Tenga en cuenta que para alpine , Marinos An informa en los comentarios :

docker run -t -d alpine/gitNo mantiene el proceso.
Tuve que hacer:docker run --entrypoint "/bin/sh" -it alpine/git


Respuesta original (2015)

Como se menciona en este artículo :

En lugar de ejecutar con docker run -i -t image your-command, -dse recomienda usar porque puede ejecutar su contenedor con solo un comando y no necesita desconectar la terminal del contenedor presionandoCtrl + P+ Q.

Sin embargo, hay un problema con -d opción. Su contenedor se detiene inmediatamente a menos que los comandos no se ejecuten en primer plano .
Docker requiere su comando para seguir ejecutándose en primer plano. De lo contrario, cree que sus aplicaciones se detienen y apagan el contenedor.

El problema es que algunas aplicaciones no se ejecutan en primer plano. ¿Cómo podemos hacerlo más fácil?

En esta situación, puede agregar tail -f /dev/null a su comando.
Al hacer esto, incluso si su comando principal se ejecuta en segundo plano, su contenedor no se detiene porque la cola sigue ejecutándose en primer plano.

Entonces esto funcionaría:

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

UNA docker ps mostraría que el contenedor de centos sigue funcionando.

Desde allí, puede adjuntarlo o desconectarlo (o docker execalgunos comandos).

VonC
fuente
Lo siento, una pregunta más, tengo que ejecutar un script al inicio, parece que /etc/rc.d/rc.local ya no funciona (mi mentalidad todavía trata a Docker como SO), supongo que el archivo Docker es una mejor opción en este ¿caso?
J John
55
@GuruprasadGV Eso se espera. En lugar de usar docker attach, use docker exec -it <yourContainer> bash.
VonC
3
Esto también funciona si agrega el comando de cola al final de un archivo de punto de entrada.
yara
2
Usé sshd como mi último comando (de larga ejecución). Luego puede ssh también en su contenedor como lo haría en una VM (una vez que configure .ssh / Authorizedkeys, etc.) ... También puede continuar para configurar el contenedor usando ansible.
Andrew Paté
1
Terminé haciendo esto para ejecutar mi comando más la corrección anterior enumerada anteriormente: docker run image_name / bin / bash -c "my / command && tail -f / dev / null"
Geordie
58

Según esta respuesta , agregar la -tbandera evitará que el contenedor salga cuando se ejecute en segundo plano. Luego puede usar docker exec -i -t <image> /bin/bashpara ingresar a un indicador de comandos de shell.

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

Parece que la opción -t no está muy bien documentada , aunque la ayuda dice que "asigna un pseudo-TTY".

cjsimon
fuente
10
Agradable. Parece menos hacky que tail -f /dev/null
agregar
¡Gracias! En la pequeña posibilidad de que esto ayude a alguien, esto no se comporta bien en Emacs Eshell.
Peter Becich 01 de
2
docker run -t -d --name mysql -p 3306:3306 mysql- no funciona para mí (ubuntu 14.04.5): ESTADO = Salido (1) hace 4 segundos
Putnik
Descubrí que no necesitas <comando> aquí, a menos que quieras. Curiosamente, también funciona para reemplazar -t con -i (interactivo). El documento menciona que usar -t -i combinado se comportará como un shell.
jersey bean
44

Antecedentes

Un contenedor Docker ejecuta un proceso (el "comando" o "punto de entrada") que lo mantiene vivo. El contenedor continuará ejecutándose mientras el comando continúe ejecutándose.

En su caso, el comando ( /bin/bash, por defecto, encentos:latest ) sale inmediatamente (como lo hace bash cuando no está conectado a un terminal y no tiene nada que ejecutar).

Normalmente, cuando ejecuta un contenedor en modo demonio (con -d), el contenedor ejecuta algún tipo de proceso de demonio (comohttpd ). En este caso, mientras el demonio httpd se esté ejecutando, el contenedor permanecerá vivo.

Lo que parece estar intentando hacer es mantener vivo el contenedor sin que se ejecute un proceso demonio dentro del contenedor. Esto es algo extraño (porque el contenedor no está haciendo nada útil hasta que interactúa con él, tal vez condocker exec ), pero hay ciertos casos en los que podría tener sentido hacer algo como esto.

(¿Querías llegar a un aviso de bash dentro del contenedor? ¡Eso es fácil! docker run -it centos:latest )

Solución

Una manera simple de mantener un contenedor vivo en modo demonio indefinidamente es ejecutarlo sleep infinitycomo el comando del contenedor. Esto no depende de hacer cosas extrañas como asignar un TTY en modo demonio. Aunque se basa en hacer cosas extrañas como usarlo sleepcomo su comando principal.

$ 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

Solución alternativa

Como lo indica cjsimon, la -topción asigna un "pseudo-tty". Estos trucos hacen que continúe ejecutándose indefinidamente porque cree que está conectado a un TTY interactivo (aunque no tenga forma de interactuar con ese TTY en particular si no lo aprueba -i). De todos modos, esto también debería hacer el truco:

$ docker run -t -d centos:latest

No estoy 100% seguro de si -tproducirá otras interacciones extrañas; tal vez deje un comentario a continuación si lo hace.

mkasberg
fuente
Tenga en cuenta que esto no funciona en alpino ya que el sueño de BusyBox no acepta infinity.
John Kugelman el
Esto me ayudó a solucionar una imagen de Amazon-Linux, gracias
influyente
18

Hola, este problema se debe a que los contenedores de Docker salen si no hay una aplicación en ejecución en el contenedor.

-d 

La opción es simplemente ejecutar un contenedor en modo deamon.

Entonces, el truco para hacer que su contenedor se ejecute continuamente es apuntar a un archivo de shell en Docker que mantendrá su aplicación en funcionamiento. Puede intentar con un archivo start.sh

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

Este start.sh debería apuntar a una aplicación interminable.

En caso de que no desee que se ejecute ninguna aplicación, puede instalar monit que mantendrá su contenedor Docker en ejecución. Háganos saber si estos dos casos funcionaron para usted para mantener su contenedor en funcionamiento.

Todo lo mejor

Pratik
fuente
12

Puedes lograr lo que quieres con:

docker run -t -d <image-name>

o

docker run -i -d <image-name>

o

docker run -it -d <image-name>

El parámetro de comando sugerido por otras respuestas (es decir, tail -f / dev / null) es completamente opcional y NO es necesario para que su contenedor permanezca funcionando en segundo plano.

También tenga en cuenta que la documentación de Docker sugiere que la combinación de las opciones -i y -t hará que se comporte como un shell.

Ver:

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

frijol jersey
fuente
9

Tengo este fragmento de código ejecutado ENTRYPOINTen mi archivo acoplable:

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

Ejecute la imagen incorporada del acoplador como:

docker run -td <image name>

Inicie sesión en el shell del contenedor:

docker exec -it <container id> /bin/bash
Binita Bharati
fuente
¿Es esta la solución que has creado para este bucle infinito? : D
Muhammad SaLman
8

ejecutar el comando de la siguiente manera:

docker run -t -d <image-name>

si desea especificar el puerto, entonces comience de la siguiente manera:

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

Verifique el contenedor en ejecución con el siguiente comando:

docker ps
kalyani chaudhari
fuente
En realidad, me gusta esta respuesta, porque la respuesta más popular sugiere que necesita un comando (es decir, tail -f / dev / null). El comando es completamente opcional. La clave aquí es usar -t. También encontré que -i funciona en lugar de -t, o también puede usar ambos -it combinados (como la documentación sugiere que se ejecutará como un shell).
jersey bean
¿Hay alguna ventaja de usar -t -dvs -i -d? Ambos mantendrán el contenedor en funcionamiento.
wisbucky
5

Docker requiere su comando para seguir ejecutándose en primer plano. De lo contrario, cree que sus aplicaciones se detienen y apagan el contenedor.

Entonces, si su script de entrada de Docker es un proceso en segundo plano como el siguiente:

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

El '&' hace que el contenedor se detenga y salga si no hay otro proceso de primer plano activado más tarde. Entonces, la solución es simplemente eliminar el '&' o tener otro CMD en primer plano ejecutándose después , como

tail -f server.log
Peiming Hu
fuente
Es posible que desee touchese archivo primero, en caso de que no pueda encontrar un archivo de registro.
Samuel Elh
Por lo general, el archivo de registro que sigo es el registro actual del servidor o la salida de redirección, que ya debería estar allí después de que se inicie el proceso.
Peiming Hu
4

El contenedor Docker se cierra si se realiza la tarea en el interior, por lo que si desea mantenerlo vivo incluso si no tiene ningún trabajo o ya los terminó, puede hacerlo docker run -di image. Después de que lo hagasdocker container ls , lo verás en ejecución.

Vrangz
fuente
3

Tal vez soy solo yo, pero en CentOS 7.3.1611 y Docker 1.12.6, pero terminé teniendo que usar una combinación de las respuestas publicadas por @VonC y @Christopher Simon para que esto funcione de manera confiable. Nada de lo que hice antes impedirá que el contenedor salga después de ejecutar CMD con éxito. Estoy iniciando oracle-xe-11Gr2 y 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

Luego agregue -d -t y -i para ejecutar

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 

Finalmente después de horas de golpear mi cabeza contra la pared

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

Por alguna razón, lo anterior se cerrará después de ejecutar CMD si se elimina la cola -f, o si se omite cualquiera de las opciones -t -d -i.

steven87vt
fuente
1

Tuve el mismo problema, solo abrir otra terminal con un golpe me funcionó:

crear contenedor:

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

iniciar contenedor:

docker start 52bbc9b30557

iniciar bash para mantener el contenedor en funcionamiento:

docker exec -it 52bbc9b30557 bash

proceso de inicio que necesita:

docker exec -it 52bbc9b30557 /path_to_cool_your_app
Steef
fuente
1

Si está utilizando CMD al final de su Dockerfile, lo que puede hacer es agregar el código al final. Esto solo funcionará si su docker está construido en ubuntu o en cualquier sistema operativo que pueda usar bash.

&& /bin/bash

Brevemente, el final de su Dockerfile se verá así.

...

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

Entonces, si tiene algo ejecutándose automáticamente después de ejecutar la imagen de su ventana acoplable, y cuando se complete la tarea, el terminal bash estará activo dentro de su ventana acoplable. De este modo, puede ingresar sus comandos de shell.

Ekin
fuente
1

Ejecutar Docker con modo interactivo podría resolver el problema.

Aquí está el ejemplo para ejecutar imágenes con y sin modo interactivo

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

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

ID DE CONTENEDOR MANDO DE IMAGEN ESTADO CREADO NOMBRES DE PUERTOS

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

ID DE CONTENEDOR MANDO DE IMAGEN ESTADO CREADO PUERTOS NOMBRES c3d6a9529fd7 test_again1.0 "bash" hace 2 segundos Subir 1 segundo awesome_haibt

Chaitra
fuente
0

Si desea operar en el contenedor, debe ejecutarlo en primer plano para mantenerlo vivo.

lwpro2
fuente
-1

El orden de los argumentos es importante

La respuesta de Jersey Beans (los 3 ejemplos) funcionó para mí. Después de bastante prueba y error, me di cuenta de que el orden de los argumentos es importante.

Mantiene el contenedor ejecutándose en segundo plano: docker run -t -d <image-name>

Mantiene el contenedor ejecutándose en primer plano: docker run <image-name> -t -d

No era obvio para mí venir de un fondo Powershell.

HVL71
fuente