← Alle Artikel
Zuletzt aktualisiert: 2026-03-30

Docker-Container startet nicht? Systematische Fehlersuche

Systematischer Ansatz zum Debuggen von Docker-Containern. Exit-Codes, Logs, Compose-Probleme, Berechtigungsprobleme.

Kurzfassung

Wenn ein Docker-Container nicht startet, arbeite systematisch vor: Pruefe zuerst docker logs auf Anwendungsfehler, nutze docker inspect fuer den Container-Zustand und den Exit-Code, ueberpruefe Port-Verfuegbarkeit und Volume-Berechtigungen, und kontrolliere den freien Speicherplatz. Die haeufigsten Ursachen fuer Startprobleme lassen sich auf fuenf Kategorien eingrenzen: Anwendungsfehler (Exit-Code 1), fehlende Binaries (127), Speicherlimit ueberschritten (137), Berechtigungsprobleme oder Port-Konflikte. Diese Anleitung fuehrt mit konkreten Befehlen durch jedes Szenario.

Voraussetzungen

Schritt-fuer-Schritt Debugging-Anleitung

1. Container-Logs auslesen

Hier faengt jede Fehlersuche an. Container-Logs erfassen alles, was der Hauptprozess der Anwendung auf stdout und stderr schreibt.

# Alle Logs eines Containers anzeigen (auch gestoppte Container)
docker logs mein-container

# Nur die letzten 50 Zeilen anzeigen
docker logs --tail 50 mein-container

# Logs in Echtzeit verfolgen (wie tail -f)
docker logs --tail 50 -f mein-container

# Zeitstempel zu jeder Zeile anzeigen
docker logs -t mein-container

# Logs ab einem bestimmten Zeitpunkt
docker logs --since 2025-01-01T10:00:00 mein-container

Wenn der Container sofort beendet wurde, enthalten die Logs meistens die genaue Fehlermeldung. Sind die Logs leer, liegt das Problem wahrscheinlich auf Container-Runtime-Ebene: falscher Entrypoint, fehlendes Binary oder keine Ausfuehrungsberechtigung.

2. Container-Zustand untersuchen

docker inspect liefert saemtliche Informationen, die Docker ueber einen Container hat: Konfiguration, Zustand, Netzwerkeinstellungen und mehr.

# Vollstaendige JSON-Ausgabe
docker inspect mein-container

# Nur den Zustand abfragen (Status, Exit-Code, Fehler)
docker inspect --format '{{json .State}}' mein-container | jq .

# Exit-Code direkt auslesen
docker inspect --format '{{.State.ExitCode}}' mein-container

# OOM-Killer-Flag pruefen
docker inspect --format '{{.State.OOMKilled}}' mein-container

# Den ausgefuehrten Befehl anzeigen
docker inspect --format '{{.Config.Cmd}}' mein-container

# Entrypoint pruefen
docker inspect --format '{{.Config.Entrypoint}}' mein-container

# Volume-Konfiguration anzeigen
docker inspect --format '{{json .Mounts}}' mein-container | jq .

3. Exit-Codes verstehen

Der Exit-Code verraet, wie der Prozess beendet wurde. Die folgende Tabelle deckt die wichtigsten Faelle ab:

Exit-CodeBedeutungTypische Ursache
0ErfolgDer Prozess wurde normal beendet. Wenn der Container "nicht laufen bleibt," ist vermutlich der Entrypoint ein Skript, das durchlaeuft statt zu blockieren.
1AnwendungsfehlerAllgemeiner Fehler. docker logs enthaelt die eigentliche Fehlermeldung.
126Keine AusfuehrungsberechtigungDie Entrypoint-Datei existiert, ist aber nicht ausfuehrbar.
127Befehl nicht gefundenDas Binary in CMD/ENTRYPOINT existiert nicht im Container. Haeufig bei Multi-Stage-Builds, wenn das COPY vergessen wurde.
137SIGKILL (OOM)Der Container hat sein Speicherlimit ueberschritten und wurde vom OOM-Killer beendet. Bestaetigung mit docker inspect --format '{{.State.OOMKilled}}'.
139SIGSEGVSegmentation Fault in der Anwendung. Tritt haeufig auf, wenn ein amd64-Binary auf arm64 ausgefuehrt wird (oder umgekehrt).
143SIGTERMDer Prozess hat ein Beendigungssignal erhalten. Normal bei docker stop, aber unerwartet beim Start deutet auf einen Orchestrator hin, der den Container stoppt.

