web-dev-qa-db-fra.com

Comment exécuter une commande sur un conteneur Docker déjà existant?

J'ai créé un conteneur avec -d afin qu'il ne soit 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 avoir la réponse.

J'ai essayé de démarrer la machine. J'ai essayé d'attacher. Je pensais pouvoir appeler run avec un conteneur, mais cela ne semble pas être autorisé. Utiliser start semble simplement fonctionner puis exister rapidement.

Je voudrais revenir en mode interactif après avoir quitté.

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 lance, il se termine quand même. Catch 22. Je ne peux pas gagner.

372
Johnston

En octobre 2014, l'équipe Docker a introduit la commande docker exec : https://docs.docker.com/engine/reference/commandline/exec/

Alors maintenant, vous pouvez exécuter n’importe quelle commande d’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 un 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 sera pas arrêté immédiatement.

439
Scadge

Votre conteneur va quitter comme la commande que vous lui avez donnée va se terminer. Utilisez les options suivantes pour le garder actif:

  • -i Laissez STDIN ouvert même s'il n'est pas connecté.
  • -t Allouer un pseudo-ATS.

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.

265
cdrev

Pour développer la réponse de katrmr, si le conteneur est arrêté et ne peut pas être démarré à cause d'une erreur, vous devez le nommer commit en une image. Ensuite, vous pouvez lancer bash dans la nouvelle image:

docker commit [CONTAINER_ID] temporary_image
docker run --entrypoint=bash -it temporary_image
85
Aaron V

Donc, je pense que la réponse est simple que beaucoup de réponses trompeuses précédentes.

Pour démarrer un conteneur existant qui est arrêté

docker start <container-name/ID>

Pour arrêter un conteneur en cours d'exécution

docker stop <container-name/ID>

Puis vous connecter au shell interactif d'un conteneur

docker exec -it <container-name/ID> bash
74
Peter T.

Certaines réponses sont trompeuses car elles concernent des conteneurs en cours d’exécution et non arrêtés.

Sven Dowideit a expliqué sur le forum Docker que les conteneurs sont liés à leur processus (et que Docker ne peut pas modifier le processus d’un conteneur arrêté, apparemment du moins à sa structure interne: https://github.com/docker/docker/issues/1437 ). Donc, la seule option possible est de commit le conteneur en 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 avec arguments" ne fonctionnerait pas non plus, car vous ne seriez toujours pas en mesure de changer les arguments en un conteneur arrêté.)

38
katrmr

Je devais utiliser bash -c pour exécuter ma commande: docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"

16
velop

Créer un conteneur et lui envoyer des commandes une à 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
13
stackoverflowwww

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.

7
imriss

Pipe une commande à stdin

Doit supprimer le -t pour que cela fonctionne:

echo 'touch myfile' | Sudo docker exec -i CONTAINER_NAME bash

Cela peut être plus pratique qu'en utilisant parfois les options de la 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 le premier Shell:

ls -l myfile

sur Docker 1.13.1, hôte Ubuntu 16.04.

Si vous essayez d'exécuter un script shell, vous devez l'exécuter en tant que bash (basé sur la réponse velop).

docker exec -it containerid bash -c /path/to/your/script.sh
2
MrKulli

Malheureusement, il est impossible de remplacer ENTRYPOINT par des arguments avec docker run --entrypoint pour atteindre cet objectif.

Remarque: vous pouvez remplacer le paramètre ENTRYPOINT à l’aide de --entrypoint, mais cela ne peut que définir le binaire sur exec (aucun sh -c ne sera utilisé).

2
wieczorek1990

En supposant que l'image utilise le point d'entrée par défaut /bin/sh -c, l'exécution de /bin/bash se terminera immédiatement en mode démon (-d). Si vous souhaitez 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 en exécutant généralement un autre processus, vous pouvez également essayer nsenter ou nsinit. Consultez https://blog.codecentric.de/fr/2014/07/enter-docker-container/ pour plus de détails.

2
Andreas Steffan

Je l'ai fait pour mon conteneur noeud-rouge et résolu mon problème:

NODEREDNAME=mynodered
# Create a new node red container
docker run -it -p 1880:1880 -v "$(pwd)/data":/data --name $NODEREDNAME -d nodered/node-red-docker

# Open a Shell in the container (THAT ANSWERS THE QUESTION)
docker exec -it $NODEREDNAME bash -c "cd /data & npm install node-red-node-mongodb"

# Restart the container to load the new nodes
docker stop $NODEREDNAME
docker start $NODEREDNAME
1
Ângelo Polotto

J'utilise un conteneur Windows et je dois rechercher à l'intérieur du conteneur docker les fichiers et les dossiers créés et copiés.

Afin de faire cela, j'ai utilisé la commande suivante docker entrypoint pour obtenir l'invite de commande s'exécutant à l'intérieur du conteneur ou l'attacher au conteneur.

ENTRYPOINT ["C:\\Windows\\System32\\cmd.exe", "-D", "FOREGROUND"]

Cela m'a aidé à la fois Invite de commande attacher au conteneur et de garder le conteneur en vie. :)

0
Jenish Rabadiya

Pour Mac:

$ docker exec -it <container-name> sh

si vous voulez vous connecter en tant qu'utilisateur root:

$ docker exec -u 0 -it <container-name> sh
0
Lyncean Patel

Réponse simple: démarrez et attachez 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
user353305
# docker exec -d container_id command 

Ex:

# docker exec -d xcdefrdtt service jira stop 
0
Rajesh Gurram