Podman ist eine Docker-kompatible Container-Engine, die ohne Root-Rechte läuft. Sie bietet bessere Sicherheit und ist der Standard auf RHEL/CentOS.

Installation

# Debian/Ubuntu
apt install podman

# RHEL/CentOS
dnf install podman

# Version prüfen
podman --version

Grundlagen

Docker-Kompatibilität

# Alias setzen (optional)
alias docker=podman

# Die meisten Docker-Befehle funktionieren
podman pull nginx
podman run -d -p 80:80 nginx
podman ps
podman stop container_id

Rootless vs Root

# Als normaler User (rootless)
podman run -d nginx

# Als Root (wie Docker)
sudo podman run -d nginx

# Images sind getrennt!
podman images        # User-Images
sudo podman images   # Root-Images

Container

Container starten

# Interaktiv
podman run -it alpine sh

# Im Hintergrund
podman run -d --name webserver -p 8080:80 nginx

# Mit Volume
podman run -d -v /host/data:/data:Z nginx

# Mit Umgebungsvariablen
podman run -d -e MYSQL_ROOT_PASSWORD=secret mysql

Container verwalten

# Auflisten
podman ps           # Laufende
podman ps -a        # Alle

# Stoppen
podman stop webserver
podman stop -a      # Alle

# Starten
podman start webserver

# Entfernen
podman rm webserver
podman rm -f webserver  # Erzwingen

Container-Infos

# Logs
podman logs webserver
podman logs -f webserver  # Follow

# Prozesse
podman top webserver

# Ressourcen
podman stats

# Details
podman inspect webserver

In Container einsteigen

# Shell
podman exec -it webserver /bin/bash

# Befehl ausführen
podman exec webserver cat /etc/nginx/nginx.conf

Images

Images verwalten

# Suchen
podman search nginx

# Herunterladen
podman pull docker.io/library/nginx
podman pull nginx  # Kurz

# Auflisten
podman images

# Entfernen
podman rmi nginx
podman rmi -a  # Alle ungenutzten

Eigenes Image erstellen

# Aus Container
podman commit container_id myimage:v1

# Mit Containerfile (wie Dockerfile)
podman build -t myapp:v1 -f Containerfile .

Containerfile

# Containerfile
FROM debian:bullseye-slim

