web-dev-qa-db-fra.com

Comment démarrer un conteneur Docker arrêté avec une commande différente?

Je voudrais démarrer un conteneur Docker arrêté avec une commande différente, car la commande par défaut se bloque. Cela signifie que je ne peux pas démarrer le conteneur et utiliser ensuite "docker exec". 

En gros, j'aimerais démarrer un shell afin de pouvoir inspecter le contenu du conteneur.

Heureusement, j'ai créé le conteneur avec l'option -it!

144
aaa90210

Trouvez votre identifiant de conteneur arrêté

docker ps -a

Commettez le conteneur arrêté:

Cette commande enregistre l'état du conteneur modifié dans une nouvelle image user/test_image

docker commit $CONTAINER_ID user/test_image

Démarrer/exécuter avec un point d’entrée différent:

docker run -ti --entrypoint=sh user/test_image

Description de l'argument Entrypoint: https://docs.docker.com/engine/reference/run/#/entrypoint-default-command-torexecute-at-runtime

Remarque:

Les étapes ci-dessus démarrent simplement un conteneur arrêté avec le même état de système de fichiers. C'est parfait pour une enquête rapide. Toutefois, les variables d'environnement, la configuration réseau, les volumes attachés et les autres employés ne sont pas hérités. Vous devez donc spécifier explicitement tous ces arguments.

Voici les étapes à suivre pour démarrer un conteneur arrêté: (dernier commentaire) https://github.com/docker/docker/issues/18078

246
Dmitriusan

Editez ce fichier (correspondant à votre conteneur arrêté):

vi /var/lib/docker/containers/923...4f6/config.json

Modifiez le paramètre "Path" pour qu'il pointe vers votre nouvelle commande, par exemple./bin/bash. Vous pouvez également définir le paramètre "Args" pour transmettre des arguments à la commande.

Redémarrez le service Docker (notez que cela arrêtera tous les conteneurs en cours d'exécution):

service docker restart

Listez vos conteneurs et assurez-vous que la commande a été modifiée:

docker ps -a

Commencez le conteneur et attachez-le, vous devriez maintenant être dans votre Shell!

docker start -ai mad_brattain

Travaillé sur Fedora 22 avec Docker 1.7.1.

REMARQUE: Si votre shell n'est pas interactif (par exemple, vous n'avez pas créé le conteneur d'origine avec l'option -it), vous pouvez remplacer la commande par "/ bin/sleep 600" ou "/ bin/tail -f/dev/null "pour vous donner le temps de faire" docker exec -it CONTID/bin/bash "comme un autre moyen d'obtenir un shell.

NOTE2: Les versions les plus récentes de docker ont config.v2.json, où vous devrez changer soit Entrypoint, soit Cmd (merci à l'utilisateur60561).

92
aaa90210

Ajouter un chèque en haut de votre script Entrypoint

Docker doit vraiment implémenter cela en tant que nouvelle fonctionnalité, mais voici une autre option de contournement pour les situations dans lesquelles vous avez un Entrypoint qui se termine après un succès ou un échec, ce qui peut rendre difficile le débogage.

Si vous ne possédez pas déjà de script Entrypoint, créez-en un qui exécute toutes les commandes dont vous avez besoin pour votre conteneur. Ensuite, en haut de ce fichier, ajoutez ces lignes à entrypoint.sh:

# Run once, hold otherwise
if [ -f "already_ran" ]; then
    echo "Already ran the Entrypoint once. Holding indefinitely for debugging."
    cat
fi
touch already_ran

# Do your main things down here

Pour vous assurer que cat maintient la connexion, vous devrez peut-être fournir un TTY. J'exécute le conteneur avec mon script Entrypoint comme suit:

docker run -t --entrypoint entrypoint.sh image_name

Le script ne sera exécuté qu'une seule fois et créera un fichier indiquant qu'il a déjà été exécuté (dans le système de fichiers virtuel du conteneur). Vous pouvez ensuite redémarrer le conteneur pour effectuer le débogage:

docker start container_name

Lorsque vous redémarrez le conteneur, le fichier already_ran sera trouvé, ce qui provoquera le blocage du script Entrypoint avec cat (qui attend pour toujours une entrée qui ne viendra jamais, mais maintient le conteneur en vie). Vous pouvez ensuite exécuter une session de débogage bash:

docker exec -i container_name bash

Pendant que le conteneur est en cours d'exécution, vous pouvez également supprimer already_ran et exécuter manuellement le script entrypoint.sh pour le réexécuter, si vous devez déboguer de cette manière.

12
Ethan T

J'ai pris la réponse de @ Dmitriusan et en ai fait un alias:

alias docker-run-prev-container = 'prev_container_id = "$ (docker ps -aq | head -n1)" && docker commit "$ prev_container_id" "prev_container/$ prev_container_id" && docker run -it --entrypoint = prevent/$ prev_container_id "'

Ajoutez ceci dans votre fichier d'alias ~/.bashrc, et vous aurez un nouvel alias docker-run-prev-container astucieux qui vous déposera dans un shell dans le conteneur précédent.

Utile pour le débogage a échoué docker builds.

1
Dean Rather

Mon problème:  

  • J'ai commencé un conteneur avec docker run <IMAGE_NAME>
  • Et puis ajouté des fichiers à ce conteneur
  • Ensuite, j'ai fermé le conteneur et essayé de le redémarrer avec la même commande que ci-dessus.
  • Mais quand j'ai vérifié les nouveaux fichiers, ils manquaient
  • quand je lance docker ps -a, je pouvais voir deux conteneurs. 
  • Cela signifie que chaque fois que j'exécutais la commande docker run <IMAGE_NAME>, une nouvelle image était créée.

Solution: Pour travailler sur le même conteneur que vous avez créé en premier lieu, suivez ces étapes

  • docker ps pour obtenir le conteneur de votre conteneur
  • docker container start <CONTAINER_ID> pour démarrer le conteneur existant
  • Ensuite, vous pouvez continuer d'où vous êtes parti. par exemple. docker exec -it <CONTAINER_ID> /bin/bash
  • Vous pouvez ensuite décider de créer une nouvelle image
0
Amit Dudhbade

Il n'a pas été spécifié si le conteneur est en train de se fermer, mais simplement que votre code se bloque et que vous devez voir ce qui se passe dans le conteneur. Si ce n'est pas la solution, voici une autre solution potentielle. 

Obtenir l'identifiant du conteneur avec docker ps

docker exec -it 665b4a1e17b6 /bin/sh

Si entrypoint est défini sur quelque chose de problématique, il peut également être remplacé comme suggéré dans la réponse de Dmitriusan. Notez également que vous pouvez attacher à tout conteneur en cours d'exécution avec docker attach. Tant de solutions différentes solutions. Je ne vois tout simplement pas la nécessité de s'engager pour l'image. Cela semble inutile.

Documents pour Docker exec - https://docs.docker.com/engine/reference/commandline/exec/

Docs for Docker attach - https://docs.docker.com/engine/reference/commandline/attach/

0
deadbabykitten

Ce n'est pas exactement ce que vous demandez, mais vous pouvez utiliser docker export sur un conteneur arrêté si tout ce que vous voulez est d'inspecter les fichiers.

mkdir $TARGET_DIR
docker export $CONTAINER_ID | tar -x -C $TARGET_DIR
0