Comment modifier des fichiers dans un conteneur Docker arrêté / ne démarre pas

94

En essayant de corriger les erreurs et de déboguer les problèmes avec mon application qui est répartie sur plusieurs conteneurs, j'édite fréquemment des fichiers dans des conteneurs:

  • soit je suis totalement paresseux et installe nano et édite directement dans le conteneur ou

  • Je docker cp le fichier hors du conteneur, le modifier, le recopier et redémarrer le conteneur

Ce sont des étapes intermédiaires avant d'arriver à un nouveau contenu pour la construction de conteneurs, ce qui prend beaucoup plus de temps que de faire ce qui précède (ce qui, bien sûr, n'est que intermédiaire / bidouillage).

Maintenant, je casse fréquemment le programme de démarrage du conteneur, qui dans les cas de rupture est soit un script de nœud ou un script de serveur Web python, les deux échouent généralement à cause d'erreurs de syntaxe.

Existe-t-il un moyen de sauvegarder ces conteneurs? Puisqu'ils ne démarrent pas, je ne peux pas les exécuter, et ils me sont donc perdus. Je vais ensuite sur la route rm / rmi / build / run après avoir corrigé le fichier incriminé dans l'entrée de construction.

Comment puis-je modifier des fichiers dans un conteneur arrêté, les cp ou démarrer un shell dans un conteneur arrêté - tout ce qui me permet de réparer ce conteneur?

(Cela ressemble un peu à travailler sur un ordinateur distant et à interrompre la configuration du réseau - la connexion est perdue "pour toujours" de cette façon et il faut utiliser une solution de secours, si elle existe.)

Comment modifier les fichiers de conteneur Docker à partir de l'hôte? semble pertinent mais est obsolète.

Andreas Reiff
la source
Celui-ci pourrait également être une solution de contournement stackoverflow.com/a/32353134/586754 - dans l'espoir d'une meilleure solution pour le moment.
Andreas Reiff
1
peut-être devriez-vous envisager de monter un volume afin de pouvoir éditer des fichiers sur votre hôte plutôt que dans le conteneur. Une fois satisfait de votre code, vous êtes libre de docker cp
placer
Oui, ce serait un peu tard si je n'avais pas mis en place des choses comme ça depuis le début. Cela ne fonctionne pas pour la récupération, je pense.
Andreas Reiff
De nombreux lecteurs voudront uniquement afficher les fichiers plutôt que de les modifier. Dans ces cas, vous pouvez utiliser la docker commitcommande pour casser une nouvelle image. name=$(docker commit); docker run -it $name /bin/shfera ce que vous voulez.
Att Righ
il semble donc que les systèmes de fichiers des conteneurs arrêtés soient relativement permanents à la fin?
Webwoman

Réponses:

139

J'ai eu un problème avec un conteneur qui ne démarre pas en raison d'un mauvais changement de configuration que j'ai effectué. J'ai pu copier le fichier hors du conteneur arrêté et le modifier. quelque chose comme:

docker cp docker_web_1:/etc/apache2/sites-enabled/apache2.conf .

(corrigez le fichier)

docker cp apache.conf docker_web_1:/etc/apache2/sites-enabled/apache2.conf
Tomurie
la source
22
Cela devrait être la réponse acceptée. Pour une raison quelconque, je ne pensais pas que le CP travaillait sur des conteneurs arrêtés. Agréable!
Proximo
Parfait. J'ai copié un fichier à partir du conteneur (je connaissais son chemin), puis je l'ai modifié, puis recopié dans le conteneur au même emplacement. A travaillé pour moi! Merci!
Nawaz
Existe-t-il un moyen de supprimer un fichier?
kodlan
1
@kodlan Seulement s'il n'apparaît que dans le que UpperDirvous obtenez docker container inspect- vous devrez expérimenter pour voir comment le système de superposition représente les fichiers dans la structure sous-jacente qui ont été supprimés dans la couche supérieure.
Tim Baverstock le
Merci, cela m'a aidé à réparer mon conteneur MySQL fonctionnant dans docker sur macOS.
mazedlx
60

Répondre à ma propre question ... espérant toujours une meilleure réponse d'une personne plus compétente !!

Il y a 2 possibilités.

1) Modification du système de fichiers directement sur l'hôte . Ceci est quelque peu dangereux et risque de casser complètement le conteneur, éventuellement d'autres données en fonction de ce qui ne va pas.

2) Changer le script de démarrage pour quelque chose qui n'échoue jamais comme démarrer un bash, faire les correctifs / modifications, puis changer à nouveau le programme de démarrage pour celui souhaité (comme le nœud ou ce qu'il était auparavant).

Plus de détails:

1) Utilisation

docker ps

pour trouver les conteneurs en cours d'exécution ou

docker ps -a

pour trouver tous les conteneurs (y compris ceux arrêtés) et

docker inspect (containername)

recherchez le "Id", l'une des premières valeurs.

C'est la partie qui contient les détails de l'implémentation et qui peut changer, sachez que vous risquez de perdre votre conteneur de cette façon.

