Zuletzt aktualisiert am 28. März 2026 von Lars
Wenn du in der IT unterwegs bist, wirst du immer mal wieder von Docker, Kubernetes und Podman hören. Mehr dazu findest du in diesm Artikel
Inhaltsverzeichnis
Problemstellung Anwendungsbereitstellung
Betrachten wir zunächst, worum es bei Docker geht: Docker hilft bei der Bereitstellung von Anwendungen. Wenn du eine Anwendung bereitstellen möchtest, musst du nicht nur das Programm, sondern auch viele Abhängigkeiten wie Bibliotheken, Betriebssystem-Spezifikationen und externe Dienste berücksichtigen. Man denke hier zum Beispiel an die DLL-Dateien, die ein Windows-Programm in der Regel benötigt.
Früher gab es dafür zwei Hauptlösungen: klassische Installer oder virtuelle Maschinen. Beide hatten ihre Vor- und Nachteile.
Klassischer Installer
Vorteil des Installers ist seine Kompaktheit und die einfache Ausführbarkeit auf jedem Zielsystem. Problematisch wird es aber, wenn auf dem Zielsystem spezielle Konfigurationen vorhanden sein müssen, wie zum Beispiel eine bestimmte Datenbankversion, damit die Applikation einwandfrei funktioniert.
Virtuelle Maschine
Nachteil von virtuellen Maschinen ist deren Grösse. Sie enthalten immer das komplette Betriebssystem. Bei lizenzpflichtigen Betriebssystemen wird zudem immer eine eigene Lizenz benötigt. Dafür sind virtuelle Maschinen in der Regel recht universell einsetzbar.
Siehe auch: Was ist Virtualisierung?
Lösung mit Docker
Docker nutzt das Konzept von sogenannten Containern. Statt eine komplette virtuelle Maschine für jede Anwendung zu starten, isoliert Docker einfach den Prozess der Anwendung. Das bedeutet, dass mehrere Docker-Container den gleichen Betriebssystemkern nutzen können, wodurch sie leichter und schneller sind.

Der Nachteil der Nutzung des Betriebssystemkerns ist aber, dass auf einem Linux nur eine Linux-Applikation laufen kann und nicht etwa eine Windows-Applikation, wie das mit Virtualisierung möglich wäre.