4. Interaktives Debugging mit exec

Wenn der Container laeuft, aber sich falsch verhaelt, kannst du direkt hineinspringen:

# Shell in einem laufenden Container oeffnen
docker exec -it mein-container /bin/sh

# Falls sh nicht verfuegbar ist, bash versuchen
docker exec -it mein-container /bin/bash

# Einzelnen Diagnosebefehl ausfuehren
docker exec mein-container cat /etc/os-release
docker exec mein-container ls -la /app/

Wenn der Container sofort beendet wird und kein exec moeglich ist, ueberschreibe den Entrypoint:

# Image mit Shell statt normalem Entrypoint starten
docker run -it --entrypoint /bin/sh mein-image

# Oder mit sleep am Leben halten, um dann exec zu nutzen
docker run -d --entrypoint sleep mein-image 3600
docker exec -it $(docker ps -q -f ancestor=mein-image) /bin/sh

5. Docker-Compose-Probleme

Port-Konflikte

Wenn ein Service nicht startet, weil der Port bereits belegt ist:

# Herausfinden, welcher Prozess einen Port belegt
lsof -i :8080

# Unter Linux alternativ:
ss -tlnp | grep 8080

# Prozess bei Bedarf beenden
kill -9 $(lsof -t -i :8080)

Netzwerkprobleme

# Alle Docker-Netzwerke auflisten
docker network ls

# Bestimmtes Netzwerk untersuchen (zeigt verbundene Container)
docker network inspect meine-app_default

# Konnektivitaet zwischen Containern testen
docker exec mein-container ping anderer-container

# DNS-Aufloesung innerhalb eines Containers pruefen
docker exec mein-container nslookup anderer-container

depends_on vs. Healthchecks

depends_on wartet nur darauf, dass der Container gestartet wird — nicht darauf, dass die Anwendung darin bereit ist. Ein Datenbank-Container braucht vielleicht 10 Sekunden zur Initialisierung, aber die App versucht sofort eine Verbindung herzustellen.

# docker-compose.yml mit korrektem Healthcheck
services:
  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  app:
    image: meine-app
    depends_on:
      db:
        condition: service_healthy

Volume-Berechtigungen

# Besitzrechte gemounteter Volumes pruefen
docker exec mein-container ls -la /data/

# Pruefen, als welcher Benutzer der Container-Prozess laeuft
docker exec mein-container id

# Besitzrechte auf dem Host korrigieren
sudo chown -R 1000:1000 ./data/

6. Berechtigungsprobleme

Berechtigungsfehler gehoeren zu den frustrierendsten Docker-Problemen, besonders im Zusammenspiel mit gemounteten Volumes.

# Schlecht: Dateien als root kopiert, dann auf non-root User gewechselt
FROM node:20-alpine
COPY . /app
USER node
CMD ["node", "/app/server.js"]

# Richtig: Besitzrechte explizit setzen
FROM node:20-alpine
COPY --chown=node:node . /app
WORKDIR /app
USER node
CMD ["node", "server.js"]

Bei Bind-Mounts von Host-Verzeichnissen muss die UID im Container mit dem Dateibesitzer auf dem Host uebereinstimmen:

# UID des Container-Benutzers pruefen
docker exec mein-container id
# uid=1000(node) gid=1000(node)

# Sicherstellen, dass Host-Dateien uebereinstimmen
ls -ln ./data/
# Bei Abweichung korrigieren:
sudo chown -R 1000:1000 ./data/

7. Multi-Stage-Build-Fehler

