docker exec vs. docker attach: Der Unterschied, den viele falsch verstehen
AI generated
FROM
RUN
Docker · Container-Debugging · CLI
docker exec vs. docker attach
Ein falsches Kommando kann deinen Container beenden

docker exec und docker attach wirken auf den ersten Blick austauschbar, beide verschaffen Zugriff auf einen laufenden Container. Technisch handelt es sich jedoch um zwei grundverschiedene Mechanismen. Wer den Unterschied nicht kennt, riskiert im produktiven Betrieb, den Hauptprozess versehentlich zu beenden, nur weil ein Terminal geschlossen wurde.

14 Min. Lesezeit PID 1 & Signale TTY-Verhalten Sichere Debugging-Sessions

1. Zwei Wege in einen laufenden Container

Ein Container ist im Kern nichts anderes als ein isolierter Linux-Prozessbaum. Der Prozess, der beim Start mit ENTRYPOINT oder CMD ausgeführt wird, bekommt innerhalb des Containers die Prozess-ID 1 zugewiesen. Alles, was ein Entwickler danach zusätzlich in diesem Container erledigen möchte, muss sich entweder an genau diesen einen Prozess anhängen oder einen komplett neuen Prozess daneben starten. Genau das ist der Unterschied zwischen docker attach und docker exec, und er ist keine stilistische Feinheit, sondern betrifft die Prozessverwaltung des Kernels direkt.

docker exec erzeugt über die Namespace-APIs des Kernels einen völlig neuen Prozess innerhalb der Namespaces des Containers, ohne den ursprünglichen Hauptprozess zu berühren. docker attach hingegen öffnet lediglich die bestehenden Standard-Ein- und Ausgabeströme von PID 1 erneut und leitet sie an das aktuelle Terminal um. Es wird kein zusätzlicher Prozess erzeugt, sondern eine bereits existierende Verbindung wiederhergestellt. Diese Unterscheidung erklärt fast alle Überraschungen, die Einsteiger mit beiden Kommandos erleben.

2. Wie docker exec technisch funktioniert

Beim Aufruf von docker exec weist der Docker-Daemon den Container-Runtime (containerd bzw. runc) an, einen neuen Prozess in denselben Namespaces zu starten, in denen bereits PID 1 läuft: gleicher Netzwerk-Namespace, gleiches Dateisystem, gleiche Cgroup-Beschränkungen. Der neue Prozess bekommt dabei intern eine eigene, höhere PID, bleibt aber vollständig unabhängig vom Hauptprozess. Schließt man das Terminal oder beendet die Shell mit exit, stirbt nur dieser Nebenprozess, der Hauptprozess läuft unbeeindruckt weiter.

Das macht exec zum Standardwerkzeug für Debugging, Wartungsarbeiten und Health-Checks. Man kann beliebig viele parallele exec-Sitzungen öffnen, ohne den laufenden Betrieb zu stören. Wichtig ist dabei, dass der ausgeführte Befehl im Container tatsächlich existiert, andernfalls schlägt der Aufruf mit einem klaren Fehler fehl, ohne irgendeine Auswirkung auf PID 1 zu haben.


# Neue interaktive Shell im laufenden Container öffnen
docker exec -it webshop_app /bin/bash

# Einzelbefehl ausführen, ohne interaktive Shell
docker exec webshop_app php bin/magento cache:status

# Prozessliste zeigt zwei unabhängige PIDs
docker exec webshop_app ps aux
#   PID   USER  COMMAND
#     1   root  php-fpm: master process
#    47   root  bash

3. Wie docker attach an den Hauptprozess andockt

docker attach erzeugt keinen neuen Prozess, sondern verbindet das lokale Terminal direkt mit den Standard-Streams (stdin, stdout, stderr) von PID 1. Das ist genau der Mechanismus, den auch docker run ohne die Option -d intern nutzt, um die Ausgabe eines Containers live im Vordergrund anzuzeigen. Wer attach nutzt, sieht also exakt das, was der Hauptprozess selbst ausgibt, nicht mehr und nicht weniger.

