# Exkurs: Podman im Novaris-Projekt

Podman ist die Container-Runtime fuer die lokale Entwicklung und passt gut zur
OpenShift-Zielplattform. Die Bedienung ist Docker sehr aehnlich, Podman arbeitet
jedoch ohne dauerhaft laufenden zentralen Docker-Daemon. Wer mit Podman noch
gar nicht vertraut ist, findet die allgemeinen Grundlagen (ohne Projektbezug)
in der [Podman-Einfuehrung](19-podman-einfuehrung.md).

## 1. Architektur unter Windows

Unter Linux kann Podman Container direkt ausfuehren. Unter Windows laeuft dafuer
eine Linux-VM, die von Podman als **Podman-Machine** verwaltet wird:

```text
PowerShell
    |
    +-- podman CLI
            |
            +-- podman-machine-default (Linux-VM)
                    |
                    +-- Images, Container, Volumes, Netzwerke
```

Die Machine ist nicht dasselbe wie eine Docker-Desktop-Installation. Docker-
Desktop-Images, Docker-WSL-Distributionen und Podman-Images liegen in getrennten
Speichern.

```powershell
podman machine list
podman machine start
podman machine stop
podman machine ssh
```

Falls `podman` in einer bereits geoeffneten PowerShell nicht gefunden wird, ein
neues Terminal oeffnen oder den Podman-Installationspfad pruefen. Die Machine
kann trotzdem bereits installiert sein.

## 2. Images

Ein Image ist eine unveraenderliche Vorlage fuer Container. Repository und Tag
bilden zusammen die uebliche Referenz, zum Beispiel `nginx:latest` oder
`quay.io/keycloak/keycloak:latest`.

```powershell
podman images
podman image ls
podman images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}"
```

Images laden, bauen und entfernen:

```powershell
podman pull nginx:latest
podman build -t novaris-policy-core:local .
podman tag novaris-policy-core:local quay.io/example/novaris-policy-core:1.0
podman rmi novaris-policy-core:local
```

Lokale Images sind nicht automatisch in einer Registry. Fuer einen OpenShift-
Rollout muss das Image in eine erreichbare Registry gepusht werden:

```powershell
podman login quay.io
podman push quay.io/example/novaris-policy-core:1.0
```

## 3. Container

Ein Container ist eine laufende oder beendete Instanz eines Images.

```powershell
podman run -d --name web -p 8080:80 nginx:latest
podman ps
podman ps -a
podman logs web
podman inspect web
podman exec -it web sh
```

Der Port-Schalter bedeutet `Host-Port:Container-Port`. Der Dienst ist danach
unter `http://localhost:8080` erreichbar.

```powershell
podman stop web
podman start web
podman rm web
```

Das Entfernen eines Containers entfernt nicht automatisch das Image und nicht
automatisch ein benanntes Volume.

## 4. Volumes und Datenhaltung

Container-Dateisysteme sind temporaer. Datenbanken und andere dauerhafte Daten
gehoeren deshalb in Volumes:

```powershell
podman volume create postgres-data
podman volume ls
podman volume inspect postgres-data
podman run -d --name postgres `
  -e POSTGRES_PASSWORD=localdev `
  -v postgres-data:/var/lib/postgresql/data `
  postgres:16
