web-dev-qa-db-fra.com

Exécuter un service automatiquement dans un conteneur de menu fixe

Je crée une image simple: celle qui contient Riak (une base de données NoSQL). L'image démarre le service Riak avec riak start en tant que CMD. À présent, si je l'exécute en tant que démon avec docker run -d quintenk/riak-dev, le processus Riak démarre (je peux le voir dans les journaux). Cependant, il se ferme automatiquement après quelques secondes. Si je l'exécute en utilisant docker run -i -t quintenk/riak-dev /bin/bash, le processus riak n'est pas lancé (UPDATE: voir les réponses pour une explication à ce sujet). En fait, aucun service ne fonctionne du tout. Je peux le démarrer manuellement à l'aide du terminal, mais j'aimerais que Riak démarre automatiquement. Je suppose que ce comportement se produirait également pour d'autres services, Riak n'est qu'un exemple.

Ainsi, l'exécution/le redémarrage du conteneur devrait automatiquement démarrer Riak. Quelle est la bonne approche pour mettre cela en place?


Pour référence, voici le fichier Docker avec lequel l'image peut être créée (UPDATE: modifié à l'aide de la réponse choisie):

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

EDIT: -f changé en -F dans CMD conformément à sa remarque


MA PROPRE REPONSE

Après avoir travaillé avec Docker pendant un certain temps, j’ai pris l’habitude d’utiliser Supervord pour optimiser mes processus. Si vous souhaitez un exemple de code pour cela, consultez https://github.com/Krijger/docker-cookbooks . J'utilise mon image de superviseur comme base pour toutes mes autres images. J'ai blogué sur l'utilisation de superviseur ici .

34
qkrijger

Pour que les conteneurs Docker continuent de fonctionner, vous devez conserver un processus actif au premier plan.

Donc, vous pourriez probablement remplacer cette dernière ligne dans votre fichier Docker avec

CMD /bin/riak console

Ou même

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

Notez que vous ne pouvez pas avoir plusieurs lignes d'instructions CMD, seul le dernier est exécuté.

41
Gigablah

Utiliser la queue pour garder le conteneur en vie est un hack. Notez également que, avec l'option -f, le conteneur d'options se termine lorsque la rotation du journal est effectuée (vous pouvez éviter cela en utilisant -F).

Une meilleure solution consiste à utiliser supervisor . Jetez un coup d'œil à ce tutorial sur l'utilisation de Riak dans un conteneur Docker.

31
sesm

"Si je l'exécute en utilisant le menu fixe -i -t quintenk/riak-dev/bin/bash, le processus riak n'est pas démarré"

Il semble que vous souhaitiez uniquement pouvoir surveiller le journal lorsque vous vous attachez au conteneur. Mon cas d'utilisation est un peu différent en ce sens que je veux que les commandes soient lancées automatiquement, mais je veux pouvoir attacher au conteneur et être dans un shell bash. J'ai pu résoudre nos deux problèmes comme suit:

Dans l'image/conteneur, ajoutez les commandes souhaitées à la fin du fichier /etc/bash.bashrc.

Dans votre cas, ajoutez simplement la ligne /bin/riak start && tail -F /var/log/riak/erlang.log.1 ou insérez /bin/riak start et tail -F /var/log/riak/erlang.log.1 sur des lignes distinctes, en fonction de la fonctionnalité souhaitée.

Maintenant, validez vos modifications dans votre conteneur et réexécutez-le avec: docker run -i -t quintenk/riak-dev /bin/bash. Vous constaterez que les commandes que vous avez insérées dans le bashrc sont déjà en cours d'exécution lorsque vous vous attachez.

4
damick

L'explication de: 

Si je l'exécute en utilisant docker run -i -t quintenk/riak-dev /bin/bash, le processus riak n'est pas lancé

est comme suit. L'utilisation de CMD dans le fichier Docker est en réalité la même fonctionnalité que le démarrage du conteneur à l'aide de docker run {image} {command}. Comme Gigablah l'a fait remarquer, seul le dernier CMD est utilisé, de sorte que celui écrit dans le fichier Docker est remplacé dans ce cas.

En utilisant CMD /bin/riak start && tail -f /var/log/riak/erlang.log.1 dans le fichier de construction, vous pouvez démarrer le conteneur en tant que processus d'arrière-plan en utilisant docker run -d {image}, qui fonctionne comme un charme.

4
qkrijger

Parce que je veux un moyen propre de quitter le processus plus tard, je fais de la dernière commande un appel au shell read qui provoque le blocage de ce processus jusqu'à ce que j'y attache plus tard et appuyez sur Entrée.

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

comme vous pouvez voir le conteneur se ferme après que vous y avez attaché et débloqué la lecture. Vous pouvez bien sûr utiliser un script plus sophistiqué que read -p si vous devez effectuer d'autres opérations de nettoyage, telles que l'arrêt des services et la sauvegarde des journaux, etc.

3
Arthur Ulfeldt

J'utilise une astuce simple à chaque fois que je commence à construire un nouveau conteneur Docker. Pour le garder en vie, j'utilise un ping dans le script du point d'entrée.

Ainsi, dans Dockerfile, lors de l’utilisation de Debian, par exemple, je m’assure de pouvoir cingler . C’est d'ailleurs, toujours agréable, pour vérifier ce qui est accessible depuis le conteneur.

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

Et dans le fichier entrypoint.sh

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

J'utilise ceci au lieu de CMD bash, car je finis toujours par utiliser un fichier de démarrage.

0
Osiris