Das ist bei einem Datenbankserver oder einem Webserver im Vordergrundmodus durchaus sinnvoll, etwa um Live-Logausgaben direkt am Prozess zu beobachten, ohne einen separaten Logging-Treiber zu konfigurieren. Problematisch wird es jedoch, sobald man versucht, mit dem Hauptprozess zu interagieren, ohne die Konsequenzen der Terminal-Kopplung zu verstehen.


# An den Hauptprozess des Containers andocken
docker attach webshop_db

# Verbindung ohne Signalweiterleitung trennen (empfohlen)
# Tastenkombination im Terminal: Strg+P gefolgt von Strg+Q

4. Warum attach den Container beenden kann

Der häufigste Fehler entsteht, wenn eine Entwicklerin oder ein Entwickler nach einer attach-Sitzung die Sitzung mit der gewohnten Tastenkombination Strg+C verlassen möchte. Da das Terminal direkt mit stdin von PID 1 verbunden ist, wird dieses Signal standardmäßig genau an diesen Prozess weitergereicht, nicht nur an die Terminal-Sitzung. Ein Webserver oder eine Datenbank interpretiert SIGINT in aller Regel als Aufforderung, sich sauber zu beenden, und der gesamte Container stoppt.

Der korrekte Weg, eine attach-Sitzung zu verlassen, ohne den Container zu beeinflussen, ist die Tastenkombination Strg+P gefolgt von Strg+Q, das sogenannte Detach-Sequence. Alternativ kann man die Signalweiterleitung beim Aufruf komplett deaktivieren, was insbesondere in Wartungsfenstern empfehlenswert ist, wenn Unsicherheit über das Verhalten des Ziel-Prozesses besteht.


# Signale werden NICHT an PID 1 weitergeleitet
docker attach --sig-proxy=false webshop_db

# Zum Vergleich: Strg+C in einer normalen attach-Sitzung
# schickt SIGINT an PID 1 und kann den Container stoppen

5. Das PID-1-Problem im Container

In einem klassischen Linux-System übernimmt init oder systemd als PID 1 besondere Aufgaben: verwaiste Kindprozesse einsammeln (Reaping) und Signale sinnvoll weiterleiten. Viele Anwendungen wie ein einfaches Node.js- oder PHP-Skript sind für diese Rolle nicht ausgelegt und ignorieren Standardsignale oder reagieren unerwartet darauf, wenn sie direkt als PID 1 im Container laufen. Das verschärft die Risiken von docker attach zusätzlich, weil das Verhalten je nach Anwendung stark variiert.

Aus diesem Grund empfiehlt es sich, produktive Container mit einem minimalen Init-System wie tini zu starten, das als PID 1 fungiert und Signale korrekt an den eigentlichen Anwendungsprozess weiterreicht. Docker bietet dafür seit Version 1.13 die eingebaute Option --init, die genau dieses Verhalten ohne zusätzliches Image-Layer bereitstellt.


# Container mit eingebautem Init-Prozess starten
docker run --init -d --name webshop_app mironsoft/webshop:latest

# PID 1 ist jetzt tini, nicht die Anwendung selbst
docker exec webshop_app ps -o pid,comm

6. Mehrere parallele Sitzungen mit exec

Ein praktischer Vorteil von docker exec, den attach prinzipbedingt nicht bietet, ist die Möglichkeit, beliebig viele unabhängige Sitzungen gleichzeitig zu öffnen. Ein Entwickler kann in einem Terminal die Logdatei einer Anwendung live verfolgen, während in einem zweiten Terminal parallel Datenbankabfragen getestet und in einem dritten der Speicherverbrauch beobachtet wird, ganz ohne dass sich die Sitzungen gegenseitig stören.

Das ist besonders bei komplexen Debugging-Situationen wertvoll, etwa wenn ein Fehler nur unter Last reproduzierbar ist. Ein Terminal erzeugt künstliche Last mit einem Benchmark-Tool, ein zweites beobachtet parallel die Prozessliste und ein drittes prüft Logdateien. Bei attach wäre das nicht möglich, da immer nur eine Verbindung zu den Streams von PID 1 gleichzeitig bestehen kann.


# Terminal 1: Live-Logs verfolgen
docker exec webshop_app tail -f var/log/system.log

# Terminal 2: Datenbankabfrage testen
docker exec -it webshop_db mysql -u root -p webshop

# Terminal 3: Ressourcenverbrauch live beobachten
docker exec webshop_app top

