Berechtigungsprobleme mit Bind Mounts lösen - UID und GID verstehen
Berechtigungsprobleme mit Bind Mounts lösen - UID und GID verstehen
„Permission denied" beim Bind Mount ist einer der häufigsten Docker-Anfängerfehler – das Problem ist immer dasselbe: UID-Mismatch zwischen Container und Host.
Das Problem verstehen
Linux-Berechtigungen basieren auf numerischen User-IDs, nicht auf Namen. Wenn der Prozess im Container als UID 1000 läuft und das gemountete Verzeichnis auf dem Host root (UID 0) gehört, verweigert der Kernel den Zugriff.
Diagnose
# Welcher User läuft im Container?
docker exec mycontainer id
# uid=1000(appuser) gid=1000(appuser)
# Wem gehört das gemountete Verzeichnis?
docker exec mycontainer ls -lan /app/data
# drwxr-xr-x 2 root root 4096 Sep 1 12:00 data
Wenn UID und Besitzer nicht übereinstimmen, ist das die Ursache.
Auf dem Host nachsehen:
ls -lan /pfad/zum/host-verzeichnis
Lösung 1: Host-Verzeichnis dem richtigen User geben
Die simpelste Lösung: dem Host-Verzeichnis die UID zuweisen, die der Container-Prozess nutzt.
# Wenn Container-Prozess als UID 1000 läuft
chown -R 1000:1000 /host/pfad/zum/verzeichnis
# Oder rekursiv mit chmod kombinieren
chown -R 1000:1000 /host/pfad && chmod -R 755 /host/pfad
Lösung 2: Container als aktueller Host-User starten
Docker kann den Container als den aktuellen Host-User ausführen – damit stimmen UIDs automatisch überein:
docker run --user $(id -u):$(id -g) -v $(pwd)/data:/app/data myimage
In Compose:
services:
app:
image: myimage
user: "${UID}:${GID}"
volumes:
- ./data:/app/data
Und in der .env Datei:
UID=1000
GID=1000
Achtung: Wenn der Container-Prozess bestimmte Dateien im Image als root besitzt (z.B. /var/run), kann das zu anderen Problemen führen.
Lösung 3: Dockerfile mit korrekter UID bauen
Für eigene Images die UID direkt im Dockerfile festlegen:
FROM node:20-alpine
# User mit passender UID anlegen
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
USER appuser
WORKDIR /app
Sonderfall: Root-owned Verzeichnisse
Manche Anwendungen erwarten root-Rechte für bestimmte Verzeichnisse beim Start, laufen dann aber als unprivilegierter User. Hier hilft ein Entrypoint-Skript:
#!/bin/sh
# Besitzer des gemounteten Verzeichnisses korrigieren
chown -R appuser:appuser /app/data
exec su-exec appuser "$@"
Sonderfall: NFS-Mounts
Bei NFS-Servern mit root_squash (Standard) werden root-Anfragen vom Container auf den anonymen User gemappt – das führt zu Berechtigungsfehlern. Lösung: entweder no_root_squash auf dem NFS-Server (Sicherheitsrisiko abwägen) oder den Container-Prozess als Non-Root mit der richtigen UID starten.
Sonderfall: SELinux
Auf RHEL/Fedora/CentOS mit aktivem SELinux schlägt der Zugriff auf Bind Mounts fehl, auch wenn UIDs stimmen. SELinux-Labels müssen gesetzt werden:
# :z = geteiltes Label (mehrere Container)
docker run -v $(pwd)/data:/app/data:z myimage
# :Z = privates Label (nur dieser Container)
docker run -v $(pwd)/data:/app/data:Z myimage
Schnell-Checkliste
# 1. Container-UID ermitteln
docker exec CONTAINER id
# 2. Host-Verzeichnis-Besitzer prüfen
ls -lan /host/pfad
# 3. Anpassen
chown UID:GID /host/pfad