- Shell 53.4%
- Dockerfile 46.6%
| .devcontainer | ||
| project | ||
| .gitignore | ||
| README.md | ||
DevPod Sample
Devcontainer-Vorlage als Startpunkt für eigene Projekte. Läuft unverändert unter:
- DevPod (empfohlen) - mit jedem Provider (Docker, Podman, Kubernetes, SSH, AWS, ...)
- VS Code Dev Containers
- GitHub Codespaces
- Zed
Aufbau
.devcontainer/devcontainer.json baut das .devcontainer/Dockerfile und
mountet den Workspace nach /workspace.
Gemountet wird dabei nicht das Repo selbst, sondern der (leere) Unterordner
project/. Der Container startet also mit leerem /workspace - der ideale
Startpunkt für ein neues Projekt. Repo-Dateien wie dieses README bleiben auf
dem Host und sind im Container nicht sichtbar. Eigene Dateien landen auf dem
Host unter project/ und bleiben dort auch nach einem Container-Rebuild
erhalten.
Quickstart mit DevPod
# DevPod installieren, siehe https://devpod.sh/docs/getting-started/install
devpod provider add docker # oder: podman, kubernetes, ssh, aws, ...
devpod up .
Eigene Git-Identität mitbringen (providerübergreifend, auch bei entfernten Providern) über ein Dotfiles-Repo:
devpod up . --dotfiles https://git.serk-b.de/rev/my-dotfiles.git
Mit VS Code / Codespaces öffnen
Ordner in VS Code öffnen, "Dev Containers: Reopen in Container" ausführen. Codespaces funktioniert identisch.
Claude Code
Das Claude-Code-Feature
ist bereits eingebunden; die lokale ~/.claude-Config wird gemountet.
Docker/Podman im Container
Die podman-CLI ist im Dockerfile per apt-get installiert (nativ auf
Debian trixie verfügbar, kein Docker-Repo nötig). Der Podman-Socket des Hosts
wird gemountet ("Sibling-Container": Container, die im Devcontainer gestartet
werden, laufen neben ihm auf dem Host, nicht verschachtelt); CONTAINER_HOST
zeigt im Container standardmäßig darauf.
Bewusst kein docker-outside-of-docker-Feature: Das Feature installiert
moby-cli/docker-ce-cli, die es (Stand jetzt) für Debian trixie noch nicht
gibt - der Build bricht mit "The 'moby' option is not supported on debian
'trixie'" ab.
Auf Linux mit rootless Podman passt der Default
(/run/user/1000/podman/podman.sock), sofern der Podman-Socket-Dienst des
Users läuft:
systemctl --user enable --now podman.socket
devpod up .
Weicht der UID des Host-Users von 1000 ab oder soll ein anderer Socket
verwendet werden, CONTAINER_SOCK vor dem Start entsprechend setzen:
export CONTAINER_SOCK="${XDG_RUNTIME_DIR}/podman/podman.sock"
devpod up .
Auf macOS mit einer Podman-Machine ist der Socket-Pfad und dessen
Erreichbarkeit deutlich komplizierter (VM-Grenze, SELinux, User-Namespace-
Remapping) - siehe den Abschnitt "Advanced" unten für die nötigen
Host-seitigen Vorbereitungsschritte, bevor CONTAINER_SOCK gesetzt wird.
Advanced: manueller Podman-Socket-Ansatz (ohne DevPod, macOS)
Diese Vorlage kam ursprünglich aus einem Setup, das VS Code/Zed ohne DevPod direkt mit einer lokalen Podman-Machine auf dem Mac verbunden hat ("podman-outside-of-podman": Podman-Socket der VM wird in den Devcontainer gemountet). DevPod nimmt einem das ab (der Provider kümmert sich selbst um die Container-Runtime) - relevant ist der Abschnitt nur ohne DevPod, mit selbstverwalteter Podman-Machine auf macOS.
Die Host-seitigen Vorbereitungsschritte (Socket-Pfad ermitteln, world-
accessible machen, SELinux permissive setzen) gelten zusätzlich zu dem oben
beschriebenen Socket-Mount in devcontainer.json - der Mount allein reicht
auf macOS wegen der VM-Grenze nicht aus.
Vollständige macOS-Anleitung (ohne DevPod)
Durchgehend Podman - auf dem Mac-Host und innerhalb des Devcontainers, verbunden über den Host-Socket.
Einmalige Vorbereitung auf dem Mac
Rootless Podman reicht den eigenen Socket auf macOS nur zuverlässig durch, wenn mehrere Fixes gemeinsam greifen - fehlt einer, gibt es "Permission denied" oder "no such file"-Fehler.
1. Podman Machine starten
brew install podman
podman machine init
podman machine start
2. Socket-Pfad ermitteln und setzen
Der Socket-Pfad muss von innerhalb der VM ermittelt werden - nicht über
podman machine inspect (liefert einen macOS-seitigen Weiterleitungs-Socket,
der sich wegen virtiofs-Limitierungen nicht mounten lässt):
podman machine ssh -- podman info --format '{{.Host.RemoteSocket.Path}}'
# z.B. /run/user/501/podman/podman.sock
GUI-Apps erben auf macOS keine Shell-Umgebungsvariablen, daher launchctl setenv verwenden und die App danach komplett neu starten (Cmd+Q):
launchctl setenv PODMAN_SOCK "/run/user/501/podman/podman.sock"
3. Socket world-accessible machen
Rootless Podman nutzt User-Namespace-Remapping: "root" im Devcontainer hat eine andere UID als der Socket-Eigentümer in der VM. Per systemd-Override den Socket-Modus auf world-accessible setzen:
podman machine ssh -- mkdir -p .config/systemd/user/podman.socket.d
podman machine ssh -- tee .config/systemd/user/podman.socket.d/override.conf <<< '[Socket]
SocketMode=0666'
podman machine ssh -- systemctl --user daemon-reload
podman machine ssh -- systemctl --user restart podman.socket
Kontrolle (podman machine ssh -- ls -la /run/user/501/podman/podman.sock)
sollte srw-rw-rw- zeigen. Sicherheitshinweis: Damit kann jeder lokale
Prozess in der VM den Socket ansprechen - bei einer Ein-Personen-VM
vergleichbar mit chmod 666 /var/run/docker.sock.
4. SELinux in der VM auf permissive setzen
Selbst mit korrekten Unix-Rechten (0666) kann SELinux in der VM den Zugriff
weiterhin blockieren - beim Build wie zur Laufzeit. Dauerhaft (übersteht
podman machine stop/start) auf permissive setzen:
podman machine ssh -- sudo setenforce 0
podman machine ssh -- sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config
5. Zed aktuell halten
Native Podman-Unterstützung für Dev Containers (use_podman) ist erst seit
ca. Mitte 2026 vollständig stabil.
Bekannte Einzelfehler und ihre Bedeutung
| Fehler | Ursache | Fix |
|---|---|---|
statfs .../podman.sock: no such file or directory |
Falscher Socket-Pfad in PODMAN_SOCK (macOS- statt VM-Pfad) |
Schritt 2 |
statfs .../podman.sock: operation not supported |
macOS-Weiterleitungs-Socket über podman machine inspect statt VM-internem Pfad |
Schritt 2 |
Permission denied (Socket zeigt -?????????) |
Rootless User-Namespace-Remapping, Socket gehört anderer UID | Schritt 3 |
Permission denied (trotz srw-rw-rw- sichtbar) |
SELinux in der VM blockiert weiterhin | Schritt 4 |
Build scheitert bei RUN --mount=type=bind,from=dev_containers_feature_content_source |
SELinux beim Build (falls doch ein devcontainer-Feature verwendet wird) | Schritt 4 |
apt-get: Sub-process /usr/bin/sqv returned an error code (1), Not live until ... |
Uhrzeit-Drift der VM (meist nach Standby/Neustart) | podman machine ssh -- sudo chronyc -a makestep |
Projekt öffnen
Zed: use_podman: true in den Einstellungen setzen. VS Code: in den
Dev-Containers-Extension-Einstellungen --docker-path podman --docker-compose-path podman-compose setzen.
devcontainer.json
Der Socket-Mount und CONTAINER_HOST sind bereits in der
devcontainer.json dieser Vorlage enthalten (siehe Abschnitt "Docker/Podman
im Container" oben). Für diesen Mac-Modus lediglich CONTAINER_SOCK auf den
in Schritt 2 ermittelten PODMAN_SOCK-Wert setzen, bevor der Container
gebaut/gestartet wird - z.B. export CONTAINER_SOCK="$PODMAN_SOCK".
Optional zusätzlich die Host-Gitconfig mounten:
"mounts": [
"source=${localEnv:HOME}/.gitconfig,target=/home/vscode/.gitconfig-host,type=bind,consistency=cached"
]
Die gestarteten Container laufen dann als Sibling-Container neben dem
Devcontainer und sind auf dem Mac auch direkt über podman ps sichtbar.