7. Wann attach tatsächlich die richtige Wahl ist

Trotz aller Risiken hat attach durchaus berechtigte Einsatzgebiete. Wenn ein Container bewusst im Vordergrund mit docker run gestartet und die Ausgabe versehentlich vom Terminal getrennt wurde, etwa weil die SSH-Sitzung abgebrochen ist, erlaubt attach, wieder Sichtkontakt zur Live-Ausgabe herzustellen, ohne den Prozess neu zu starten. Auch bei interaktiven Programmen, die direkt als PID 1 laufen und auf Tastatureingaben über stdin warten, ist attach oft der einzige Weg, tatsächlich mit dem Prozess zu interagieren.

Ein weiteres legitimes Szenario ist das gezielte Testen von Signalverhalten selbst, etwa um zu verifizieren, ob eine Anwendung SIGTERM korrekt für einen sauberen Shutdown verarbeitet, bevor sie produktiv eingesetzt wird. In diesem Fall ist die Signalweiterleitung von attach kein Nachteil, sondern genau die gewünschte Eigenschaft, um das reale Verhalten beim Beenden zu überprüfen.

8. Best Practices für den produktiven Einsatz

Für den alltäglichen Debugging- und Wartungsbetrieb sollte docker exec die Standardwahl sein, weil es keine Auswirkung auf den Hauptprozess hat und beliebig oft wiederholt werden kann. Zusätzlich lohnt es sich, exec-Sitzungen mit expliziten Nutzern und Umgebungsvariablen zu versehen, um Berechtigungsprobleme zu vermeiden und reproduzierbare Debugging-Umgebungen zu schaffen, statt sich auf den Root-Standardnutzer des Containers zu verlassen.

Sollte attach dennoch nötig sein, gehört die Detach-Sequenz Strg+P Strg+Q ins Standardrepertoire jedes Teams, ebenso wie das Wissen um --sig-proxy=false für riskante Situationen. Teams, die regelmäßig mit attach arbeiten, profitieren außerdem davon, produktive Container grundsätzlich mit --init zu starten, damit Signale kontrolliert verarbeitet werden, statt den Container ungewollt zu beenden.


# exec mit explizitem Nutzer und Umgebungsvariable
docker exec -it -u www-data -e APP_ENV=dev webshop_app bash

# Root-Rechte nur wenn wirklich noetig
docker exec -it -u root webshop_app bash

9. Entscheidungshilfe: exec oder attach?

In der Praxis lässt sich die Entscheidung fast immer anhand einer einzigen Frage treffen: Will ich etwas zusätzlich im Container tun, ohne den Hauptprozess zu beeinflussen, oder will ich die tatsächliche Ein- und Ausgabe von PID 1 selbst sehen und steuern? Im ersten Fall ist exec praktisch immer die richtige Wahl, im zweiten Fall bleibt attach das einzige passende Werkzeug.

Die folgende Tabelle fasst typische Situationen aus dem Alltag zusammen und ordnet ihnen das jeweils passende Kommando zu, inklusive einer kurzen Einschätzung des Risikos bei falscher Handhabung.

Situation Empfohlenes Kommando Begründung Risiko bei Fehlbedienung
Shell zum Debuggen öffnen docker exec -it Neuer, unabhängiger Prozess Keines, unabhängig von PID 1
Health-Check per Skript docker exec Automatisierbar, kein TTY nötig Keines
Live-Ausgabe eines Vordergrundprozesses ansehen docker attach Direkter Zugriff auf stdout von PID 1 Strg+C kann Container stoppen
Interaktive Eingabe an PID 1 senden docker attach Einziger Weg für Interaktion mit dem Hauptprozess Falsche Tastenkombination beendet Prozess
Mehrere Debugging-Sitzungen parallel docker exec Beliebig oft wiederholbar Keines
Signalverhalten der Anwendung testen docker attach Signale werden real an PID 1 gesendet Gewollter Effekt, kein Risiko

Mironsoft

Container-Infrastruktur, CI-Pipelines und Deployment-Automatisierung

Docker-Setups, die im Team und in Produktion tragfähig bleiben?

