Docker exec: the input device is not TTY
Von Miro Kodet
Warum Docker Befehle aus der Pipeline verweigert hat
translationKey: "docker-exec-the-input-device-is-not-tty"
Kürzlich sind wir auf ein Problem gestoßen, bei dem bestimmte docker exec-Befehle nicht ausgeführt werden konnten, wenn sie aus einer CI/CD-Pipeline (in unserem Fall GitHub Actions) heraus aufgerufen wurden.
Auf unseren lokalen Entwicklungsmaschinen funktionierten diese Befehle einwandfrei, aber nach der Migration in ein Automatisierungsskript traten unerwartete Fehler auf. Der typische Befehl sah so aus:
docker exec -it <container_name> bin/console importmap:installWährend dies auf unseren Entwicklungsmaschinen funktionierte, schlug die Pipeline mit folgendem Fehler fehl:
the input device is not a TTY
Warum passiert das?
Der Übeltäter ist der -it-Schalter, den wir auf lokalen Maschinen oft aus Gewohnheit verwenden. Dieses Flag ist eigentlich eine Kombination aus zwei Optionen:
-i/--interactive: STDIN offen halten, auch wenn nicht angehängt-t/--tty: Ein Pseudo-TTY (Teletypewriter) zuweisen
Wenn du einen Befehl interaktiv im Terminal ausführst, kann Docker ein TTY zuweisen. In CI/CD-Pipelines, Skripten oder nicht-interaktiven Shells steht jedoch kein TTY-Gerät zur Verfügung, sodass Docker diese Anforderung nicht erfüllen kann und mit dem obigen Fehler abbricht.
TL;DR: Die Lösung
Entferne die -it-Flags bei der Ausführung in nicht-interaktiven Umgebungen!
Verwende stattdessen:
docker exec <container_name> bin/console importmap:installDies führt den Befehl nicht-interaktiv aus, was für CI/CD-Pipelines und Skripte geeignet ist.
Wann solltest du -it verwenden?
- Verwende
-it, wenn du mit dem Container interagieren möchtest (z. B. eine Shell öffnen, ein REPL ausführen oder interaktiv debuggen). - Lasse
-itin Skripten, CI/CD-Pipelines oder nicht-interaktiven Umgebungen weg.
Du kannst -i und -t auch einzeln verwenden, wenn du nur eine der Funktionen benötigst. Zum Beispiel ist -i nützlich für Befehle, die STDIN benötigen, aber kein TTY.
Was ist ein TTY?
TTY steht für Teletypewriter (Fernschreiber). Ursprünglich bezeichnete es physische Geräte für textbasierte Ein- und Ausgabe. Heute ist es eine Software-Schicht, die dieses Verhalten emuliert und Programmen die Interaktion mit Benutzern über Text ermöglicht.
In Docker weist das -t-Flag ein Pseudo-TTY zu, das für interaktive Programme notwendig ist. In nicht-interaktiven Umgebungen (wie CI/CD) steht kein TTY zur Verfügung, sodass Docker keines zuweisen kann – was zu dem Fehler führt.
Checkliste zur Fehlerbehebung
Wenn du den Fehler „the input device is not a TTY" bekommst:
- Befehl prüfen: Verwendest du
-itunnötigerweise? - Umgebung bestimmen: Ist es interaktiv (lokales Terminal) oder nicht-interaktiv (Skript, CI/CD)?
- Versuche
-itzu entfernen: Die meisten Befehle in der Automatisierung benötigen kein TTY. - Dokumentation konsultieren: Siehe Docker-Dokumentation für weitere Details zu exec und TTY-Optionen.
Referenzen
translationKey: "docker-exec-the-input-device-is-not-tty"
Wenn du den Unterschied zwischen interaktiven und nicht-interaktiven Umgebungen verstehst und weißt, wie Docker die TTY-Zuweisung handhabt, kannst du diese häufige Falle in deinen Automatisierungsskripten und Pipelines vermeiden.