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.

340
demandé sur Peter Mortensen 2014-10-02 06:34:25

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 .

400
répondu Scadge 2017-04-26 15:48:17

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.

248
répondu cdrev 2015-02-01 20:10:51

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
80
répondu Aaron V 2017-02-03 17:25:12

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
62
répondu Peter T. 2017-03-16 10:15:05

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é.)

37
répondu katrmr 2015-03-30 23:38:29

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"

13
répondu velop 2016-05-25 14:29:38

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
12
répondu stackoverflowwww 2016-07-11 13:36:50

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.

6
répondu imriss 2015-06-30 17:24:53

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.

2
répondu Andreas Steffan 2014-10-02 07:38:13

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é).

2
répondu wieczorek1990 2016-11-03 13:34:46

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.

1

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>

0
répondu user353305 2016-12-19 19:21:18