Comment accéder au shell d'un conteneur Docker?

1163

Je commence à travailler avec Docker. J'utilise l'image de base WordPress et docker-compose.

J'essaie de ssh dans l'un des conteneurs pour inspecter les fichiers / répertoires qui ont été créés lors de la construction initiale. J'ai essayé de courir docker-compose run containername ls -la, mais cela n'a rien fait. Même si c'est le cas, je préfère avoir une console où je peux parcourir la structure de répertoires, plutôt que d'exécuter une seule commande. Quelle est la bonne façon de procéder avec Docker?

Andrew
la source
Il semble donc que la réponse soit Docker Attach. Mais comment puis-je y accéder depuis docker-compose?
Andrew
3
Utilisez docker exec askubuntu.com/a/543057/35816 . Obtenez l'identifiant du conteneur en utilisantdocker ps
Mauricio Scheffer
26
sudo docker run -it --entrypoint /bin/bash <container_name>vous met dans le conteneur de manière interactive. Ensuite, on peut inspecter le système de fichiers dans le conteneur en utilisantcd <path>
Sergei

Réponses:

1737

docker attachvous permettra de vous connecter à votre conteneur Docker, mais ce n'est pas vraiment la même chose que ssh. Si votre conteneur exécute un serveur Web, par exemple, docker attachil vous connectera probablement à la sortie standard du processus de serveur Web. Cela ne vous donnera pas nécessairement un coquillage.

La docker execcommande est probablement ce que vous recherchez; cela vous permettra d'exécuter des commandes arbitraires dans un conteneur existant. Par exemple:

docker exec -it <mycontainer> bash

Bien entendu, la commande que vous exécutez doit exister dans le système de fichiers du conteneur.

Dans la commande ci-dessus se <mycontainer>trouve le nom ou l'ID du conteneur cible. Peu importe que vous utilisiez ou non docker compose; il suffit d'exécuter docker pset d'utiliser soit l'ID (une chaîne hexadécimale affichée dans la première colonne) ou le nom (affiché dans la dernière colonne). Par exemple, étant donné:

$ docker ps
d2d4a89aaee9        larsks/mini-httpd   "mini_httpd -d /cont   7 days ago          Up 7 days                               web                 

Je peux courir:

$ docker exec -it web ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever

Je pourrais accomplir la même chose en exécutant:

$ docker exec -it d2d4a89aaee9 ip addr

De même, je pourrais démarrer un shell dans le conteneur;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$
larsks
la source
76
En outre, docker execne fonctionne que sur les conteneurs en cours d'exécution (sinon utiliser docker run -it --entrypoint /bin/bashou similaire).
L0j1k
59
pour votre commodité, -itest une combinaison de -iet -tqui est --interactive("Garder STDIN ouvert même s'il n'est pas attaché") respectivement --tty("Allouer un pseudo-ATS").
Adrian Föder
23
Sur les conteneurs basés sur Linux alpin, vous pourriez ne pas avoir bash, donc si c'est le cas, utilisez plutôt sh.
Robin Green
9
@ L0j1k c'est docker run -it --entrypoint /bin/bash <imageid> --any --more --args, juste pour clarifier pour les gens
Alexander Mills
2
@AlexanderMills Oui, et de préciser davantage, ceux que --any --more --argsvous avez seront intégrés dans ce que l'image a défini comme CMDet non Docker (ou si votre image définit seulement une ENTRYPOINTet pas CMD, alors ces options sera alimenté en /bin/bashtant que vous avez spécifié ici ). Ainsi, par exemple, toutes les autres docker runoptions (par exemple --net "host") doivent précéder le <imageid>.
L0j1k
302

Pour bash dans un conteneur en cours d'exécution, tapez ceci:

docker exec -t -i container_name /bin/bash

ou

docker exec -ti container_name /bin/bash

ou

docker exec -ti container_name sh
Agustí Sánchez
la source
En supposant qu'il s'agit d'un conteneur Linux?
Peter Mortensen
5
/ bin / bash n'était pas nécessaire, juste bash l'a fait pour moi
Anand Varkey Philips
6
Je préférerais docker exec -itau lieu dedocker exec -t -i
VaTo
quelle est la différence @VaTo
AATHITH RAJENDRAN
@AATHITHRAJENDRANI préfère simplement une forme plus courte de la commande au lieu d'avoir deux drapeaux, vous pouvez inclure ces deux options dans le même argument -it.
VaTo
85

