Comment se connecter en SSH à un conteneur Docker

Vous n'en avez presque jamais besoin. Lancez docker exec -it web sh sur la machine où tourne le conteneur, ou ssh -t user@server docker exec -it web sh depuis ailleurs. Un conteneur n'a normalement pas de serveur SSH, et en ajouter un vaut rarement la peine. Pour piloter un Docker distant depuis votre portable, utilisez DOCKER_HOST=ssh://user@server.

Mis à jour le . Les options de docker exec, les messages d'erreur, le shell en conteneur auxiliaire et le Dockerfile de sshd ont été exécutés avec Docker sur Linux. Les erreurs d'exec, le conteneur auxiliaire et docker cp ont été revérifiés avec Docker 29.5.

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/ssh dans 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:22 peut donc être ouvert au monde même avec ufw actif.
  • Cette image ne contient aucun secret. authorized_keys ne 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

Autres guides : SSH sur chaque système

Tous les guides