Comment redémarrer un seul conteneur avec docker-compose

333

J'ai un docker-compose.ymlfichier qui contient 4 conteneurs: redis, postgres, api, worker

Lors du développement de Worker, j'ai souvent besoin de le redémarrer pour appliquer des modifications. Existe-t-il un bon moyen de redémarrer un conteneur (par exemple worker) sans redémarrer les autres conteneurs?

Bryan Chen
la source
2
docker-compose -f docker-compose.yml redémarrer le travail
Jinna Balu

Réponses:

398

C'est très simple: utilisez la commande:

docker-compose restart worker

Vous pouvez définir le temps d'attente pour l'arrêt avant de tuer le conteneur (en secondes)

docker-compose restart -t 30 worker

Notez que cela redémarrera le conteneur mais sans le reconstruire. Si vous souhaitez appliquer vos modifications puis redémarrer, consultez les autres réponses.

bmkrio
la source
3
pour moi, cela a fonctionné, mais une question générale si elle est autorisée ici: le «redémarrage» prend-il en charge les conteneurs liés et met-il à jour les / etc / hosts ou un «redémarrage» ne change-t-il aucune adresse IP?
michabbb
Les conteneurs sont liés par leur nom et généralement la seule IP dont vous devez vous soucier est l'adresse IP de l'hôte de docker externe (généralement 192.168.99.100). Il peut y avoir des problèmes si, par exemple, vous redémarrez un conteneur de base de données auquel d'autres conteneurs sont connectés. Les conteneurs dépendants devront être suffisamment résistants pour se reconnecter.
Ryan Kimber
20
L'OP indique qu'il doit "le redémarrer pour appliquer les modifications". Selon les documents, les docker-compose restartcommandes n'appliqueront aucune modification. "Si vous apportez des modifications à votre docker-compose.ymlconfiguration, ces modifications ne sont pas répercutées après l'exécution de cette commande." Utilisez donc docker-compose up -d --build. docs.docker.com/compose/reference/restart
featherbelly
5
nb, travailleur est le nom donné au service dans le fichier yaml et pas tout ce que vous voyez lors de l'exécutiondocker ps -a
worc
2
Cette autre réponse est bien meilleure stackoverflow.com/a/39501539/292408 , car elle restartn'applique pas les modifications même si vous avez déjà exécuté un docker-compose build <container name>et il s'agit d'une réponse non fonctionnelle / incorrecte.
Elijah Lynn
170

Les autres réponses au redémarrage d' un noeud unique est sur la cible, docker-compose restart worker. Cela fera rebondir ce conteneur, mais n'inclura aucune modification, même si vous l'avez reconstruit séparément. Vous pouvez manuellement stop, rm, createet start, mais il y a beaucoup de méthodes plus faciles.

Si vous avez mis à jour votre code, vous pouvez faire la construction et recharger en une seule étape avec:

docker-compose up --detach --build

Cela va d'abord reconstruire vos images à partir de n'importe quel code modifié, ce qui est rapide s'il n'y a pas de changements puisque le cache est réutilisé. Et puis il ne remplace que les conteneurs modifiés. Si vos images téléchargées sont périmées, vous pouvez faire précéder la commande ci-dessus avec:

docker-compose pull

Pour télécharger d'abord les images modifiées (les conteneurs ne seront pas redémarrés tant que vous n'aurez pas exécuté une commande comme celle upci - dessus). Faire un arrêt initial n'est pas nécessaire.

Et pour ne le faire que pour un seul service, suivez la commande up ou pull avec les services que vous souhaitez spécifier, par exemple:

docker-compose up --detach --build worker

Voici un exemple rapide de la première option, le Dockerfile est structuré pour garder les parties du code qui changent fréquemment près de la fin. En fait, les exigences sont extraites séparément pour le, pip installcar ce fichier change rarement. Et comme les conteneurs nginx et redis étaient à jour, ils n'ont pas été redémarrés. Le temps total pour l'ensemble du processus était inférieur à 6 secondes:

$ time docker-compose -f docker-compose.nginx-proxy.yml up --detach --build
Building counter
Step 1 : FROM python:2.7-alpine
 ---> fc479af56697
Step 2 : WORKDIR /app
 ---> Using cache
 ---> d04d0d6d98f1
Step 3 : ADD requirements.txt /app/requirements.txt
 ---> Using cache
 ---> 9c4e311f3f0c
Step 4 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> 85b878795479
Step 5 : ADD . /app
 ---> 63e3d4e6b539
Removing intermediate container 9af53c35d8fe
Step 6 : EXPOSE 80
 ---> Running in a5b3d3f80cd4
 ---> 4ce3750610a9
Removing intermediate container a5b3d3f80cd4
Step 7 : CMD gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0
 ---> Running in 0d69957bda4c
 ---> d41ff1635cb7
Removing intermediate container 0d69957bda4c
Successfully built d41ff1635cb7
counter_nginx_1 is up-to-date
counter_redis_1 is up-to-date
Recreating counter_counter_1

real    0m5.959s
user    0m0.508s
sys     0m0.076s
BMitch
la source
C'est intéressant, mais pourrait-il être utilisé avec l' -no-cacheoption? Disons que j'ai ajouté quelque chose dans mon package.jsonet que je dois le faire RUN npm installmais que le Dockerfilelui - même n'a pas changé
Augustin Riedinger
2
@augustinriedinger Si votre fichier d'entrée est modifié et que vous l'incluez avec une COPYcommande, cela cassera automatiquement le cache.
BMitch
1
@augustinriedinger merci. Je suis mobile, donc je ne vois pas les questions liées. Des étapes de votre question, vous devriez déjà avoir une COPYcommande dans votre Dockerfile. Le git pullmettra à jour le fichier package.json et le cache de génération se brisera lorsque le docker vous verra copier dans un autre fichier.
BMitch
1
Merci ne connaissait pas ce comportement! J'utilisais ADDau lieu de COPYmais apparemment, ce dernier est une meilleure pratique, donc je vais y aller!
Augustin Riedinger
1
@augustinriedinger ADDaura le même résultat que COPYsur le cache du cache, mais (comme suggéré dans le lien des meilleures pratiques) la plupart n'ont pas besoin des capacités supplémentaires, donc je ne me donne même pas la peine de le mentionner.
BMitch
28

