Keine Beschreibung
  • Shell 53.4%
  • Dockerfile 46.6%
Datei suchen
2026-08-10 21:39:15 +02:00
.devcontainer DoD 2026-08-10 21:39:15 +02:00
project updated devcontainer 2026-08-05 00:08:44 +02:00
.gitignore updated devcontainer 2026-08-05 00:08:44 +02:00
README.md DoD 2026-08-10 21:39:15 +02:00

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.