imagenes - download docker image
¿Cómo mantener el contenedor Docker ejecutándose después de iniciar los servicios? (9)
¿Qué tal usar la forma de servicio supervisar si está disponible?
servicio TU SERVICIO supervisa
Ahorra tener que crear un
supervisord.conf
He visto un montón de tutoriales que parecen hacer lo mismo que estoy tratando de hacer, pero por alguna razón mis contenedores Docker se cierran.
Básicamente, estoy configurando un servidor web y algunos demonios dentro de un contenedor Docker.
Hago las partes finales de esto a través de un script bash llamado
run-all.sh
que ejecuto a través de CMD en mi Dockerfile.
run-all.sh
tiene este aspecto:
service supervisor start
service nginx start
Y lo inicio dentro de mi Dockerfile de la siguiente manera:
CMD ["sh", "/root/credentialize_and_run.sh"]
Puedo ver que todos los servicios se inician correctamente cuando ejecuto las cosas manualmente (es decir, acceder a la imagen con -i -t / bin / bash), y todo parece funcionar correctamente cuando ejecuto la imagen, pero se cierra una vez termina de iniciar mis procesos.
Me gustaría que los procesos se ejecuten indefinidamente, y hasta donde yo entiendo, el contenedor debe seguir ejecutándose para que esto suceda.
Sin embargo, cuando ejecuto
docker ps -a
, veo:
➜ 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
¿Lo que da? ¿Por qué está saliendo? Sé que podría poner un bucle while al final de mi script bash para mantenerlo, pero ¿cuál es la forma correcta de evitar que salga?
Acabo de tener el mismo problema y descubrí que si está ejecutando su contenedor con los indicadores
-t
y
-d
, sigue ejecutándose.
docker run -td <image>
Esto es lo que hacen las banderas (según
docker run --help
):
-d, --detach=false Run container in background and print container ID
-t, --tty=false Allocate a pseudo-TTY
La más importante es la bandera
-t
.
-d
simplemente te permite ejecutar el contenedor en segundo plano.
Asegúrate de agregar
daemon off;
a usted nginx.conf o ejecútelo con
CMD ["nginx", "-g", "daemon off;"]
según la imagen oficial de nginx
Luego use lo siguiente para ejecutar el supervisor como servicio y nginx como proceso en primer plano que evitará que el contenedor salga
service supervisor start && nginx
En algunos casos, necesitará tener más de un proceso en su contenedor, por lo que obligar al contenedor a tener exactamente un proceso no funcionará y puede crear más problemas en la implementación.
Por lo tanto, debe comprender las compensaciones y tomar su decisión en consecuencia.
Capture el PID del proceso ngnix en una variable (por ejemplo $ NGNIX_PID) y al final del archivo de punto de entrada haga
wait $NGNIX_PID
De esa manera, su contenedor debería funcionar hasta que ngnix esté vivo, cuando ngnix se detenga, el contenedor también se detendrá
La razón por la que sale es porque el script de shell se ejecuta primero como PID 1 y cuando se completa, el PID 1 desaparece y la ventana acoplable solo se ejecuta mientras que el PID 1 lo está.
Puede usar el supervisor para hacer todo, si se ejecuta con el indicador "-n" se le dice que no demonice, por lo que se mantendrá como el primer proceso:
CMD ["/usr/bin/supervisord", "-n"]
Y tu supervisor.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
Entonces puede tener tantos otros procesos como desee y el supervisor se encargará de reiniciarlos si es necesario.
De esa forma, podría usar la supervisión en casos en los que necesite nginx y php5-fpm y no tenga mucho sentido separarlos.
Realmente no es así como debe diseñar sus contenedores Docker.
Al diseñar un contenedor Docker, se supone que debe construirlo de modo que solo se esté ejecutando un proceso (es decir, debe tener un contenedor para Nginx y uno para el supervisor o la aplicación que se está ejecutando); Además, ese proceso debe ejecutarse en primer plano.
El contenedor "saldrá" cuando el proceso mismo salga (en su caso, ese proceso es su script bash).
Sin embargo, si
realmente
necesita (o desea) ejecutar múltiples servicios en su contenedor Docker, considere comenzar desde
"Docker Base Image"
, que usa
runit
como un proceso
runit
(
runit
permanecerá en línea mientras se ejecutan Nginx y Supervisor), que permanecerá en primer plano mientras sus otros procesos hacen lo suyo.
Tienen documentos sustanciales, por lo que debería poder lograr lo que está tratando de hacer de manera razonablemente fácil.
Si está utilizando un Dockerfile, intente:
ENTRYPOINT ["tail", "-f", "/dev/null"]
(Obviamente, esto es solo para fines de desarrollo, no debería necesitar mantener vivo un contenedor a menos que esté ejecutando un proceso, por ejemplo, nginx ...)
puede ejecutar
cat
simple sin ningún argumento mencionado por bro @ Sa''ad para simplemente mantener el contenedor funcionando [en realidad no haciendo más que esperar la entrada del usuario] (el complemento Docker de Jenkins hace lo mismo)
Motivación:
No hay nada de malo en ejecutar múltiples procesos dentro de un contenedor acoplable . Si a uno le gusta usar Docker como una máquina virtual ligera, que así sea. A otros les gusta dividir sus aplicaciones en micro servicios. Pienso: ¿una pila de LÁMPARAS en un contenedor? Simplemente genial.
La respuesta:
Quédese con una buena imagen base como la imagen base de phusion . Puede haber otros. Por favor comenta.
Y esto es solo otra petición de supervisión. Porque la imagen base de phusion proporciona un supervisor además de algunas otras cosas como la configuración de cron y locale. Cosas que te gustaría tener configuradas cuando ejecutas una máquina virtual tan liviana. Por lo que vale, también proporciona conexiones ssh en el contenedor.
La imagen de phusion en sí comenzará y seguirá ejecutándose si emite esta instrucción básica de ejecución de docker:
moin@stretchDEV:~$ docker run -d phusion/baseimage
521e8a12f6ff844fb142d0e2587ed33cdc82b70aa64cce07ed6c0226d857b367
moin@stretchDEV:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
521e8a12f6ff phusion/baseimage "/sbin/my_init" 12 seconds ago Up 11 seconds
O muy simple:
Si una imagen base no es para ti ... Para que la CMD rápida la mantenga en funcionamiento, supongo que algo así para bash:
CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"
O esto para busybox:
CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"
Esto es bueno, porque saldrá
inmediatamente
en una
docker stop
.
Simplemente
sleep
o el
cat
tardará unos segundos antes de que salga el contenedor.