Comment faire en sorte que docker-compose recrée toujours des conteneurs à partir d'images fraîches?


199

Mes images Docker sont construites sur un serveur Jenkins CI et sont transférées vers notre registre Docker privé. Mon objectif est de fournir des environnements avec docker-compose qui démarrent toujours l'état d'origine des images.

J'utilise actuellement docker-compose 1.3.2 ainsi que 1.4.0 sur différentes machines, mais nous avons également utilisé des versions plus anciennes précédemment.

J'ai toujours utilisé les docker-compose pull && docker-compose up -dcommandes pour récupérer les nouvelles images du registre et les démarrer. Je crois que mon comportement préféré fonctionnait comme prévu jusqu'à un certain moment, mais depuis lors, a docker-compose upcommencé à réexécuter les conteneurs précédemment arrêtés au lieu de démarrer à chaque fois les images initialement créées.

Existe-t-il un moyen de se débarrasser de ce comportement? Est-ce que cela pourrait être celui qui est câblé dans le fichier de configuration docker-compose.yml pour ne pas dépendre de "ne pas oublier" quelque chose sur la ligne de commande à chaque appel?

ps. En plus de trouver un moyen d'atteindre mon objectif, j'aimerais également en savoir un peu plus sur le contexte de ce comportement. Je pense que l'idée de base de Docker est de construire une infrastructure immuable. Le comportement actuel de docker-compose semble simplement en contradiction avec cette approche .. ou est-ce que je manque quelques points ici?

Réponses:


233

docker-compose up --force-recreateest une option, mais si vous l'utilisez pour CI, je commencerais la construction avec docker-compose rm -fpour arrêter et supprimer les conteneurs et les volumes (puis la suivre avec pull and up).

Voici ce que j'utilise:

docker-compose rm -f
docker-compose pull
docker-compose up --build -d
# Run some tests
./tests
docker-compose stop -t 1

La raison pour laquelle les conteneurs sont recréés est de conserver tous les volumes de données qui pourraient être utilisés (et cela se produit également upbeaucoup plus rapidement).

Si vous faites du CI, vous ne le voulez pas, alors tout simplement supprimer tout devrait vous donner ce que vous voulez.

Mise à jour: utilisation up --buildqui a été ajoutée en docker-compose1.7


1
Oui, en fait, c'est aussi ce que je fais dans CI. Je ne sais pas pourquoi je n'ai pas mentionné cela ...
Adrian Mouat

@dnephin docker-compose run -dn'existe pas? Tu veux dire docker-compose up -dnon?
Guillaume Vincent

2
si vous courez docker-compose pullavant, docker-compose rm -fvous pouvez gagner encore plus de temps
stephanlindauer

2
À quoi sert le drapeau -d à la fin?
David

3
"-d Mode détaché: exécutez les conteneurs en arrière-plan",
dnephin

135

La seule solution qui a fonctionné pour moi était cette commande:

docker-compose build --no-cache

Cela extraira automatiquement une nouvelle image du référentiel et n'utilisera pas la version du cache qui est préconstruite avec les paramètres que vous avez utilisés auparavant.


1
En outre, sous Windows 10, il peut aider à définir le serveur DNS dans les paramètres d'Automatique à Fixe ou de Fixé à Automatique.
qräbnö

2
A travaillé pour moi sur la construction OS X avec docker-comopse version 2.
RoboBear

1
Travaillé sur docker OS X.
HelloWorld

55

Selon la documentation officielle actuelle , il existe un raccourci qui arrête et supprime les conteneurs, les réseaux, les volumes et les images créés par up, s'ils sont déjà arrêtés ou partiellement supprimés, etc., il fera également l'affaire:

docker-compose down

Ensuite, si vous avez de nouvelles modifications sur vos images ou Dockerfiles, utilisez:

docker-compose build --no-cache

Finalement:docker-compose up

En une seule commande: docker-compose down && docker-compose build --no-cache && docker-compose up


2
docker-compose build --no-cachen'est nécessaire que s'il y a des changements sur Dockerfiles.
Victor Timoftii

En effet, Victor. Merci! J'ai pensé que c'était également nécessaire après la mise à jour d'un module / application qui est exécuté au démarrage du conteneur. Pour ces cas, avant d'exécuter docker-compose up, il est nécessaire de reconstruire les services avec docker-compose build.
ivanleoncz

18

Vous pouvez passer --force-recreateà docker compose up, qui devrait utiliser des conteneurs frais.

Je pense que le raisonnement derrière la réutilisation des conteneurs est de conserver tout changement pendant le développement. Notez que Compose fait quelque chose de similaire avec les volumes, qui persisteront également entre les récréations de conteneurs (un conteneur recréé sera attaché aux volumes de son prédécesseur). Cela peut être utile, par exemple, si vous avez un conteneur Redis utilisé comme cache et que vous ne voulez pas perdre le cache chaque fois que vous effectuez une petite modification. À d'autres moments, c'est juste déroutant.

Je ne pense pas que vous puissiez forcer cela à partir du fichier Compose.

Il est possible que cela entre en conflit avec les principes d'infrastructure immuables. Le contre-argument est probablement que vous n'utilisez pas (encore) Compose en production. De plus, je ne suis pas sûr d'être d'accord sur le fait que l'infra immuable est l'idée de base de Docker, bien que ce soit certainement un bon cas d'utilisation / argument de vente.


Merci d'avoir répondu. Je pense qu'il serait vraiment utile de le forcer au niveau de la configuration, par exemple. pour l'imposer pour un conteneur de base de données et désactiver la recréation par défaut pour les conteneurs d'application ..
Kristof Jozsa

8
--force-recreatene fonctionne pas pour moi ... L'image n'est pas tirée même si une nouvelle version est disponible ...
lisak

1
@lisak Je n'ai jamais dit que cela tirait de nouvelles images. Ce n'est pas le cas. Il démarre simplement de nouveaux conteneurs en utilisant l'image disponible localement. Vous devrez exécuter Docker Pull manuellement.
Adrian Mouat

2
docker-compose up --build

OU

docker-compose build --no-cache

1
Dans la mesure du possible, veuillez faire un effort pour fournir des explications supplémentaires au lieu de simplement du code. Ces réponses ont tendance à être plus utiles car elles aident les membres de la communauté et en particulier les nouveaux développeurs à mieux comprendre le raisonnement de la solution, et peuvent aider à éviter d'avoir à répondre à des questions de suivi.
Rajan

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.