Disons que, pour des raisons qui vous sont propres, vous voulez vraiment utiliser SSH. Cela prend quelques étapes, mais cela peut être fait. Voici les commandes que vous exécuteriez à l'intérieur du conteneur pour le configurer ...

apt-get update
apt-get install openssh-server

mkdir /var/run/sshd
chmod 0755 /var/run/sshd
/usr/sbin/sshd

useradd --create-home --shell /bin/bash --groups sudo username ## includes 'sudo'
passwd username ## Enter a password

apt-get install x11-apps ## X11 demo applications (optional)
ifconfig | awk '/inet addr/{print substr($2,6)}' ## Display IP address (optional)

Maintenant, vous pouvez même exécuter des applications graphiques (si elles sont installées dans le conteneur) à l'aide du transfert X11 vers le client SSH:

ssh -X username@IPADDRESS
xeyes ## run an X11 demo app in the client

Voici quelques ressources connexes:

nobar
la source
34

Si vous êtes ici à la recherche d'une réponse spécifique à Docker Compose comme je l'ai été, cela vous permet d'accéder facilement sans avoir à rechercher l'ID de conteneur généré.

docker-compose execprend le nom du service selon votre docker-compose.ymlfichier.

Donc, pour obtenir un shell Bash pour votre service 'web', vous pouvez faire:

$ docker-compose exec web bash
bcmcfc
la source
docker-compose runfonctionne également si votre conteneur n'existe pas encore.
Paul
23

Remarque : cette réponse fait la promotion d'un outil que j'ai écrit.

J'ai créé un serveur SSH conteneurisé que vous pouvez «coller» à n'importe quel conteneur en cours d'exécution. De cette façon, vous pouvez créer des compositions avec chaque conteneur. La seule exigence est que le conteneur ait Bash.

L'exemple suivant démarrerait un serveur SSH attaché à un conteneur avec le nom 'mon-conteneur'.

docker run -d -p 2222:22 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINER=my-container -e AUTH_MECHANISM=noAuth \
  jeroenpeeters/docker-ssh

ssh localhost -p 2222

Lorsque vous vous connectez à ce service SSH (avec le client SSH de votre choix), une session Bash est lancée dans le conteneur avec le nom «mon-conteneur».

Pour plus de pointeurs et de documentation, voir: https://github.com/jeroenpeeters/docker-ssh

Jeroen Peeters
la source
1
C'est plutôt mignon. Le gros avantage de procéder de cette façon est que vous obtenez un terminal entièrement fonctionnel. Lorsque j'ai utilisé l'approche "docker exec", je n'ai pas pu effacer le contenu du terminal, lessje montrais un avertissement à chaque fois que je l'exécutais, etc. L'utilisation du conteneur de Jeroen me donne une bien meilleure expérience jusqu'à présent. Assurez-vous simplement de consulter la documentation . L'exemple de commande dans la réponse ne semble plus valide.
Rafał G.18
1
c'est un excellent outil. Savez-vous comment puis-je l'utiliser comme agent docker jenkins pipeline? Je veux que jenkins transfère certains fichiers par SCP vers un hôte distant et les exécute avec SSH
Gilson
21

Si vous utilisez Docker sous Windows et souhaitez obtenir un accès shell à un conteneur, utilisez ceci:

winpty docker exec -it <container_id> sh

Très probablement, vous avez déjà installé Git Bash . Sinon, assurez-vous de l'installer.

Cosmin Ababei
la source
1
Suppose un conteneur Linux Docker?
Peter Mortensen
1
docker exec -ti <container_id> cmd fonctionne bien
PBo
17

