Obtenir un shell : docker exec
docker ps
docker exec -it web sh
-i garde l'entrée ouverte et -t vous donne un terminal. Remplacez web par le nom affiché par docker ps. Utilisez bash si l'image l'a. Options utiles :
docker exec -it -u root web sh # as another user
docker exec -it -w /app web sh # in another folder
docker exec -e DEBUG=1 web env # with an extra variable
docker compose exec web sh # with Compose: no -it needed
Avec Podman, les mêmes commandes fonctionnent en écrivant podman à la place de docker.
Sur un serveur distant
Connectez-vous en SSH à l'hôte, pas au conteneur. Pour le faire en une seule étape, demandez un terminal avec -t :
ssh -t user@server docker exec -it web sh
Sans -t, les versions récentes de Docker s'arrêtent avec cannot attach stdin to a TTY-enabled container because stdin is not a terminal, les plus anciennes avec the input device is not a TTY. Pour plus d'une commande, connectez-vous simplement d'abord au serveur.
Un nom court pour le serveur évite de tout retaper : voyez des exemples de fichier de configuration SSH.
Erreurs courantes
Pas de shell dans l'image :
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH
Essayez sh. Les images Alpine ont sh et pas bash. Si sh donne la même erreur, l'image n'a aucun shell, ce qui est fréquent pour les images minimales. Lancez un conteneur auxiliaire qui partage sa vue des processus et du réseau :
docker run --rm -it --pid=container:web --network=container:web alpine sh
De là, ps affiche les processus de l'autre conteneur.
Conteneur arrêté :
Error response from daemon: container 962d0cc0707e... is not running
On ne peut pas faire d'exec dans un conteneur arrêté. Lisez pourquoi il s'est arrêté, et copiez-en les fichiers si besoin. docker cp fonctionne aussi sur un conteneur arrêté :
docker logs web
docker cp web:/etc/hostname .
Piloter un Docker distant depuis votre portable
Le client Docker peut parler à un démon distant via SSH : docker ps et docker exec sur votre portable agissent alors sur le serveur. Aucun port Docker n'est ouvert, seul SSH est utilisé :
DOCKER_HOST=ssh://user@server docker ps
DOCKER_HOST=ssh://user@server docker exec -it web sh
Pour le conserver, créez un contexte :
docker context create --docker host=ssh://user@server remote
docker --context remote ps
Il vous faut une connexion par clé fonctionnelle vers le serveur, un client Docker sur votre portable, et un utilisateur du serveur autorisé à utiliser le socket Docker. Sachez que l'accès au démon Docker équivaut presque à root sur cette machine : la documentation de Docker dit que seuls des utilisateurs de confiance devraient l'avoir.
Chaque commande ouvre une nouvelle connexion, c'est pourquoi Docker suggère d'en réutiliser une dans ~/.ssh/config. Voir le multiplexage SSH.
Quand sshd dans un conteneur se justifie
Seulement quand SSH lui-même est le but :
- Un serveur de test pour des clients SSH, des scripts ou Ansible.
- Un outil qui ne peut atteindre les choses que par SSH ou SFTP, et que vous ne pouvez pas modifier.
- Un hôte de rebond ou un dépôt SFTP que vous faites volontairement tourner dans un conteneur.
Pour entrer et déboguer quelque chose, cela ajoute un service, une clé et un port ouvert, alors que docker exec fait déjà le travail. Si vous en avez vraiment besoin, ceci se lance et accepte la connexion par clé :
FROM debian:13-slim
RUN apt-get update && apt-get install -y --no-install-recommends openssh-server \
&& rm -f /etc/ssh/ssh_host_* \
&& useradd -m -s /bin/bash app && mkdir -p /run/sshd \
&& install -d -m 700 -o app -g app /home/app/.ssh
COPY authorized_keys /home/app/.ssh/authorized_keys
RUN chown app:app /home/app/.ssh/authorized_keys && chmod 600 /home/app/.ssh/authorized_keys
CMD ["sh", "-c", "ssh-keygen -A && exec /usr/sbin/sshd -D -e -o PasswordAuthentication=no"]
docker build -t sshd-demo .
docker run -d --name sshd-demo -p 127.0.0.1:2222:22 sshd-demo
ssh -p 2222 app@127.0.0.1
Trois détails comptent ici :
- Les clés d'hôte sont créées au démarrage, pas dans l'image. Sinon, tous les conteneurs issus de l'image partagent la même clé d'hôte privée. L'inconvénient est une nouvelle clé à chaque recréation du conteneur, ce qui déclenche l'avertissement de clé d'hôte. Gardez
/etc/sshdans un volume si cela compte. - Le port est lié à 127.0.0.1. Les ports publiés contournent ufw. La documentation de Docker indique que le trafic est dévié avant d'atteindre les règles d'ufw :
-p 2222:22peut donc être ouvert au monde même avec ufw actif. - Cette image ne contient aucun secret.
authorized_keysne contient que des clés publiques. Ne copiez jamais une clé privée dans une image.
Questions
docker exec a-t-il besoin de SSH ?
Non. La commande docker parle au démon Docker, qui démarre le processus dans le conteneur.
Comment ouvrir un shell dans un conteneur en root ?
Ajoutez -u root : docker exec -it -u root web sh. Cela marche même si l'image tourne avec un autre utilisateur.
Comment entrer dans un conteneur sur un serveur distant ?
Connectez-vous en SSH au serveur qui le fait tourner, puis utilisez docker exec. En une seule étape : ssh -t user@server docker exec -it web sh.
Un shell lancé avec docker exec survit-il au redémarrage du conteneur ?
Non. Il ne tourne que tant que le processus principal du conteneur tourne, et il n'est pas relancé quand le conteneur redémarre.
Sources
- docker container exec, Docker Docs
- Protect the Docker daemon socket, Docker Docs
- Docker security, Docker Docs
- Packet filtering and firewalls, Docker Docs