hub - docker tutorial
El contenedor Docker se detendrá automáticamente después de "docker run-d" (14)
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, en
centos:latest
) sale inmediatamente (como lo hace bash cuando no está conectado a una terminal y no tiene nada que ejecutar).
Normalmente, cuando ejecuta un contenedor en modo daemon (con
-d
), el contenedor ejecuta algún tipo de proceso de daemon (como
httpd
).
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 de 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 con
docker 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 forma sencilla de mantener vivo un contenedor en modo demonio indefinidamente es ejecutar el modo de
sleep infinity
como 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 usar el
sleep
como 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 opción
-t
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 pasa
-i
).
De todos modos, esto también debería hacer el truco:
$ docker run -t -d centos:latest
No estoy 100% seguro de que
-t
produzca otras interacciones extrañas;
tal vez deje un comentario a continuación si lo hace.
Según el tutorial que leí hasta ahora, el uso de "
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 ejecuté "
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?
De acuerdo con
esta respuesta
, agregar el indicador
-t
evitará que el contenedor salga cuando se ejecute en segundo plano.
Luego puede usar
docker exec -i -t <image> /bin/bash
para 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".
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 hacer que otro CMD en primer plano se ejecute después , como
tail -f server.log
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
primer plano
(
-t
,
-i
o
-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.
Eso se informó inicialmente en la
kalyani-chaudhari
y se detalla en la
answer
de
jersey bean
.
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/git
no mantiene el proceso activo.
Tenía 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
, se recomienda usar-d
porque puede ejecutar su contenedor con solo un comando y no necesita separar la terminal del contenedor presionando Ctrl + P + Q.Sin embargo, hay un problema con la opción
-d
. 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
Un
docker ps
mostraría que el contenedor centos aún se está ejecutando.
Desde allí, puede
adjuntarlo o desconectarlo
(o
docker exec
algunos comandos).
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 hacer que
docker run -di image
.
Después de hacer
docker container ls
, lo verás ejecutándose.
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.
Hola, este problema se debe a que los contenedores 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á en ejecución su contenedor docker.
Háganos saber si estos dos casos funcionaron para usted para mantener su contenedor en funcionamiento.
Todo lo mejor
Lo he explicado en la siguiente publicación que tiene la misma pregunta.
¿Cómo retener el contenedor alpino docker después de usar la "salida"?
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 ejecutándose 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:
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.
Tal vez soy solo yo, pero en CentOS 7.3.1611 y Docker 1.12.6, pero terminé usando 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 agregando -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.
Tengo este fragmento de código ejecutado desde el
ENTRYPOINT
en 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
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
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