```

Alle Podman-Ressourcen mit Speicherverbrauch anzeigen:

```powershell
podman system df -v
```

`podman volume prune` entfernt ungenutzte Volumes und kann Daten loeschen:

```powershell
podman volume ls
podman ps -a
podman volume prune
```

## 5. Netzwerke

Container koennen in einem eigenen Podman-Netzwerk miteinander kommunizieren:

```powershell
podman network create novaris-net
podman network ls
podman run -d --name policy-db --network novaris-net postgres:16
podman run -d --name policy-core --network novaris-net novaris-policy-core:local
podman network inspect novaris-net
```

Innerhalb des Netzwerks wird der Containername als Hostname verwendet. Die
Anwendung kann die Datenbank daher ueber `policy-db` erreichen, nicht ueber
`localhost`.

## 6. Pods und Kubernetes-Naehe

Ein Pod gruppiert Container, die gemeinsam Netzwerk- und Lebenszyklusregeln
nutzen. Das entspricht dem Betriebsmodell von Kubernetes und OpenShift:

```powershell
podman pod create --name novaris-pod -p 8080:8080
podman run -d --pod novaris-pod --name policy-core novaris-policy-core:local
podman pod ps
podman pod inspect novaris-pod
podman generate kube novaris-pod > novaris-pod.yaml
podman play kube novaris-pod.yaml
```

Das ersetzt kein OpenShift-Deployment mit Routes, Secrets, Policies und
Observability, ist aber eine gute Lernbruecke vom lokalen Container zum Cluster.

## 7. Compose mit Podman

Bestehende Compose-Projekte koennen meist weiterverwendet werden:

```powershell
podman compose up -d
podman compose ps
podman compose logs -f
podman compose down
```

Fuer dieses Projekt sollte die gemeinsame Infrastruktur aus
`../../shared/enterprise-infrastructure/` verwendet werden. Dadurch laufen Kafka, PostgreSQL, Keycloak,
Zipkin und Prometheus nur einmal fuer mehrere Lernprojekte:

```powershell
Set-Location ..\..\shared\enterprise-infrastructure
podman compose up -d
podman compose ps
```

Anwendungs-Compose-Dateien sollten deshalb keine zweite Kafka-, PostgreSQL- oder
Keycloak-Instanz starten, sofern die gemeinsame Infrastruktur erreichbar ist.

## 8. Docker-Befehle zu Podman uebertragen

| Zweck | Docker | Podman |
|---|---|---|
| Images | `docker images` | `podman images` |
| Container starten | `docker run ...` | `podman run ...` |
| Container anzeigen | `docker ps -a` | `podman ps -a` |
| Logs | `docker logs <name>` | `podman logs <name>` |
| Shell | `docker exec -it <name> sh` | `podman exec -it <name> sh` |
| Volumes | `docker volume ls` | `podman volume ls` |
| Netzwerke | `docker network ls` | `podman network ls` |
| Aufraeumen | `docker system prune` | `podman system prune` |

Nicht jede Docker-Desktop-Funktion hat eine identische Podman-Entsprechung.
Insbesondere Desktop-GUI, Docker-Desktop-Extensions und Docker-spezifische
Kontextverwaltung sind nicht Teil des normalen Podman-Workflows.

## 9. Sicherheit und Rootless-Betrieb

Podman ist fuer Rootless-Container ausgelegt. Fuer Produktionsnaehe gelten
folgende Regeln:

- keine Passwoerter direkt in Images einbauen
- Secrets ueber Umgebungsvariablen, Secret-Objekte oder Jenkins-Credentials zufuehren
- Images mit festen Versionen statt unkontrolliertem `latest` verwenden
- Container nur mit benoetigten Ports und Berechtigungen starten
- Logs, Healthchecks und Ressourcenverbrauch pruefen
- fuer OpenShift die vorhandenen SecurityContexts und NetworkPolicies beibehalten

## 10. Diagnose

```powershell
podman info
podman version
podman system df -v
podman stats
podman events
podman inspect <container>
```

| Problem | Pruefung |
|---|---|
| `podman` nicht gefunden | Neues Terminal, PATH und Installation pruefen |
| Machine nicht erreichbar | `podman machine list` und `podman machine start` |
| Port bereits belegt | `podman ps` und Windows-Portpruefung |
| Image fehlt | `podman images` oder `podman pull` |
| Anwendung erreicht Datenbank nicht | gleiches Netzwerk und Containername pruefen |
| Daten scheinbar weg | richtiges Volume mit `podman volume inspect` pruefen |

## 11. Aufraeumen ohne Datenverlust

Zuerst nur eine Bestandsaufnahme:

```powershell
podman ps -a
podman images
podman volume ls
podman network ls
podman system df -v
```

Danach koennen einzelne Ressourcentypen bereinigt werden:

```powershell
podman container prune
podman image prune
podman volume prune
```

Die umfassende Variante entfernt mehrere ungenutzte Ressourcentypen:

```powershell
podman system prune --volumes
```

Diese letzte Variante erst verwenden, wenn klar ist, dass keine lokalen
Datenbanken oder Testdaten mehr benoetigt werden.

## Merksatz

Images sind Vorlagen, Container sind Instanzen, Volumes enthalten dauerhafte
Daten, Netzwerke verbinden Services und Pods bilden die Bruecke zu Kubernetes.
Unter Windows verwaltet die Podman-Machine diese Linux-Container getrennt von
Docker Desktop.