RUN apt-get update && \
    apt-get install -y nginx && \
    rm -rf /var/lib/apt/lists/*

COPY index.html /var/www/html/

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
# Bauen
podman build -t mywebserver:v1 .

# Ausführen
podman run -d -p 8080:80 mywebserver:v1

Pods

Pod erstellen

# Leeren Pod erstellen
podman pod create --name mypod -p 8080:80

# Pod mit Container
podman run -d --pod mypod --name web nginx
podman run -d --pod mypod --name php php:fpm

Pod-YAML

# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: webstack
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
      hostPort: 8080
  - name: php
    image: php:fpm
# Pod aus YAML erstellen
podman play kube pod.yaml

# Pod stoppen
podman pod stop webstack

# Pod entfernen
podman pod rm webstack

Pod verwalten

# Pods auflisten
podman pod ls

# Pod-Details
podman pod inspect mypod

# Pod stoppen/starten
podman pod stop mypod
podman pod start mypod

# Pod entfernen
podman pod rm mypod

Volumes

Volume erstellen

# Named Volume
podman volume create mydata

# Auflisten
podman volume ls

# Details
podman volume inspect mydata

Volume verwenden

# Mit Named Volume
podman run -d -v mydata:/var/lib/mysql mysql

# Mit Bind Mount
podman run -d -v /host/path:/container/path nginx

# Mit SELinux-Label (:Z)
podman run -d -v /host/data:/data:Z nginx

Volume-Optionen

| Option | Beschreibung | |--------|--------------| | :ro | Nur Lesen | | :rw | Lesen/Schreiben | | :Z | Private SELinux-Label | | :z | Shared SELinux-Label |

Netzwerk

Netzwerke verwalten

# Netzwerk erstellen
podman network create mynet

# Auflisten
podman network ls

# Details
podman network inspect mynet

# Entfernen
podman network rm mynet

Container mit Netzwerk

# Container in Netzwerk starten
podman run -d --network mynet --name web nginx
podman run -d --network mynet --name db mysql

# Container können sich über Namen erreichen
podman exec web ping db

Systemd-Integration

Service generieren

# Systemd-Unit generieren
podman generate systemd --name webserver --files

# In User-Service-Verzeichnis
mkdir -p ~/.config/systemd/user/
podman generate systemd --name webserver > ~/.config/systemd/user/container-webserver.service

# Service aktivieren (rootless)
systemctl --user daemon-reload
systemctl --user enable container-webserver.service
systemctl --user start container-webserver.service

Auto-Start beim Login

# Für rootless Container
loginctl enable-linger $USER

Root-Service

# Als Root generieren
sudo podman generate systemd --name webserver > /etc/systemd/system/container-webserver.service
sudo systemctl daemon-reload
sudo systemctl enable container-webserver.service

Quadlet (Podman 4.4+)

Container als Systemd-Unit

# ~/.config/containers/systemd/nginx.container
[Unit]
Description=Nginx Container

[Container]
Image=docker.io/library/nginx
PublishPort=8080:80
Volume=/srv/www:/usr/share/nginx/html:ro,Z

[Service]
Restart=always

[Install]
WantedBy=default.target
# Systemd neu laden
systemctl --user daemon-reload

# Service starten
systemctl --user start nginx

Compose

Podman-Compose

# Installation
pip install podman-compose

# Oder
apt install podman-compose

docker-compose.yml verwenden

# docker-compose.yml
version: '3'
services:
  web:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html

  db:
    image: mariadb
    environment:
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:
# Starten
podman-compose up -d

# Status
podman-compose ps

# Stoppen
podman-compose down

Registries

Registry-Konfiguration

# /etc/containers/registries.conf

[registries.search]
registries = ['docker.io', 'quay.io', 'registry.fedoraproject.org']

[registries.insecure]
registries = ['myregistry.local:5000']

Login

# Docker Hub
podman login docker.io

# Andere Registry
podman login myregistry.local:5000

Push

# Image taggen
podman tag myapp:v1 docker.io/myuser/myapp:v1

# Pushen
podman push docker.io/myuser/myapp:v1

Sicherheit

Rootless-Vorteile

# Container läuft als User
podman run --rm alpine id
# uid=0(root) - aber nur im Container!

# Auf Host ist es ein normaler User
ps aux | grep conmon

Capabilities einschränken

# Ohne Capabilities
podman run --cap-drop=ALL nginx

# Nur benötigte
podman run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx

Read-Only Filesystem

podman run --read-only -v /tmp:/tmp nginx

Troubleshooting

Häufige Probleme

# "Permission denied" bei Volumes
# → SELinux-Label verwenden
podman run -v /data:/data:Z nginx

# Rootless Port < 1024
# → Unprivilegierten Port verwenden
# Oder: sysctl net.ipv4.ip_unprivileged_port_start=80

Debugging

# Verbose
podman --log-level=debug run nginx

# Container-Logs
podman logs -f container_name

# Events
podman events

Zusammenfassung

| Befehl | Funktion | |--------|----------| | podman run | Container starten | | podman ps | Container auflisten | | podman exec | In Container arbeiten | | podman build | Image erstellen | | podman pod create | Pod erstellen | | podman generate systemd | Systemd-Service |

| Feature | Podman | Docker | |---------|--------|--------| | Rootless | Native | Experimentell | | Daemon | Keiner | dockerd | | Pods | Ja | Nein | | Compose | Via Tool | Nativ | | Systemd | Integriert | Manuell |

| Datei | Funktion | |-------|----------| | /etc/containers/registries.conf | Registry-Config | | ~/.config/containers/ | User-Config | | Containerfile | Image-Definition |

Fazit

Podman ist die sichere Alternative zu Docker. Rootless-Betrieb erhöht die Sicherheit erheblich. Die Docker-Kompatibilität erleichtert den Umstieg. Pods ermöglichen Kubernetes-ähnliche Deployments. Die Systemd-Integration macht Container zu First-Class-Services.