Wir prüfen bestehende Dockerfiles und Compose-Stacks auf Sicherheitslücken, aufgeblähte Images und fragile Build-Pipelines und bauen daraus eine Container-Infrastruktur, die schnell baut, sicher läuft und im Team nachvollziehbar bleibt.

Dockerfile-Review

Multi-Stage-Builds, Layer-Caching und Image-Größe systematisch optimieren.

Security-Audit

Container-Isolation, Secrets-Handling und Image-Scanning gegen echte Angriffsflächen absichern.

CI/CD-Integration

Build-Pipelines, Registries und Deployment-Strategien für reproduzierbare Releases aufbauen.

10. Zusammenfassung

docker exec vs. attach: Das Wichtigste auf einen Blick

exec

Startet einen neuen, unabhängigen Prozess im Container, ohne PID 1 zu berühren.

attach

Verbindet das Terminal direkt mit den Streams von PID 1, inklusive Signalweiterleitung.

Risiko

Strg+C in einer attach-Sitzung kann den gesamten Container beenden.

Empfehlung

Für Debugging und Wartung standardmäßig exec verwenden, attach gezielt und mit Detach-Sequenz.

11. FAQ: docker exec vs. attach: Das Wichtigste auf einen Blick

1Was ist der grundlegende Unterschied zwischen docker exec und docker attach?
docker exec startet einen komplett neuen Prozess innerhalb der Namespaces des Containers, während docker attach lediglich die bestehenden Ein- und Ausgabeströme des bereits laufenden Hauptprozesses PID 1 an das lokale Terminal anbindet.
2Warum beendet Strg+C in einer attach-Sitzung manchmal den ganzen Container?
Weil das Terminal direkt mit stdin von PID 1 verbunden ist, wird das Signal SIGINT durch Strg+C direkt an den Hauptprozess weitergereicht. Viele Anwendungen interpretieren dieses Signal als Aufforderung zum sauberen Beenden, wodurch der gesamte Container stoppt.
3Wie verlasse ich eine attach-Sitzung, ohne den Container zu beenden?
Mit der Detach-Sequenz Strg+P gefolgt von Strg+Q. Diese Tastenkombination trennt nur die Terminalverbindung, ohne ein Signal an den Hauptprozess zu senden.
4Kann ich mehrere docker exec Sitzungen gleichzeitig öffnen?
Ja, das ist einer der großen Vorteile von exec gegenüber attach. Es lassen sich beliebig viele unabhängige Sitzungen parallel öffnen, ohne dass sie sich gegenseitig beeinflussen oder den Hauptprozess stören.
5Was passiert, wenn ich exit in einer docker exec Shell eingebe?
Nur der durch exec gestartete Nebenprozess wird beendet. Der Hauptprozess PID 1 und damit der gesamte Container laufen unbeeinflusst weiter.
6Was ist das PID-1-Problem und was hat es mit attach zu tun?
Anwendungen, die nicht dafür ausgelegt sind, als PID 1 zu laufen, verarbeiten Signale oft nicht korrekt oder ignorieren sie. Das macht das Verhalten von docker attach unvorhersehbar, weshalb produktive Container idealerweise mit einem Init-System wie tini gestartet werden.
7Wie starte ich einen Container mit einem korrekten Init-Prozess?
Mit der Option --init beim docker run Befehl. Docker startet dann automatisch tini als PID 1, das Signale korrekt an die eigentliche Anwendung weiterleitet und verwaiste Kindprozesse einsammelt.
8Kann ich die Signalweiterleitung bei docker attach deaktivieren?
Ja, mit der Option --sig-proxy=false. Dann werden Signale wie SIGINT nicht mehr an PID 1 weitergereicht, was das Risiko eines versehentlichen Container-Stopps deutlich reduziert.
9Wann sollte ich attach statt exec verwenden?
Attach ist sinnvoll, wenn man die tatsächliche Live-Ausgabe eines im Vordergrund laufenden Hauptprozesses beobachten oder direkt mit ihm interagieren möchte, etwa nach einer unterbrochenen SSH-Verbindung zu einem im Vordergrund gestarteten Container.
10Braucht docker exec zwingend die Option -it?
Nur für interaktive Sitzungen mit Terminal-Zuweisung, etwa für eine Shell. Für einzelne, nicht-interaktive Befehle wie Health-Checks oder Skriptaufrufe kann -it entfallen.