Eine Shell öffnen: docker exec
docker ps
docker exec -it web sh
-i hält die Eingabe offen und -t gibt Ihnen ein Terminal. Ersetzen Sie web durch den Namen aus docker ps. Nehmen Sie bash, wenn das Image es hat. Nützliche Optionen:
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
Mit Podman funktionieren dieselben Befehle, wenn Sie podman statt docker schreiben.
Auf einem entfernten Server
Verbinden Sie sich per SSH mit dem Host, nicht mit dem Container. Um das in einem Schritt zu erledigen, fordern Sie mit -t ein Terminal an:
ssh -t user@server docker exec -it web sh
Ohne -t brechen neuere Docker-Versionen mit cannot attach stdin to a TTY-enabled container because stdin is not a terminal ab, ältere mit the input device is not a TTY. Für mehr als einen Befehl melden Sie sich einfach zuerst am Server an.
Ein kurzer Name für den Server spart hier Tipparbeit: siehe Beispiele für die SSH-Konfigurationsdatei.
Häufige Fehler
Keine Shell im Image:
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH
Versuchen Sie sh. Alpine-Images haben sh und kein bash. Kommt mit sh derselbe Fehler, hat das Image gar keine Shell, was bei minimalen Images üblich ist. Starten Sie dann einen Hilfs-Container, der Prozess- und Netzwerksicht mit dem Ziel teilt:
docker run --rm -it --pid=container:web --network=container:web alpine sh
Von dort zeigt ps die Prozesse des anderen Containers.
Container angehalten:
Error response from daemon: container 962d0cc0707e... is not running
In einen angehaltenen Container können Sie nicht per exec hinein. Lesen Sie nach, warum er angehalten wurde, und kopieren Sie Dateien heraus, falls Sie sie brauchen. docker cp funktioniert auch bei einem angehaltenen Container:
docker logs web
docker cp web:/etc/hostname .
Ein entferntes Docker vom Laptop aus steuern
Der Docker-Client kann über SSH mit einem entfernten Daemon sprechen, sodass docker ps und docker exec auf Ihrem Laptop auf dem Server wirken. Es wird kein Docker-Port geöffnet, nur SSH wird benutzt:
DOCKER_HOST=ssh://user@server docker ps
DOCKER_HOST=ssh://user@server docker exec -it web sh
Um das dauerhaft zu machen, legen Sie einen Context an:
docker context create --docker host=ssh://user@server remote
docker --context remote ps
Sie brauchen eine funktionierende Schlüssel-Anmeldung am Server, einen Docker-Client auf dem Laptop und einen Server-Benutzer, der den Docker-Socket nutzen darf. Bedenken Sie, dass Zugriff auf den Docker-Daemon fast Root-Rechten auf dieser Maschine entspricht: Laut Dokumentation von Docker sollten ihn nur vertrauenswürdige Benutzer haben.
Jeder Befehl öffnet eine neue Verbindung, deshalb empfiehlt Docker, in ~/.ssh/config eine Verbindung wiederzuverwenden. Siehe SSH-Multiplexing.
Wann sshd im Container sinnvoll ist
Nur, wenn SSH selbst der Zweck ist:
- Ein Testserver für SSH-Clients, Skripte oder Ansible.
- Ein Werkzeug, das nur über SSH oder SFTP etwas erreicht und das Sie nicht ändern können.
- Ein Jump-Host oder eine SFTP-Ablage, die Sie bewusst als Container betreiben.
Um zur Fehlersuche hineinzukommen, fügt es einen Dienst, einen Schlüssel und einen offenen Port hinzu, und docker exec erledigt diese Aufgabe schon. Wenn Sie es doch brauchen, läuft das hier und meldet sich mit einem Schlüssel an:
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
Drei Details sind wichtig:
- Host-Schlüssel entstehen beim Start, nicht im Image. Sonst teilt sich jeder Container aus dem Image denselben privaten Host-Schlüssel. Der Nachteil ist ein neuer Schlüssel bei jedem neu erstellten Container, was die Host-Key-Warnung auslöst. Legen Sie
/etc/sshin ein Volume, wenn das wichtig ist. - Der Port ist an 127.0.0.1 gebunden. Veröffentlichte Ports umgehen ufw. Laut Dokumentation von Docker wird der Verkehr umgeleitet, bevor er die Regeln von ufw erreicht, sodass
-p 2222:22auch bei aktiviertem ufw für die ganze Welt offen sein kann. - Dieses Image enthält keine Geheimnisse.
authorized_keysenthält nur öffentliche Schlüssel. Kopieren Sie niemals einen privaten Schlüssel in ein Image.
Fragen
Braucht docker exec SSH?
Nein. Der Befehl docker spricht mit dem Docker-Daemon, der den Prozess im Container startet.
Wie öffne ich eine Shell im Container als root?
Mit -u root: docker exec -it -u root web sh. Das klappt auch, wenn das Image als anderer Benutzer läuft.
Wie komme ich in einen Container auf einem Remote-Server?
Melden Sie sich per SSH an dem Server an, auf dem er läuft, und nutzen Sie docker exec. In einem Schritt: ssh -t user@server docker exec -it web sh.
Überlebt eine mit docker exec gestartete Shell einen Neustart des Containers?
Nein. Sie läuft nur, solange der Hauptprozess des Containers läuft, und wird beim Neustart des Containers nicht wieder gestartet.
Quellen
- docker container exec, Docker Docs
- Protect the Docker daemon socket, Docker Docs
- Docker security, Docker Docs
- Packet filtering and firewalls, Docker Docs