Pour redémarrer un service avec des modifications, voici les étapes que j'ai effectuées:

docker-compose stop -t 1 worker
docker-compose build worker
docker-compose create worker
docker-compose start worker
Jeff
la source
10
Si vous avez besoin de modifications à appliquer avec une build, vous pouvez facilement faire une docker-compose up -d --buildet il reconstruira tout et redémarrera tous les conteneurs modifiés. Pas besoin d'arrêter d'abord, avec des temps d'arrêt, et des commandes de création et de démarrage séparées.
BMitch
4
Oui, si vous voulez redémarrer tous les services, mais l'OP ne veut redémarrer qu'un seul service et ne pas redémarrer les autres
Jeff
3
Voir la réponse que j'ai postée, dans l'exemple, le uptestament n'a recréé que le conteneur qui avait été modifié et avait donc besoin d'un redémarrage.
BMitch
18

Commande suivante

docker-compose restart worker

va simplement arrêter et démarrer le conteneur. c'est-à-dire sans charger aucune modification depuis le docker-compose.xml

STOP est similaire à l'hibernation sur PC. Par conséquent, stop / start ne recherchera aucune modification apportée au fichier de configuration. Pour recharger à partir de la recette du conteneur (docker-compose.xml), nous devons supprimer et créer le conteneur (analogie similaire au redémarrage du PC)

Les commandes seront donc les suivantes

docker-compose stop worker       // go to hibernate
docker-compose rm worker        // shutdown the PC 
docker-compose create worker     // create the container from image and put it in hibernate

docker-compose start worker //bring container to life from hibernation
Mr Coder
la source
+1, merci beaucoup! Pour l' rmoption de ligne -fest pratique (pas d'invite) et avec le docker actuel createet startest fusionné comme up(donc au total nous avons 3 commandes et non 4), et pour l' upoption -dest utile (l'exécution est en arrière-plan).
astrowalker
10

Redémarrez le service avec le fichier docker-compose

docker-compose -f [COMPOSE_FILE_NAME].yml restart [SERVICE_NAME]

Cas d'utilisation n ° 1: si COMPOSE_FILE_NAME est docker-compose.ymlet le service est travailleur

docker-compose restart worker

Cas d'utilisation n ° 2: si le nom du fichier est sample.ymlet que le service est travailleur

docker-compose -f sample.yml restart worker

Par défaut, docker-compose recherche docker-compose.ymlsi nous exécutons la docker-composecommande, sinon nous avons un indicateur pour donner un nom de fichier spécifique avec-f [FILE_NAME].yml

Jinna Balu
la source
7

La simple commande «docker» ne sait rien du conteneur «travailleur». Utilisez une commande comme celle-ci

docker-compose -f docker-compose.yml restart worker

Shtlzut
la source
4
ne fonctionne pas - les nouvelles modifications apportées à coker-compose.yml n'ont pas été appliquées au redémarrage
jlee
3

Redémarrez le conteneur

Si vous souhaitez simplement redémarrer votre conteneur:

docker-compose restart servicename

Considérez cette commande comme «redémarrez simplement le conteneur par son nom», ce qui équivaut à la docker restartcommande.

Notez les mises en garde:

  1. Si vous avez modifié les variables ENV, elles ne seront pas mises à jour dans le conteneur. Vous devez l'arrêter et recommencer. Ou, l'utilisation d'une seule commande docker-compose updétectera les modifications et recréera le conteneur.

  2. Comme beaucoup d'autres l'ont mentionné, si vous avez modifié le docker-compose.ymlfichier lui-même, un simple redémarrage n'appliquera pas ces changements.

  3. Si vous copiez votre code à l'intérieur du conteneur au stade de la construction (à l' Dockerfileaide de ADDou de COPYcommandes), chaque fois que le code change, vous devez reconstruire le conteneur ( docker-compose build).

Corrélation avec votre code

docker-compose restartdevrait fonctionner parfaitement bien, si votre code obtient un chemin mappé dans la directive conteneur par volume de la docker-compose.ymlmanière suivante:

services:

  servicename:
    volumes:
      - .:/code

Mais je recommanderais d'utiliser le rechargement de code en direct, qui est probablement fourni par votre framework de choix en mode DEBUG (vous pouvez également rechercher des packages de rechargement automatique dans la langue de votre choix). L'ajout de cela devrait éliminer la nécessité de redémarrer le conteneur à chaque fois après que votre code change, au lieu de recharger le processus à l'intérieur.

Lev Rubel
la source
1

La réponse ici parle de la réflexion du changement sur le fichier docker-compose.yml.

Mais que se passe-t-il si je veux incorporer les modifications que j'ai apportées à mon code, et je crois que cela ne sera possible qu'en reconstruisant l'image et que je fais avec les commandes suivantes

1. arrêt du conteneur docker

docker stop container-id

2. retrait du conteneur docker

docker rm container-id

3. suppression d'image docker

docker rmi image-id

4. composez à nouveau le conteneur

docker-compose up container-name
Anshul Sharma
la source