Comment exécuter une commande sur un conteneur Docker déjà existant?
J'ai créé un conteneur avec -d
donc ce n'est pas interactif.
docker run -d shykes/pybuilder bin/bash
Je vois que le conteneur est sorti:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d6c45e8cc5f0 shykes/pybuilder:latest "bin/bash" 41 minutes ago Exited (0) 2 seconds ago clever_bardeen
Maintenant, je voudrais exécuter des commandes occasionnelles sur la machine et quitter. Juste pour obtenir la réponse.
J'ai essayé de démarrer la machine. J'ai essayé de l'attacher. Je pensais pouvoir appeler run
avec un conteneur, mais cela ne semble pas être autorisé. L'utilisation de start
semble juste fonctionner et exister rapidement.
Je voudrais revenir en mode interactif après quitter.
J'ai essayé:
docker attach d6c45e8cc5f0
Mais je reçois:
2014/10/01 22:33:34 You cannot attach to a stopped container, start it first
Mais si je le démarre, il sort quand même. Attrape 22. Je ne peux pas gagner.
12 réponses
En octobre 2014, l'équipe docker a introduit docker exec
Commande: https://docs.docker.com/engine/reference/commandline/exec/
Vous pouvez donc maintenant exécuter n'importe quelle commande dans un conteneur en cours d'exécution en connaissant simplement son ID (ou son nom):
docker exec -it <container_id_or_name> echo "Hello from container!"
Notez que la commande exec
ne fonctionne que sur le conteneur déjà en cours d'exécution. Si le conteneur est actuellement arrêté, vous devez d'abord l'exécuter avec la commande suivante:
docker run -it -d shykes/pybuilder /bin/bash
La chose la plus importante ici est l'option -d
, qui signifie detached
. Cela signifie que la commande que vous avez initialement fournie au conteneur (/bin/bash
) sera exécutée en arrière-plan et que le conteneur ne s'arrêtera pas immédiatement .
Votre conteneur quittera car la commande que vous lui avez donnée se terminera. Utilisez les options suivantes pour le maintenir actif:
-
-i
Gardez STDIN ouvert même s'il n'est pas attaché. -
-t
attribuer un pseudo-TTY.
Donc votre nouvelle commande run
est:
docker run -it -d shykes/pybuilder bin/bash
Si vous souhaitez attacher à un conteneur déjà en cours d'exécution:
docker exec -it CONTAINER_ID /bin/bash
Dans ces exemples /bin/bash
est utilisé comme commande.
Pour développer la réponse de katrmr, si le conteneur est arrêté et ne peut pas être démarré en raison d'une erreur, vous devrez le commit
dans une image. Ensuite, vous pouvez lancer bash dans la nouvelle image:
docker commit [CONTAINER_ID] temporary_image
docker run --entrypoint=bash -it temporary_image
Donc, je pense que la réponse est simple que beaucoup de réponses trompeuses ci-dessus.
Pour démarrer un conteneur qui est arrêté
docker start <container-name/ID>
Pour arrêter un conteneur en cours d'exécution
docker stop <container-name/ID>
Ensuite, pour vous connecter au shell interactif d'un conteneur
docker exec -it <container-name/ID> bash
Certaines des réponses ici sont trompeuses parce qu'elles concernent des conteneurs qui fonctionnent, pas arrêtés.
Sven Dowideit a expliqué sur le forum Docker que les conteneurs sont liés à leur processus (et Docker ne peut pas changer le processus d'un conteneur arrêté, apparemment en raison au moins de sa structure interne: https://github.com/docker/docker/issues/1437). donc, fondamentalement, la seule option est de commit
le conteneur à une image et run
avec une commande Différente.
Voir https://forums.docker.com/t/run-command-in-stopped-container/343
(Je crois que l'approche" ENTRYPOINT
with arguments " ne fonctionnerait pas non plus, puisque vous ne seriez toujours pas en mesure de changer les arguments en un conteneur arrêté.)
J'ai dû utiliser bash-c pour exécuter ma commande:
docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"
Créer un conteneur et lui envoyer des commandes, une par une:
docker create --name=my_new_container -it ubuntu
docker start my_new_container
// ps -a says 'Up X seconds'
docker exec my_new_container /path/to/my/command
// ps -a still says 'Up X+Y seconds'
docker exec my_new_container /path/to/another/command
C'est une réponse combinée que j'ai composée en utilisant la réponse CDR LDN ci-dessus et la réponse que j'ai trouvée ici.
L'exemple suivant démarre un conteneur Arch Linux à partir d'une image, puis installe git
sur ce conteneur à l'aide de l'outil pacman
:
sudo docker run -it -d archlinux /bin/bash
sudo docker ps -l
sudo docker exec -it [container_ID] script /dev/null -c "pacman -S git --noconfirm"
C'est tout.
En supposant que l'image utilise le point d'entrée par défaut /bin/sh -c
, l'exécution de {[1] } se termine immédiatement en mode démon (-d
). Si vous voulez que ce conteneur exécute un shell interactif, utilisez -it
au lieu de -d
. Si vous souhaitez exécuter des commandes arbitraires dans un conteneur exécutant généralement un autre processus, vous pouvez essayer nsenter
ou nsinit
. Jetez un oeil à https://blog.codecentric.de/en/2014/07/enter-docker-container/ pour les détails.
Malheureusement, il est impossible de remplacer ENTRYPOINT
avec des arguments avec docker run --entrypoint
pour atteindre cet objectif.
REMARQUE: Vous pouvez remplacer le paramètre ENTRYPOINT en utilisant --entrypoint, mais cela ne peut définir le binaire sur exec (aucun sh-c ne sera utilisé).
Rediriger une commande vers stdin
Devez supprimer les -t
pour que cela fonctionne:
echo 'touch myfile' | sudo docker exec -i CONTAINER_NAME bash
Cela peut être plus pratique que d'utiliser parfois des options CLI.
Testé avec:
sudo docker run --name ub16 -it ubuntu:16.04 bash
Puis sur un autre shell:
echo 'touch myfile' | sudo docker exec -i ub16 bash
Puis sur le premier shell:
ls -l myfile
Sur Docker 1.13.1, Ubuntu 16.04 hôte.
Réponse Simple: démarrer et attacher en même temps. Dans ce cas, vous faites exactement ce que vous avez demandé.
docker start <CONTAINER_ID/CONTAINER_NAME> && docker attach <CONTAINER_ID/CONTAINER_NAME>
Assurez-vous de changer <CONTAINER_ID/CONTAINER_NAME>