Après quelques recherches et essais, j'ai trouvé que j'ai eu quelques malentendus à propos de la durée de vie des conteneurs Docker. Il suffit de redémarrer un conteneur ne fait pas de menu fixe l'utilisation d'une nouvelle image, lorsque l'image a été reconstruite dans le temps. Au lieu de cela, Docker est de l'extraction de l'image seulement avant l'exécution du conteneur. Si l'état après l'exécution d'un conteneur est persistant.
Pourquoi la suppression est nécessaire
Par conséquent, la reconstruction et le redémarrage n'est pas suffisant. Je pensais que les conteneurs fonctionne comme un service: Arrêt du service, effectuez vos modifications, redémarrez-le et ils s'appliquent. C'était ma plus grosse erreur.
Parce que les conteneurs sont permanents, vous devez les enlever à l'aide de docker rm <ContainerName>
première. Après un récipient est retiré, vous ne pouvez pas tout simplement commencer par docker start
. Cela doit être fait à l'aide de docker run
, qui lui-même utilise la dernière image pour la création d'un nouveau conteneur d'instance.
Les contenants doivent être aussi indépendants que possible
Avec cette connaissance, c'est de comprendre pourquoi le stockage des données dans des conteneurs est qualifié comme une mauvaise pratique et Docker recommande volumes de données/montage d'accueil répertoires au lieu de cela: Depuis un conteneur doit être détruit pour mettre à jour les applications, les données stockées à l'intérieur serait perdu trop. Cette entraîner un surcroît de travail pour l'arrêt des services, de sauvegarde de données et ainsi de suite.
Donc c'est une solution intelligente pour exclure les données à partir du conteneur: Nous n'avons pas à vous soucier de nos données, lorsqu'il est stocké en toute sécurité sur l'ordinateur hôte et le conteneur ne contient que l'application elle-même.
Pourquoi -rf
peut pas vraiment vous aider
L' docker run
de commande, a Nettoyer commutateur appelé -rf
. Il fera cesser le comportement de garder les conteneurs docker en permanence. À l'aide de -rf
, Docker va détruire le conteneur après qu'il a été quitté. Mais ce commutateur a deux problèmes:
- Menu fixe également supprimer les volumes sans nom associé avec le conteneur, qui peut tuer vos données
- En utilisant cette option, il n'est pas possible d'exécuter des conteneurs dans l'arrière-plan à l'aide de
-d
interrupteur
Alors que l' -rf
switch est une bonne option pour enregistrer le travail en cours de développement pour les tests rapides, il est moins approprié dans la production. Surtout parce que la disparition de l'option pour exécuter un conteneur dans le fond, qui serait principalement requis.
Comment faire pour supprimer un conteneur
On peut contourner ces limitations en enlevant simplement le conteneur:
docker rm --force <ContainerName>
L' --force
(ou -f
) commutateur à utiliser SIGKILL sur l'exécution des conteneurs. Au lieu de cela, vous pouvez également arrêter le conteneur avant:
docker stop <ContainerName>
docker rm <ContainerName>
Les deux sont égaux. docker stop
est également à l'aide de SIGTERM. Mais à l'aide de --force
switch permettra de réduire votre script, en particulier lors de l'utilisation de serveurs CI: docker stop
renvoie une erreur si le conteneur n'est pas en cours d'exécution. Ce serait la cause de Jenkins et de nombreux autres serveurs CI à envisager de le construire à tort comme ayant échoué. Pour résoudre ce problème, vous devez tout d'abord vérifier si le conteneur est en cours d'exécution comme je l'ai fait dans la question (voir containerRunning
variable).
Le texte complet de la reconstruction d'un conteneur Docker
Selon cette nouvelle connaissance, j'ai corrigé mon script de la manière suivante:
#!/bin/bash
imageName=xx:my-image
containerName=my-container
docker build -t $imageName -f Dockerfile .
echo Delete old container...
docker rm -f $containerName
echo Run new container...
docker run -d -p 5000:5000 --name $containerName $imageName
Cela fonctionne parfaitement :)