Multi-Stage-Builds sind eine haeufige Quelle fuer "Container startet, aber Binary/Datei fehlt"-Probleme.

# Haeufiger Fehler: COPY aus der Build-Stage vergessen
FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN go build -o /app/server .

FROM alpine:3.19
# FEHLER: Binary wurde nicht kopiert!
CMD ["/app/server"]
# Exit-Code 127: /app/server nicht gefunden

# Korrektur:
FROM alpine:3.19
COPY --from=builder /app/server /app/server
CMD ["/app/server"]

Ein weiteres haeufiges Problem: auf einem glibc-basierten Image (Debian/Ubuntu) bauen und auf einem musl-basierten Image (Alpine) ausfuehren. Das Binary erzeugt einen Segfault (Exit-Code 139) oder findet keine Shared Libraries. Entweder die gleiche Basis verwenden oder statisch kompilieren:

# Fuer Go: vollstaendig statisches Binary bauen
CGO_ENABLED=0 go build -o /app/server .

8. Speicherplatzprobleme

Docker kann unbemerkt enorme Mengen an Speicherplatz verbrauchen. Ist die Festplatte voll, scheitern Container-Starts mit kryptischen Fehlermeldungen.

# Docker-Speicherverbrauch mit Aufschluesselung anzeigen
docker system df

# Detaillierte Ansicht
docker system df -v

# Ungenutzte Daten entfernen (gestoppte Container, verwaiste Images, ungenutzte Netzwerke)
docker system prune

# Auch ungenutzte Volumes entfernen (VORSICHT: loescht Daten)
docker system prune --volumes

# Alle ungenutzten Images entfernen, nicht nur verwaiste
docker system prune -a

# Festplattenbelegung auf dem Host pruefen
df -h /var/lib/docker

9. Umgebungsvariablen pruefen

Falsch konfigurierte Umgebungsvariablen sind ein stiller Killer. Die App startet, verbindet sich aber mit der falschen Datenbank, nutzt den falschen API-Key oder faellt auf Standardwerte zurueck.

# Alle Umgebungsvariablen in einem laufenden Container auflisten
docker exec mein-container env

# Bestimmte Variable pruefen
docker exec mein-container printenv DATABASE_URL

# Umgebungsvariablen per docker inspect (funktioniert auch bei gestoppten Containern)
docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' mein-container

# Pruefen, ob die .env-Datei in Compose korrekt geladen wird
docker compose config

docker compose config ist besonders nuetzlich: Es rendert die finale, aufgeloeste YAML-Datei mit allen Variablen-Substitutionen, sodass sich ueberpruefen laesst, ob ${VARIABLEN} korrekt aufgeloest wurden.

Schnellreferenz zur Fehlerbehebung

SymptomErster BefehlWahrscheinliche Ursache
Container beendet sich sofortdocker logs mein-containerAnwendungsabsturz oder Entrypoint laeuft durch
Exit-Code 137, keine Fehler in Logsdocker inspect --format '{{.State.OOMKilled}}'Speicherlimit ueberschritten
"port already in use"lsof -i :PORTAnderer Prozess oder Container belegt den Port
"permission denied"docker exec mein-container ls -la /pfadUID-Abweichung zwischen Container-Benutzer und Dateibesitzer
"no such file or directory"docker exec mein-container ls /app/Fehlendes COPY im Dockerfile oder falscher Pfad
Container laeuft, aber App nicht erreichbardocker network inspectNetzwerk-Fehlkonfiguration oder falscher publizierter Port
"no space left on device"docker system dfDocker-Images/Volumes belegen gesamten Speicherplatz
Compose-Services finden sich nichtdocker compose configServices in verschiedenen Netzwerken oder Tippfehler im Service-Namen

Praevention

Experten-Hilfe gebraucht?

Bug nicht gefunden? Ich debugge live per Screensharing. €49, 30 Min.

Jetzt buchen — €49

100% Geld-zurück-Garantie

HR

Harald Roessler

Infrastructure Engineer mit 20+ Jahren Erfahrung. Gründer der DSNCON GmbH.