Si le conteneur est déjà sorti (peut-être en raison d'une erreur), vous pouvez le faire

$ docker run --rm -it --entrypoint /bin/ash image_name

ou

$ docker run --rm -it --entrypoint /bin/sh image_name

ou

$ docker run --rm -it --entrypoint /bin/bash image_name

pour créer un nouveau conteneur et y mettre un shell. Puisque vous avez spécifié --rm, le conteneur sera supprimé lorsque vous quittez le shell.

user674669
la source
16

Dans certains cas, votre image peut être basée sur les Alpes. Dans ce cas, il lancera:

Échec de l'exécution du runtime OCI: échec de l'exécution: container_linux.go: 348: le démarrage du processus de conteneur a provoqué "exec: \" bash \ ": fichier exécutable introuvable dans $ PATH": inconnu

Parce que /bin/bashça n'existe pas. Au lieu de cela, vous devez utiliser:

docker exec -it 9f7d99aa6625 ash

ou

docker exec -it 9f7d99aa6625 sh
Désoxyseia
la source
15

SSH dans un conteneur Docker à l'aide de cette commande:

sudo docker exec -i -t (container ID) bash
Tjs
la source
12

Pour vous connecter à cmd dans un conteneur Windows, utilisez

docker exec -it d8c25fde2769 cmd

d8c25fde2769 est l'ID du conteneur.

Aqeel Qureshi
la source
11

C'est simple !

Listez toutes vos images Docker:

sudo docker images

Sur mon système, il a montré la sortie suivante:

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
bash                latest              922b9cc3ea5e        9 hours ago
14.03 MB
ubuntu              latest              7feff7652c69        5 weeks ago         81.15 MB

J'ai deux images Docker sur mon PC. Disons que je veux exécuter le premier.

sudo docker run -i -t ubuntu:latest /bin/bash

Cela vous donnera un contrôle terminal du conteneur. Vous pouvez maintenant effectuer tout type d'opérations shell à l'intérieur du conteneur. Comme faire ls, tous les dossiers seront affichés à la racine du système de fichiers.

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
Patel Sunil
la source
11

Pour inspecter les fichiers, exécutez docker run -it <image> /bin/shpour obtenir un terminal interactif. La liste des images peut être obtenue par docker images. Contrairement à docker execcette solution, cela fonctionne également dans le cas où une image ne démarre pas (ou se ferme immédiatement après l'exécution).

je vais
la source
Présumer une image Linux Docker?
Peter Mortensen
10

SOLUTION GOINSIDE

installer l' goinsideoutil de ligne de commande avec:

sudo npm install -g goinside

et entrez dans un conteneur docker avec une taille de terminal appropriée avec:

goinside docker_container_name

ancienne réponse

Nous avons mis cet extrait dans ~/.profile:

goinside(){
    docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside

Non seulement cela permet à tout le monde de pénétrer dans un conteneur en cours d'exécution avec:

goinside containername

Il résout également un problème de longue durée concernant les tailles fixes de terminaux à conteneurs Docker . Ce qui est très ennuyeux si vous y faites face.

De plus, si vous suivez le lien, vous obtiendrez également la fin de la commande pour les noms de vos conteneurs Docker.

Soorena
la source
1
Merci. Cela fonctionne comme un charme, au moins pour les images qui ont déjà inclus bash. Peut ne pas fonctionner pour les images alpines, mais peut être corrigé avec une fonction différente spécifiquement écrite pour sh / ash, etc.
Gaurav Bhaskar
8
$ docker exec -it <Container-Id> /bin/bash

Ou selon la coque, il peut être

$ docker exec -it <Container-Id> /bin/sh

Vous pouvez obtenir le container-Id via la docker pscommande

-i = interactif

-t = pour allouer un pseudo-ATS

Ashutosh Chamoli
la source
8

J'ai créé une fonction de terminal pour un accès plus facile au terminal du conteneur. Peut-être que cela vous est également utile:

Le résultat est donc, au lieu de taper:

docker exec -it [container_id] /bin/bash

vous écrirez:

dbash [container_id]

Mettez ce qui suit dans votre ~ / .bash_profile (ou tout ce qui vous convient), puis ouvrez une nouvelle fenêtre de terminal et profitez du raccourci:

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}
Gars
la source
7

vous pouvez interagir avec le terminal dans le conteneur docker en passant l'option -ti

docker run --rm -ti <image-name>
eg: docker run --rm -ti ubuntu

-t signifie terminal -i signifie interactif

Alwin
la source
6

docker execsera certainement une solution. Un moyen facile de travailler avec la question que vous avez posée est de monter le répertoire dans Docker dans le répertoire du système local .

Pour que vous puissiez visualiser instantanément les modifications du chemin local.

docker run -v /Users/<path>:/<container path> 
Pratik
la source
1
votre commande monte en fait le répertoire de l'hôte dans le conteneur.
Demonbane
Ouais! Effectuez une sauvegarde dans un autre répertoire, puis montez le volume, puis déplacez la sauvegarde vers le dossier monté.
Pratik
6

Utilisation:

docker attach <container name/id here>

L'autre façon, bien qu'il y ait un danger, est d'utiliser attach, mais si vous Ctrl+ Cpour quitter la session, vous arrêterez également le conteneur. Si vous voulez simplement voir ce qui se passe, utilisez docker logs -f.

:~$ docker attach --help
Usage:  docker attach [OPTIONS] CONTAINER

Attach to a running container

Options:
      --detach-keys string   Override the key sequence for detaching a container
      --help                 Print usage
      --no-stdin             Do not attach STDIN
      --sig-proxy            Proxy all received signals to the process (default true)
rbrooker
la source
6

Utilisez cette commande:

docker exec -it containerid /bin/bash
Admin Hack
la source
4

Si Docker est installé avec Kitematic, vous pouvez utiliser l'interface graphique. Ouvrez à Kitematicpartir de l'icône Docker et dans la Kitematicfenêtre, sélectionnez votre conteneur, puis cliquez sur l' execicône.

Vous pouvez également voir le journal du conteneur et de nombreuses informations sur le conteneur (dans l'onglet Paramètres) dans cette interface graphique.

Sélectionnez Kitematic dans le menu

Cliquez sur exec

Alireza Fattahi
la source
2

Dans mon cas, pour une ou plusieurs raisons, je dois vérifier toutes les informations réseau impliquées dans chaque conteneur. Les commandes suivantes doivent donc être valides dans un conteneur ...

ip
route
netstat
ps
...

J'ai vérifié toutes ces réponses, aucune ne m'a été utile. J'ai recherché des informations sur d'autres sites Web. Je n'ajouterai pas de super lien ici, car il n'est pas écrit en anglais. Je viens donc de mettre en place ce poste avec une solution récapitulative pour les personnes qui ont les mêmes exigences que moi.

Supposons que vous ayez un conteneur en cours d'exécution nommé light-test. Suivez les étapes ci-dessous.

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}. Cette commande recevra une réponse comme /var/run/docker/netns/xxxx.
  • Alors ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx. Le répertoire peut ne pas exister, faites d' mkdir /var/run/netnsabord.
  • Vous pouvez maintenant exécuter ip netns exec xxxx ip addr showpour explorer le monde du réseau en conteneur.

PS. xxxxest toujours la même valeur reçue de la première commande. Et bien sûr, toutes les autres commandes sont valides, c'est-à-dire ip netns exec xxxx netstat -antp|grep 8080.

Light.G
la source
1

Une autre option consiste à utiliser nsenter .

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid
xuhdev
la source
2
Il y a un certain nombre de problèmes avec nsenter. Le premier est qu'il nécessite que vous ayez un accès physique à l'hôte docker, ce qui n'est pas une donnée (vous travaillez peut-être avec une API docker distante). En outre, l'exécution sous nsentervous exempte de plusieurs des restrictions de sécurité et de ressources que Docker met en place (qui peuvent être un pro ou un con, selon votre environnement).
larsks
1
Même l'auteur de nsenter dit d'utiliser docker execces jours-ci.
L0j1k
1
@larsks Oui, les deux ont leurs propres avantages. Par exemple, celui-ci est un avantage de nsenter sur docker exec. docker execme semble plus élégant.
xuhdev
2
@ L0j1k Juste pour être moins déroutant: le post que vous avez référé n'est pas l'auteur de nsenter, mais l'auteur d'une image Docker qui exécute nsenter.
xuhdev
1

Si vous utilisez Docker Compose, cela vous amènera à l'intérieur d'un conteneur Docker.

docker-compose run container_name /bin/bash

À l'intérieur du conteneur, il vous amènera à WORKDIR défini dans le Dockerfile. Vous pouvez modifier votre répertoire de travail en

WORKDIR directory_path # E.g  /usr/src -> container's path
Sivakumar
la source
0

Pour exécuter dans un conteneur en cours d'exécution nommé test, voici les commandes suivantes

Si le conteneur a une bashcoque

docker exec -it test /bin/bash

Si le conteneur a une bournecoque et la plupart des cas, il est présent

docker run -it test /bin/sh
nischay goyal
la source
-3

Pour docker-compose up (Docker4Drupal)

docker-compose exec php bash

J'utilise Docker pour Drupal sur un ordinateur portable Linux. Après avoir exécuté le conteneur, j'utilise ' docker-compose exec php bash' pour me connecter au conteneur afin de pouvoir exécuter des commandos drush. Ça fonctionne bien pour moi.

illutek
la source