Wie funktioniert das?
Die Idee hinter der "Containerisierung" ist, einen Prozess und all seine Abhängigkeiten in einem "Image" zu verpacken. Wenn dieses Image (oder Archiv) gestartet wird, packt Docker es in einen Container und führt es aus. Dies ist der Vorgang der "Containerisierung".
Das ist aber stark vereinfacht ausgedrückt. Ein Container kann aus mehreren sogenannten Layern bestehen, die quasi übereinandergelegt werden können. Dadurch wird RAM gespart.
Beim Neustart eines Containers werden alle bestehenden Daten verworfen und es wird quasi wieder bei Null gestartet.
Wenn konstante Daten benötigt werden, werden sogenannte Volumes eingebunden. Volumes können in mehreren Containern eingebunden (gemountet) werden.
Docker wurde entwickelt, um die Verwendung von Linux Containern für Entwickler zu vereinfachen. Es ist im Wesentlichen ein Kommandozeilen-Tool und ein Betriebssystem-Service (=Daemon), der den Prozess steuert.
Docker auf Nicht-Linux Systemen
Wenn du ein MacOS- oder Windows-Benutzer bist, benötigst du eine virtuelle Maschine, um Docker auszuführen. Mit Produkten wie "Docker for Mac" oder "Docker for Windows" ist dies nahtlos möglich und erfordert minimalen Overhead.
Vor- und Nachteile von Docker
Vorteile von Docker
Die Liste der Vor- und Nachteile von Docker ist nicht abschliessend. Sie listet nur einige wichtige Punkte für Einsteiger auf.
- Docker-Container sind leichtgewichtig und schnell.
- Sie bieten eine bessere Isolation als klassische Installer.
- Sie sind ressourceneffizient und so können viele Container auf einem System ausführen.
Nachteile von Docker
- Da alle Container denselben Kernel verwenden, kann ein Kernel-Exploit in einem Container potenziell das gesamte Host-System beeinflussen.
- Isolierung: Die Isolierung zwischen Containern ist nicht so stark wie die von echten virtuellen Maschinen.
- Das Arbeiten mit Anwendungen, die Daten speichern müssen (z.B. Datenbanken) kann komplizierter sein.
Was ist Podman?
Podman ist wie Docker eine Container-Engine – also ein Tool, mit dem man Anwendungen in isolierten Umgebungen (Containern) betreiben kann. Wer Docker kennt, sollte sich relativ schnell zurechtfinden: Die Befehle sind praktisch identisch.
Docker vs. Podman
Der grösste Unterschied zu Docker ist, dass Podman keinen Hintergrunddienst benötigt, der ständig läuft. Container werden einfach direkt gestartet. Ausserdem läuft Podman standardmässig ohne Administratorrechte, was es sicherer macht und den Einsatz auch auf Managed Servern ermöglicht, auf denen man in der Regel keine Root-Rechte hat.
Was ist Kubernetes?
Auch wieder stark vereinfacht – Kubernetes ist...
- Ein System zur Verwaltung eines Clusters (Verbunds) von Docker-Containern.
- Bietet automatisierte Planung und Verwaltung von Containern (beispielsweise Verschieben zwischen mehreren Servern).
Docker vs. Podman - praktisches Beispiel
Docker vs. Podman. Ich möchte schon länger Docker und sein Pendant besser verstehen lernen. Da ich mich mit reiner Theorie immer eher schwer tue, habe ich nach einem praktischen Beispiel gesucht.
Dies habe ich in Grafana gefunden. Ein Raspberry Pi Zero misst bei mir auf dem Balkon die Temperatur und schreibt diese in eine MySQL-Datenbank, die dann mit Grafana visualisiert werden soll.
Der folgende Abschnitt dieses Artikels dient primär als Notiz meiner Experimente und nicht als fertiges Tutorial. Vielleicht kann er dem ein oder anderen aber trotzdem helfen.
Installation und erster Test
$ sudo apt update
Benötigte Pakete für Repos einrichten
$ sudo apt install -y ca-certificates curl gnupg lsb-release
Docker GPG Key
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Docker Repository zur APT-Quelle hinzufügen (Debian 12, da Trixie inkompatibel)
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
https://download.docker.com/linux/debian $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt update
Docker-Engine und zugehörige Komponenten installieren
$ sudo apt install -y docker-ce docker-ce-cli containerd.io
Docker-Dienst aktivieren und sofort starten
$ sudo systemctl enable --now docker
Prüfen, ob Docker läuft
$ sudo systemctl status docker
Aktuellen Nutzer zur Gruppe Docker hinzufügen
$ sudo usermod -aG docker $USER
Änderungen wirksam machen
$ newgrp docker</docker>
Test-Container Hello World ausführen
<code>docker run --rm hello-world
Test-Container Hello World ausführen
$ docker run --rm hello-worldDocker Compose Plugin
Docker Compose ist ein Werkzeug, mit dem du mehrere Docker‑Container und deren Vernetzung in einer einzigen Textdatei („docker‑compose.yml“) beschreiben kannst. Mit einem einzigen Befehl (docker compose up) startest, stoppst oder aktualisierst du dann alle definierten Services gleichzeitig. Es vereinfacht das Management von Multi‑Container‑Setups, ohne dass du jedes "docker run "einzeln eingeben musst.
Docker Compose Version holen
$ DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep tag_name | cut -d '"' -f4)
Binary herunterladen und nach /usr/local/lib/docker/cli-plugins legen
$ sudo mkdir -p /usr/local/lib/docker/cli-plugins
$ sudo curl -SL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-$(dpkg --print-architecture)" \
-o /usr/local/lib/docker/cli-plugins/docker-compose
Ausführungsrechte setzen
$ sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
Prüfung
$ docker compose version
Grafana mit Docker
Unterordner - z.B. grafana - anlegen
Darin eine docker-compose.yml anlegen
services:
grafana:
image: grafana/grafana:12.3-ubuntu
container_name: grafana
depends_on:
- influxdb
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=passwordvongrafana
volumes:
grafana_data:Das Passwort hier im Klartext abzulegen, ist nicht Best Practice, aber wir widmen uns dem später noch.
Docker Anwendung starten
$ docker compose upDocker-Anwendung stoppen
$ docker compose downLaufende Anwendungen anzeigen
$ docker psGrafana
Die Konfiguration von Grafana werde ich in eine separate Anleitung auslagern.
Der Aufruf von Grafana erfolgt über
http://IP:3000

