194 votes

Puis-je exécuter plusieurs programmes dans un conteneur Docker ?

J'essaie d'appréhender Docker du point de vue du déploiement d'une application destinée à être exécutée sur le bureau de l'utilisateur. Mon application est simplement une application web flask et une base de données mongo. Normalement, je devrais installer les deux dans une VM et transférer un port hôte à l'application web invitée. J'aimerais essayer Docker mais je ne suis pas sûr de savoir comment utiliser plus d'un programme. La documentation indique qu'il ne peut y avoir qu'un seul point d'entrée, alors comment puis-je avoir Mongo et mon application Flask ? Ou bien doivent-ils être dans des conteneurs séparés, auquel cas comment peuvent-ils communiquer entre eux et comment cela facilite-t-il la distribution de l'application ?

2 votes

Tout à fait d'accord : je me demande pourquoi les dockers étaient si populaires (processus unique ?) - mais voyons ce que les réponses nous disent

138voto

vesako Points 421

Il ne peut y avoir qu'un seul ENTRYPOINT, mais cette cible est généralement un script qui lance autant de programmes que nécessaire. Vous pouvez également utiliser par exemple Superviseur ou similaire pour prendre en charge le lancement de plusieurs services dans un seul conteneur. Voici un exemple de conteneur docker faisant fonctionner mysql, apache et wordpress dans un seul conteneur. .

Disons que vous avez une base de données qui est utilisée par une seule application web. Alors il est probablement plus facile d'exécuter les deux dans un seul conteneur.

Si vous avez une base de données partagée qui est utilisée par plus d'une application, il serait préférable d'exécuter la base de données dans son propre conteneur et les applications dans leurs propres conteneurs.

Il existe au moins deux possibilités pour que les applications puissent communiquer entre elles lorsqu'elles sont exécutées dans des conteneurs différents :

  1. Utilisez les ports IP exposés et connectez-vous par leur intermédiaire.
  2. Versions récentes de docker support de liaison .

3 votes

Il semble que les nouvelles versions de Docker supportent maintenant Réseaux de conteneurs Docker .

0 votes

Docker prend désormais en charge l'exécution de Supervisor, ce qui vous permet de spécifier le comportement de chaque processus, par exemple autorestart=true, stdout_logfile, stderr_logfile, etc. Jetez un coup d'œil à docs.docker.com/engine/admin/using_supervisord

9 votes

Je ne recommande absolument pas d'essayer d'exécuter l'application web et mongodb dans le même conteneur dans cet exemple. Il existe de bons cas d'utilisation de supervisord ou de processus similaires à init dans Docker, mais celui-ci n'en fait pas partie. Il est beaucoup plus simple d'utiliser docker-compose pour exécuter les deux services dans des conteneurs séparés.

35voto

user2491400 Points 55

Je ne suis pas du tout d'accord avec certaines solutions précédentes qui recommandaient d'exécuter les deux services dans le même conteneur. Il est clairement indiqué dans la documentation que ce n'est pas une solution recommandée. :

Il est généralement recommandé de séparer les zones de préoccupation en utilisant un service par conteneur. Ce service peut être divisé en plusieurs processus (par exemple, le serveur web Apache lance plusieurs processus de travail). Il est acceptable d'avoir plusieurs processus, mais pour tirer le meilleur parti de Docker, évitez qu'un conteneur soit responsable de plusieurs aspects de votre application globale. Vous pouvez connecter plusieurs conteneurs à l'aide de réseaux définis par l'utilisateur et de volumes partagés.

Il existe de bons cas d'utilisation pour supervisord ou des programmes similaires, mais l'exécution d'une application web + base de données n'en fait pas partie.

Vous devez absolument utiliser docker-compose pour ce faire et orchestrer plusieurs conteneurs avec des responsabilités différentes.

24voto

Basav Points 366

J'avais une exigence similaire, à savoir faire fonctionner une pile LAMP, une base de données Mongo et mes propres services.

Docker est une virtualisation basée sur le système d'exploitation, c'est pourquoi il isole son conteneur autour d'un processus en cours d'exécution, d'où la nécessité d'avoir au moins un processus en cours d'exécution dans FOREGROUND.

Ainsi, vous fournissez votre propre startup script comme point d'entrée, ainsi votre startup script devient une image Docker étendue script, dans laquelle vous pouvez empiler n'importe quel nombre de services jusqu'à AU MOINS UN SERVICE D'AVANT-PLAN EST DÉMARRÉ, LUI AUSSI VERS LA FIN

Ainsi, mon fichier d'image Docker a deux lignes ci-dessous à la toute fin :

COPY myStartupScript.sh /usr/local/myscripts/myStartupScript.sh
CMD ["/bin/bash", "/usr/local/myscripts/myStartupScript.sh"]

Dans mon script, j'exécute tout MySQL, MongoDB, Tomcat, etc. A la fin, j'exécute mon Apache comme un thread de premier plan.

source /etc/apache2/envvars
/usr/sbin/apache2 -DFOREGROUND

Cela me permet de lancer tous mes services et de maintenir le conteneur en vie, le dernier service lancé étant au premier plan.

J'espère que cela vous aidera

UPDATE : Depuis la dernière fois que j'ai répondu à cette question, de nouvelles choses sont apparues, par exemple Docker compose qui peut vous aider à exécuter chaque service sur son propre conteneur, tout en les liant tous ensemble en tant que dépendances entre ces services, essayez d'en savoir plus sur docker-compose et l'utiliser, c'est la manière la plus élégante, sauf si votre besoin ne correspond pas à cette méthode.

17voto

Sam Points 315

Bien que ce ne soit pas recommandé, vous pouvez exécuter 2 processus en avant-plan en utilisant wait . Il suffit de faire un bash script avec le contenu suivant. Par exemple start.sh :

# runs 2 commands simultaneously:

mongod & # your first application
P1=$!
python script.py & # your second application
P2=$!
wait $P1 $P2

Dans votre Dockerfile, démarrez-le avec

CMD bash start.sh

Je vous recommande de mettre en place un cluster Kubernetes local si vous souhaitez exécuter plusieurs processus simultanément. Vous pouvez "distribuer" l'application en leur fournissant un simple manifeste Kubernetes.

7voto

Alister Bulman Points 12913

Ils peuvent être dans des conteneurs séparés et, en effet, si l'application était également destinée à être exécutée dans un environnement plus vaste, ils le seraient probablement.

Un système à conteneurs multiples nécessiterait une orchestration plus poussée pour être en mesure de faire apparaître toutes les dépendances requises, bien que dans Docker v0.6.5+, il existe une nouvelle fonction pour y parvenir, intégrée à Docker lui-même. Lien vers . Cependant, dans le cas d'une solution multi-machine, il s'agit toujours d'un élément qui doit être organisé en dehors de l'environnement Docker.

Avec deux conteneurs différents, les deux parties communiquent toujours via TCP/IP, mais à moins que les ports n'aient été verrouillés spécifiquement (ce qui n'est pas recommandé, car vous ne pourriez pas exécuter plus d'une copie), vous devrez passer le nouveau port auquel la base de données a été exposée à l'application, afin qu'elle puisse communiquer avec Mongo. Là encore, Linking peut vous aider.

Pour une petite installation plus simple, où toutes les dépendances vont dans le même conteneur, avoir à la fois la base de données et le runtime Python démarrés par le programme qui est initialement appelé comme ENTRYPOINT est également possible. Cela peut être aussi simple qu'un shell script, ou tout autre contrôleur de processus - Superviseur est assez populaire, et un certain nombre d'exemples existent dans les Dockerfiles publics.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X