Ejecutar un servicio automáticamente en un contenedor docker


Estoy configurando una imagen simple: una que contenga Riak (una base de datos NoSQL). La imagen inicia el servicio Riak con riak start como un CMD. Ahora, si lo corro como un demonio con docker run -d quintenk/riak-dev, inicia el proceso Riak (puedo verlo en los registros). Sin embargo, se cierra automáticamente después de unos segundos. Si lo corro usando docker run -i -t quintenk/riak-dev /bin/bash el proceso de riak no se inicia (ACTUALIZACIÓN: ver respuestas para una explicación de esto). De hecho, no se están ejecutando servicios en absoluto. Puedo iniciarlo manualmente usando el terminal, pero lo haría como Riak para iniciar automáticamente. Me imagino que este comportamiento ocurriría para otros servicios también, Riak es solo un ejemplo.

Por lo tanto, ejecutar/reiniciar el contenedor debe iniciar automáticamente Riak. ¿Cuál es el enfoque correcto de establecer esto?


Como referencia, aquí está el Dockerfile con el que se puede crear la imagen (UPDATE: altered using the chosen answer):

FROM ubuntu:12.04
RUN apt-get update
RUN apt-get install -y openssh-server curl 
RUN curl http://apt.basho.com/gpg/basho.apt.key | apt-key add -
RUN bash -c "echo deb http://apt.basho.com precise main > /etc/apt/sources.list.d/basho.list"
RUN apt-get update
RUN apt-get -y install riak
RUN perl -p -i -e 's/(?<=\{http,\s\[\s\{")127\.0\.0\.1/0.0.0.0/g' /etc/riak/app.config
EXPOSE 8098 
CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1

EDITAR:- f cambiado a-F en CMD de acuerdo con sesm su observación


MI PROPIO RESPUESTA

Después de trabajar con Docker durante algún tiempo tomé el hábito de usar supervisord para tun mis procesos. Si desea un código de ejemplo para eso, consulte https://github.com/Krijger/docker-cookbooks. Utilizo mi imagen de supervisor como base para todas mis otras imágenes. He blogueado sobre el uso de supervisor aquí.

 34
Author: qkrijger, 2013-06-22

6 answers

Para mantener los contenedores docker en funcionamiento, debe mantener un proceso activo en primer plano.

Así que probablemente podría reemplazar esa última línea en su Dockerfile con

CMD /bin/riak console

O incluso

CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1

Tenga en cuenta que no puede tener varias líneas de instrucciones CMD, solo se ejecuta la última.

 41
Author: Gigablah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-02 14:05:41

Usar tail para mantener el contenedor vivo es un truco. Además, tenga en cuenta que con -f el contenedor de opciones terminará cuando ocurra la rotación del registro (esto se puede evitar utilizando -F en su lugar).

Una mejor solución es usar supervisor. Echa un vistazo a este tutorial sobre la ejecución de Riak en un contenedor Docker.

 31
Author: sesm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-06 06:55:27

La explicación para:

Si lo corro usando docker run -i -t quintenk/riak-dev /bin/bash el proceso riak no se inicia

Es como sigue. Usar CMD en el Dockerfile es en realidad la misma funcionalidad que iniciar el contenedor usando docker run {image} {command}. Como señaló Gigablah, solo se usa el último CMD, por lo que el escrito en el Dockerfile se sobrescribe en este caso.

Usando CMD /bin/riak start && tail -f /var/log/riak/erlang.log.1 en el Buildfile, puedes iniciar el contenedor como un proceso en segundo plano usando docker run -d {image}, que funciona como un encanto.

 4
Author: qkrijger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-30 09:36:08

"Si lo corro usando docker run-i-t quintenk/riak-dev / bin / bash el proceso de riak no se inicia"

Parece que solo desea poder monitorear el registro cuando se conecta al contenedor. Mi caso de uso es un poco diferente en que quiero que los comandos se inicien automáticamente, pero quiero poder conectarlos al contenedor y estar en un shell bash. Pude resolver nuestros dos problemas de la siguiente manera:

En la imagen/contenedor, agregue los comandos que desee se inicia automáticamente hasta el final del archivo /etc/bash.bashrc.

En su caso, simplemente agregue la línea /bin/riak start && tail -F /var/log/riak/erlang.log.1, o coloque /bin/riak start y tail -F /var/log/riak/erlang.log.1 en líneas separadas dependiendo de la funcionalidad deseada.

Ahora confirma tus cambios en tu contenedor, y ejecútalo de nuevo con: docker run -i -t quintenk/riak-dev /bin/bash. Encontrará que los comandos que puso en el bashrc ya se están ejecutando a medida que los adjunta.

 4
Author: damick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-09 05:44:33

Debido a que quiero una forma limpia de tener el proceso de salida más tarde hago el último comando una llamada a la shell read lo que hace que ese proceso se bloquee hasta que más tarde lo adjunte y presione enter.

arthur@macro:~/docker$ sudo docker run -d -t -i -v /raid:/raid -p 4040:4040 subsonic /bin/bash -c 'service subsonic start && read -p "waiting"'
WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: [8.8.8.8 8.8.4.4]
f27229a260c9

arthur@macro:~/docker$ sudo docker ps                                                                                                                                     
[sudo] password for arthur: 
ID                  IMAGE               COMMAND                CREATED              STATUS              PORTS
35f253bdf45a        subsonic:latest     /bin/bash -c service   2 days ago          Up 2 days           4040->4040

arthur@macro:~/docker$ sudo docker attach 35f253bdf45a

arthur@macro:~/docker$ sudo docker ps                                                                                                                                     
ID                  IMAGE               COMMAND             CREATED             STATUS              PORTS

Como puede ver, el contenedor sale después de conectarlo y desbloquear la lectura. Por supuesto, puede usar un script más sofisticado que read -p si necesita hacer otra limpieza, como detener servicios y guardar registros, etc.

 3
Author: Arthur Ulfeldt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 17:15:53

Uso un truco simple cada vez que empiezo a construir un nuevo contenedor docker. Para mantenerlo vivo, utilizo un ping en el script entrypoint.

Así que en el Dockerfile, cuando uso Debian, por ejemplo, me aseguro de poder hacer ping. Esto es por cierto, siempre agradable, para comprobar lo que es accesible desde el interior del contenedor.

...
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
 && apt-get install -y iputils-ping 
...
ENTRYPOINT ["entrypoint.sh"]

Y en el entrypoint.sh file

#!/bin/bash
...
ping 10.10.0.1 >/dev/null 2>/dev/null

Uso esto en lugar de CMD bash, ya que siempre termino usando un archivo de inicio.

 0
Author: Osiris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-22 08:28:10