Podman
Podman installieren
& sudo apt update && sudo apt install podman
& sudo apt install python3-pippodman-compose installieren
sudo apt install podman-composedocker compose Einstellungen sichern
mv ~/.docker/cli-plugins/docker-compose ~/.docker/cli-plugins/docker-compose.bakDienste starten
systemctl --user enable --now podman.socket
systemctl --user status podman.socketContainer starten und überprüfen
podman compose up
podman psProblem Daten aus Docker-Volume
An dieser Stelle wurden die Daten nicht gefunden und das installierte Grafana-Dashboard ist verschwunden.
Container sind von Natur aus flüchtig – wird ein Container gelöscht, sind alle Daten weg. Damit das nicht passiert, kann man Daten ausserhalb des Containers speichern. Dafür gibt es zwei Varianten:
Named Volume
Docker oder Podman erstellt einen eigenen Speicherbereich und verwaltet ihn selbst. Man weiss nicht genau, wo die Daten liegen – das übernimmt das Tool.
volumes:
- grafana_data:/var/lib/grafanaBind Mount
Man gibt einen konkreten Ordner auf dem eigenen Computer an. Die Daten liegen genau dort, wo angegeben. Man kann jederzeit "reinschauen".
volumes:
- ./grafana_data:/var/lib/grafanaDer . steht für "aktueller Ordner" – die Daten landen also direkt neben der compose.yml.
Das Problem beim Wechsel von Docker zu Podman
Docker und Podman verwalten ihre Named Volumes getrennt – jedes Tool hat seinen eigenen Speicherort. Erstellt man in Docker ein Volume namens grafana_data, weiss Podman nichts davon. Es erstellt einfach ein neues, leeres Volume mit demselben Namen.
Mit einem Bind Mount hat man dieses Problem nicht: Beide Tools greifen auf denselben Ordner zu – die Daten sind immer da.
Für Einsteiger sind daher Bind Mounts die bessere Wahl.
Da ich hier falsch angefangen habe, muss ich die Daten migrieren.
Schauen, wo Docker die Daten hat.
$ docker volume ls | grep grafana$ sudo cp -r $(docker volume inspect grafana_grafana_data --format '{{.Mountpoint}}') ./grafana_data$ sudo chown -R 472:472 ./grafana_dataIn der docker-compose.yml anpassen
volumes:
- ./grafana_data:/var/lib/grafana # geändertTest
$ podman compose upDas hat erst einmal überhaupt nicht funktioniert. Hier war dann eine längere Troubleshooting-Session mit der Claude-KI.
Docker läuft im Hintergrund als Administrator (root). Egal welcher User einen Container startet – Docker hat immer vollen Zugriff auf alle Dateien. Das ist praktisch, aber nicht besonders sicher. Podman macht das anders: Es läuft ohne Administrator-Rechte, direkt als dein normaler Benutzer. Das ist sicherer, bedeutet aber: Wenn ein Container auf einen Ordner auf deinem Computer zugreift, muss genau geprüft werden, wer auf was zugreifen darf.
User-Mapping
Innerhalb eines Containers laufen Prozesse unter eigenen User-IDs – Grafana z.B. als User 472. Aber dieser User 472 existiert auf deinem Linux-System gar nicht. Podman löst das mit einem Trick: Es übersetzt (mapped) die User-IDs im Container auf echte IDs auf deinem System. Dein Benutzer lars bekommt dafür einen reservierten Bereich zugeteilt – die sogenannten Sub-UIDs:
lars:100000:65536Das bedeutet: Podman darf für lars die UIDs 100000 bis 165535 verwenden. User 472 im Container wird also auf uid 100471 auf dem Host gemappt (100000 + 472 - 1 = 100471).
Gehört ein Ordner auf dem Host einer anderen UID, bekommt Grafana im Container einen permission denied Fehler.
Troubleshooting Schritt für Schritt
Container läuft, aber Grafana-Fehler "readonly database"
Prüfen ob das Verzeichnis überhaupt gemountet wurde:
$ podman inspect grafana | grep -A 5 Mounts
"Mounts": [
{
"Type": "bind",
"Source": "/home/lars/grafana/grafana_data",
"Destination": "/var/lib/grafana",
"Driver": "",Welchen User nutzt der Prozess im Container?
$ podman exec grafana id
uid=472(grafana) gid=0(root) groups=0(root)Wie sieht Podman die Dateien auf dem Host?
$ podman unshare ls -la /home/lars/grafana/grafana_data/Zeigte nobody das User-Mapping stimmt nicht, die Dateien gehören der falschen UID.
Sub-UIDs prüfen
$ cat /etc/subuid
lars:100000:65536Korrekte UID berechnen und Berechtigungen setzen
Formel: Startuid + Container-UID - 1
Beispiel Grafana: 100000 + 472 - 1 = 100471
sudo chown -R 100471:100471 ./grafana_dataPods automatisch starten
Bei Docker gibt es einen Hintergrunddienst (Daemon), der immer läuft und Container automatisch starten kann. Podman hat keinen solchen Dienst.
Stattdessen nutzt Podman das Init-System von Linux: systemd. Systemd ist auf fast jedem modernen Linux dafür zuständig, Dienste beim Systemstart zu starten – z.B. dedenetzwerkdienst, dedenruckerdienst usw.
Der Start wird per Quadlet definiert. Ein Quadlet ist einfach eine Konfigurationsdatei, die systemd sagt: "Starte diesen Container wie einen normalen Dienst."
Hier im konkreten faFallrstellt man eine Datei grafana.container in einem bestimmten Ordner. Podman generiert daraus automatisch eine systemd-Unit – du musst dich um nichts weiter kümmern.
Ordner für rootless (als normaler User):
~/.config/containers/systemd/Datei erstellen
$ mkdir -p ~/.config/containers/systemd/
$ vim ~/.config/containers/systemd/grafana.containerInhalt
[Unit]
Description=Grafana
[Container]
Image=grafana/grafana:12.3-ubuntu
PublishPort=3000:3000
Volume=/home/lars/grafana/grafana_data:/var/lib/grafana
Environment=GF_SECURITY_ADMIN_USER=admin
Environment=GF_SECURITY_ADMIN_PASSWORD=passwordvongrafana
[Service]
Restart=always
[Install]
WantedBy=default.targetInitialisieren und starten
$ systemctl --user daemon-reload
$ systemctl --user enable grafana.service
$ systemctl --user start grafana.serviceDamit das auch beim Hochfahren und nicht erst beim Login des Users passiert, noch
$ sudo loginctl enable-linger larsNormalerweise startet systemd die User-Dienste des Users "lars" erst, wenn lars sich einloggt – und stoppt sie wieder, wenn lars sich ausloggt. Das macht Sinn für Desktop-Anwendungen, aber nicht für einen Server der immer laufen soll.
enable-linger sagt systemd: „Starte die Dienste von lars bereits beim Systemstart – und lass sie laufen, auch wenn niemand eingeloggt ist."
Passwörter sicher ablegen
Passwörter in der docker-compose.yml sind nicht gut.
Variante 1: .env Datei
Du lagerst die Passwörter in eine separate Datei aus:
$ vim ~/grafana/.envInhalt
GF_SECURITY_ADMIN_USER=admin
GF_SECURITY_ADMIN_PASSWORD=passwordvongrafanaIn der compose.yml rreferenzierst sie dann so:
environment:
- GF_SECURITY_ADMIN_USER=${GF_SECURITY_ADMIN_USER}
- GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD}Podman Compose liest die .env Datei automatisch ein.
Der Vorteil: Du kannst die compose.yml bedenkenlos in Git einchecken oder weitergeben – solange die .env Datei nicht dabei ist.
echo ".env" >> .gitignoreVariante 2: Podman Secrets
Podman hat einen eingebauten Mechanismus für Geheimnisse. Die Daten werden verschlüsselt gespeichert:
echo "passwordvongrafana" | podman secret create grafana_password -In der Quadlet-Datei:
Secret=grafana_password,type=env,target=GF_SECURITY_ADMIN_PASSWORDZeit gespart? Dann unterstütze doch it-zeugs.de
Wenn dieser Tipp dir geholfen hat, Zeit zu sparen, überlege bitte, eine kleine Spende zu hinterlassen. Dein Beitrag hilft mir, weiterhin wertvolle Inhalte zu erstellen. Du kannst unter diesem Linke spenden: Spende it-zeugs.de
Falld du nicht spenden willst oder kannst, dann wäre es toll, wenn du deinen nächsten Amazon Einkauf mit diesem Link beginnen würdest: Amazon Link. Für dich wird es nicht teurer, ich bekomme aber einen kleinen Beitrag.
Vielen herzlichen Dank ❤️

Hallo, hier schreibt Lars. Dipl-Ing. Ingenieurinformatik (FH). Seit Jahrzehnten in der IT tätig. Geprüfter (und begeisterter) Webmaster. Ebenso begeisterter Windows-, Apple-, und Office-User. Ich schreibe über alle möglichen Themen rund um IT. Mehr über mich erfährst du hier: Über mich. Danke für deinen Besuch!