Aller à

/var/lib/docker/aufs/diff/9bc343a9..(long container id)/

et là, vous trouverez tous les fichiers qui sont modifiés vers l'image sur laquelle le conteneur est basé. Vous pouvez écraser des fichiers, ajouter ou modifier des fichiers.

Encore une fois, je ne recommanderais pas cela.

2) Comme décrit sur https://stackoverflow.com/a/32353134/586754, vous pouvez trouver la configuration json config.json à un chemin comme

/var/lib/docker/containers/9bc343a99..(long container id)/config.json

Là, vous pouvez changer les arguments par exemple de "nodejs app.js" à "/ bin / bash". Maintenant, redémarrez le service docker et démarrez le conteneur (vous devriez voir qu'il démarre maintenant correctement). Tu devrais utiliser

docker start -i (containername)

pour s'assurer qu'il ne s'arrête pas tout de suite. Vous pouvez maintenant travailler avec le conteneur et / ou attacher ultérieurement avec

docker exec -ti (containername) /bin/bash

En outre, docker cp est plutôt utile pour copier des fichiers qui ont été modifiés en dehors du conteneur.

De plus, on ne devrait revenir à ces mesures que si le conteneur est plus ou moins «perdu» de toute façon, donc tout changement constituerait une amélioration.

Andreas Reiff
la source
En espérant toujours une meilleure réponse - alors n'hésitez pas à en donner une, je déplacerai également la balise "répondue".
Andreas Reiff
J'ai utilisé la deuxième méthode et j'ai dû redémarrer le service docker afin de forcer l'écrasement des config.jsonfichiers à chaque fois que je les
éditais
2
J'ai config.v2.json et chaque fois que je démarre le conteneur zombie, il annule ma mise à jour Path / EntryPoint et meurt à nouveau. L'utilisation de "docker cp" pour mettre à jour le script entrypoint.sh pour exécuter simplement bash l'a corrigé.
Curtis Yallop
@CurtisYallop Je vis la même chose. Comment as-tu résolu ça?
Brett McLain
1
@BrettMcLain J'ai utilisé docker cp plutôt que de le modifier sur l'hôte. Comme ceci: Trouvez l'emplacement du script du point d'entrée: "docker inspect container_name | grep Entry". Récupérez le script: "docker cp nom_conteneur: /entrypoint.sh ./". (Modifiez-le) Remettez le script dans le conteneur: "docker cp entrypoint.sh nom_conteneur: /entrypoint.sh". Vous pouvez faire exécuter le point d'entrée bash ou exécuter une boucle de sommeil, par exemple "while:; do sleep 10; done". La première ligne de script doit être "#! / Bin / bash".
Curtis Yallop
9

Vous pouvez modifier directement le système de fichiers du conteneur, mais je ne sais pas si c'est une bonne idée. Vous devez d'abord trouver le chemin du répertoire qui est utilisé comme racine d'exécution pour le conteneur. Courez docker container inspect id/name. Recherchez la clé UpperDirdans la sortie JSON.

C'est votre annuaire.

Tejas Sarade
la source
J'ai trouvé le répertoire, mais il ne contenait pas tous les fichiers.
aioobe
C'est OverlayFS, donc vos fichiers doivent être dans un sur ces répertoires.
Tejas Sarade
Le nom du répertoire peut être différent de "UpperDir", par exemple, dans mon cas, il s'agit de Source. Mais ça a marché!
Rajni Kewlani
0

Si vous essayez de redémarrer un conteneur arrêté et que vous devez modifier le conteneur en raison d'une mauvaise configuration mais que le conteneur ne démarre pas, vous pouvez faire ce qui suit qui fonctionne en utilisant la commande "docker cp" (similaire à la suggestion précédente). Cette procédure vous permet de supprimer des fichiers et d'effectuer toute autre modification nécessaire. Avec de la chance, vous pouvez ignorer de nombreuses étapes ci-dessous.

  1. Utilisez docker inspect pour trouver le point d'entrée, (nommé Path dans certaines versions)
  2. Créer un clone de l'exécution du docker à l'aide
  3. Entrez clone en utilisant docker exec -ti bash (if * nix container)
  4. Localisez l'emplacement du fichier de point d'entrée en regardant à travers le clone pour trouver
  5. Copiez l'ancien script de point d'entrée en utilisant docker cp: ./
  6. Modifier ou créer un nouveau script de point d'entrée par exemple

    #!/bin/bash tail -f /etc/hosts

  7. s'assurer que le script dispose des droits d'exécution
  8. Remplacez l'ancien point d'entrée à l'aide de docker cp ./:
  9. démarrer l'ancien conteneur en utilisant start
  10. refaire les étapes 6 à 9 jusqu'au début
  11. Résoudre les problèmes dans le conteneur
  12. Restaurer le point d'entrée si nécessaire et refaire les étapes 6 à 9 si nécessaire
  13. Supprimer le clone si nécessaire
user6830669
la source