- Package #9-11: catatonit (pod infra init), nftables (netavark firewall backend), docker-compose (external compose provider for `podman compose`) — all vendored prebuilt binaries, versions.env pinned, propagated through build-packages.sh/release.sh/podman.plg/verify+update-packages.sh. - Fix WebUI: every POST action was silently failing (empty response body) because Unraid's own CSRF protection was never satisfied — app.js now sends the page's csrf_token as X-CSRF-Token. - Fix WebUI: PodmanClient::pullImage() assumed a single JSON response, but /images/pull actually streams newline-delimited JSON — every successful pull was throwing "Expected a JSON object/array response". - Fix WebUI: compose.php's up/down status detection had the same single-JSON-vs-NDJSON bug for `podman compose ps`, plus stderr was corrupting the parse. - Add cache-busting (?v=<mtime>) to Podman.page's script/style tags so a redeployed JS/CSS fix isn't served stale from browser cache. - Add a reusable modal dialog (app.js openFormModal) replacing prompt()/alert() for New Volume/Network/Pull Image. - Add host-path (bind-mount) support when creating a named volume. - Add Create Container (image, name, network mode incl. custom networks, ports, volumes, env, restart policy, privileged, start-after-create), auto-pulling the image on first use since /containers/create doesn't. All fixes verified live against a real podman system service and, where reachable, via the actual WebUI over the real socket — not just unit-level. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
671 lines
38 KiB
Markdown
671 lines
38 KiB
Markdown
# unraid-podman — Architekturplanung
|
||
|
||
Natives Unraid-Plugin zur vollständigen Integration von Podman (rootful, Phase 1) als
|
||
gleichberechtigte Alternative zu Docker, mit dem langfristigen Ziel, Docker optional
|
||
abschaltbar zu machen.
|
||
|
||
Status: Planungsdokument, kein Code. Dient als Grundlage für Implementierungs-Tickets.
|
||
|
||
---
|
||
|
||
## 0. Ziele & Nicht-Ziele
|
||
|
||
**Ziele (Phase 1 / MVP):**
|
||
- Podman rootful lauffähig unter Unraid, überlebt Reboots (Config, Images, Container, Volumes, Netzwerke).
|
||
- Koexistenz mit Docker ohne Konflikte (Storage, Netzwerk, Ports, iptables-Ketten).
|
||
- Start/Stop/Autostart analog zum bestehenden `rc.docker`-Muster, ohne systemd.
|
||
- Sauberer Update-/Rollback-Pfad für das Plugin selbst.
|
||
- Grundlegendes Logging & Fehlerdiagnose, das GUI-Meldungen von Unraid nutzt.
|
||
- Vorbereitung (nicht Umsetzung) einer WebUI-Anbindung.
|
||
|
||
**Nicht-Ziele (bewusst verschoben):**
|
||
- Rootless Podman (Phase 2+, andere Storage-/UID-Mapping-Anforderungen).
|
||
- Podman Pods / Kubernetes-YAML-Support (Phase 3, siehe Roadmap).
|
||
- 1:1-Ersatz der Community-Applications-Vorlagen (erfordert eigenen Übersetzungslayer, separat geplant).
|
||
- Abschalten von Docker (erst wenn Podman-Pfad stabil ist, siehe Abschnitt 17).
|
||
|
||
---
|
||
|
||
## 1. Rahmenbedingungen von Unraid, die die Architektur erzwingen
|
||
|
||
| Eigenschaft | Konsequenz für das Plugin |
|
||
|---|---|
|
||
| Unraid läuft komplett im RAM (SquashFS + tmpfs-Overlay via `unionfs`) | Alles, was `/`, `/etc`, `/usr`, `/var` betrifft, ist bei jedem Reboot verloren. Nichts darf implizit dort persistiert werden. |
|
||
| Persistenter Speicher nur unter `/boot` (USB-Stick, FAT32, klein, langsam, schreibintensiv riskant) und `/mnt/*` (Array/Cache/Pools) | Konfiguration klein & textbasiert auf `/boot/config/plugins/...`; große/volatile Daten (Images, Container-Storage, Logs) auf Array/Cache. |
|
||
| Kein systemd, sondern BSD-artige `/etc/rc.d/rc.*`-Skripte, angestoßen über `/boot/config/go` | Eigenes `rc.podman`-Init-Skript im klassischen `start|stop|restart|status`-Stil, keine `.service`-Units, keine `systemctl`-Aufrufe irgendwo im Code. |
|
||
| Slackware-Basis, Pakete als `.txz` (pkgtools: `installpkg`/`upgradepkg`/`removepkg`) | Podman + Abhängigkeiten müssen als Slackware-kompatible `.txz` gebaut werden, nicht als RPM/DEB. |
|
||
| Plugins werden über `.plg`-XML installiert (lädt Pakete, führt `<FILE>`-Blöcke mit Pre-/Post-Scripts aus) | Das `.plg` ist der zentrale Installations-/Update-/Deinstallations-Mechanismus, vergleichbar mit einem deklarativen Installer. |
|
||
| `/mnt/user` (shfs/FUSE) hat Einschränkungen für Overlay-Filesysteme (fehlendes `d_type` in manchen Konstellationen, FUSE-Overhead) | Podman-Storage (`overlay`-Driver) nicht direkt auf `/mnt/user/...` legen, sondern auf ein dediziertes Loopback-Image oder einen direkt gemounteten Pool/Disk-Pfad (Analogie zu `docker.img` bzw. Docker-„Directory“-Modus seit 6.12). |
|
||
| Array kann offline sein / erst spät im Boot verfügbar (`emhttpd`, Array-Start ist ein User-Trigger, kein automatischer Boot-Schritt) | `rc.podman` darf nicht blind beim Boot starten, sondern muss auf Array-/Pool-Verfügbarkeit warten bzw. vom `dynamix`-Event „array started“ getriggert werden, wie es `rc.docker` heute schon tut. |
|
||
| Unraid pflegt eigene Firewall-/NAT-Logik (`iptables`) für Docker-Netzwerke (`docker0`, custom bridges, macvlan) | Podman-Netzwerke (netavark) müssen eigene, klar abgegrenzte iptables-Ketten/Chains verwenden, um nicht mit Dockers Regeln zu kollidieren. |
|
||
|
||
---
|
||
|
||
## 2. Gesamtarchitektur (Überblick)
|
||
|
||
```
|
||
┌───────────────────────────────────────────┐
|
||
│ /boot (USB, FAT32) │
|
||
│ config/plugins/podman/ │
|
||
│ ├─ podman.cfg (Settings) │
|
||
│ ├─ autostart (Flat-File) │
|
||
│ ├─ network.json │
|
||
│ ├─ containers.conf / storage.conf (Vorlagen)
|
||
│ └─ backup/ (vorherige Paketversionen) │
|
||
└───────────────────┬─────────────────────────┘
|
||
│ beim Boot kopiert nach /etc, /var/lib
|
||
▼
|
||
┌────────────────────────────────────────────────────────────────────┐
|
||
│ RAM-Root (tmpfs/unionfs) │
|
||
│ /etc/rc.d/rc.podman (Init-Skript) │
|
||
│ /etc/containers/* (aus /boot kopiert) │
|
||
│ /usr/bin/podman, conmon, crun, netavark, aardvark-dns, ... │
|
||
│ /usr/local/emhttp/plugins/podman/ (WebUI-Stub, PHP) │
|
||
└───────────────────────────┬───────────────────────────────────────┘
|
||
│ bind-mount / Storage-Root zeigt auf
|
||
▼
|
||
┌────────────────────────────────────────────────────────────────────┐
|
||
│ Persistenter Bereich (Cache-Pool empfohlen) │
|
||
│ /mnt/cache/system/podman/ │
|
||
│ ├─ podman.img (Loopback, XFS/BTRFS, für overlay-Storage) │
|
||
│ │ → gemountet auf /var/lib/containers/storage │
|
||
│ ├─ logs/ │
|
||
│ └─ networks/ (netavark state, falls nicht im Image) │
|
||
└────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
Kernprinzip: **Trennung von „Konfiguration“ (klein, Text, `/boot`) und „Nutzdaten“
|
||
(groß, binär, Array/Cache)** — exakt das bestehende Unraid-Muster, das auch
|
||
`dynamix.docker.manager` verwendet.
|
||
|
||
---
|
||
|
||
## 3. Pluginstruktur
|
||
|
||
### 3.1 Repository-Layout (Build-/Source-Repo, nicht das, was auf Unraid landet)
|
||
|
||
```
|
||
unraid-podman/
|
||
├── podman.plg # Haupt-Plugin-Manifest (XML)
|
||
├── packages/ # Slackware .txz Build-Rezepte
|
||
│ ├── podman/
|
||
│ ├── conmon/
|
||
│ ├── crun/
|
||
│ ├── netavark/
|
||
│ ├── aardvark-dns/
|
||
│ ├── containers-common/
|
||
│ ├── fuse-overlayfs/
|
||
│ └── passt/
|
||
├── source/
|
||
│ ├── rc.podman # Init-Skript
|
||
│ ├── podman-preflight.sh # Startup-Checks
|
||
│ ├── podman-autostart.sh
|
||
│ ├── podman-backup.sh
|
||
│ └── config-templates/
|
||
│ ├── containers.conf
|
||
│ ├── storage.conf
|
||
│ └── registries.conf
|
||
├── emhttp/
|
||
│ └── plugins/podman/ # WebUI (PHP/JS), Phase 2+
|
||
├── scripts/
|
||
│ ├── build-packages.sh
|
||
│ └── release.sh
|
||
└── CHANGELOG.md
|
||
```
|
||
|
||
### 3.2 `.plg`-Manifest — Verantwortlichkeiten
|
||
|
||
Das `.plg` ist eine deklarative XML-Datei, die von Unraids `plugin`-Kommando
|
||
interpretiert wird. Verantwortlich für:
|
||
|
||
- **Metadaten**: `<plugin name="podman" version="..." pluginURL="..." min="..." />` inkl.
|
||
Mindest-Unraid-Version (Kernel-/glibc-Kompatibilität der Podman-Binaries).
|
||
- **Entity-Variablen** (XML-Entities) für Basis-URL, Version, MD5-Summen — ermöglicht
|
||
Update-Checks über den Plugin-Manager der GUI.
|
||
- **`<FILE>`-Blöcke**:
|
||
1. Download & Installation aller acht `.txz`-Pakete (die sieben Komponenten
|
||
plus das plugin-eigene `unraid-podman`-Scaffolding-Paket) einheitlich per
|
||
`upgradepkg --install-new --reinstall` — funktioniert unverändert für
|
||
Erstinstallation und Update (bestätigtes Muster echter Unraid-Plugins,
|
||
siehe unten).
|
||
2. `<INLINE>`-Postinstall-Skript: Setzen von Berechtigungen, Anlegen der
|
||
Verzeichnisstruktur unter `/boot/config/plugins/podman/` (nur beim ersten
|
||
Install, idempotent; Configs nur kopiert, wenn nicht vorhanden — kein
|
||
Überschreiben bestehender Nutzerkonfiguration bei Updates), Schreiben der
|
||
Versions-Manifest-Datei, erster `rc.podman start`.
|
||
- **Array-Start/Stop-Hook**: **kein** Eintrag in `/boot/config/go`. Stattdessen
|
||
der offizielle Unraid-Plugin-Event-Mechanismus:
|
||
`/usr/local/emhttp/plugins/podman/event/disks_mounted` (startet `rc.podman`,
|
||
sobald Cache-Pools/Disks gemountet sind) und `.../event/stopping` (stoppt
|
||
`rc.podman` synchron als allererster Schritt der Shutdown-Sequenz, bevor
|
||
Unraid die zugrundeliegende Disk unmountet). Dieses Verzeichnis-Konvention
|
||
wurde gegen den echten Quellcode etablierter Plugins verifiziert (u. a.
|
||
`unassigned.devices`, das exakt dieselben `event/`-Hooks für
|
||
`disks_mounted`/`stopping_svcs` verwendet) — kein `/boot/config/go`-Edit
|
||
nötig, dadurch auch beim Deinstallieren nichts manuell rückgängig zu machen.
|
||
- **`<FILE Run="/bin/bash" Method="remove">`-Block für Deinstallation**: ruft
|
||
zuerst `podman-uninstall-cleanup.sh` auf (stoppt `rc.podman`, räumt
|
||
Laufzeitzustand auf), dann `removepkg` für alle acht Pakete. Lässt Nutzdaten
|
||
unter `/mnt/*` und `/boot/config/plugins/podman/` standardmäßig **stehen**
|
||
(explizite Option „Restlose Deinstallation inkl. Daten“ via
|
||
`--purge-data`-Flag, kein automatisches Löschen von Nutzdaten).
|
||
|
||
### 3.3 Namens- und Versionskonventionen
|
||
|
||
- Plugin-Name: `podman` (Namespace-Kollisionen mit CA-Plugins prüfen).
|
||
- Paket-Versionierung getrennt von Plugin-Versionierung: `podman.plg` trägt eine eigene
|
||
SemVer (`1.2.0`), referenziert aber exakte Upstream-Versionen der Binärpakete
|
||
(`podman-5.x.x`, `netavark-1.x.x`, ...) — erlaubt Plugin-Patches (z. B. am
|
||
Init-Skript) ohne Podman-Versionssprung.
|
||
|
||
---
|
||
|
||
## 4. Verzeichnislayout (vollständig)
|
||
|
||
### 4.1 Auf dem Flash-Device (`/boot`, persistent, klein)
|
||
|
||
```
|
||
/boot/config/plugins/podman/
|
||
├── podman.cfg # Key=Value, analog docker.cfg (Storage-Pfad, Enable, Optionen)
|
||
├── autostart # eine Container-ID/-Name pro Zeile, Reihenfolge = Startreihenfolge
|
||
├── autostart-delay # optionale Wartezeiten pro Container (Key=Sekunden)
|
||
├── containers.conf # Vorlage, wird nach /etc/containers/ kopiert
|
||
├── storage.conf # Vorlage, referenziert podman.img-Pfad
|
||
├── registries.conf
|
||
├── policy.json
|
||
├── networks/ # persistierte netavark-Netzwerkdefinitionen (JSON)
|
||
├── backup/
|
||
│ ├── packages/<version>/*.txz # vorherige Paketversionen für Rollback
|
||
│ └── config/<timestamp>/ # Config-Snapshots vor Updates
|
||
└── plugin.log # Install-/Update-Log des Plugins selbst
|
||
```
|
||
|
||
`/boot/config/plugins/podman/` ist bewusst analog zu
|
||
`/boot/config/plugins/dynamix.docker.manager/` gehalten (Wiedererkennung für
|
||
erfahrene Unraid-Nutzer, Support-Vergleichbarkeit).
|
||
|
||
### 4.2 Laufzeit (RAM-Root, bei jedem Boot neu aufgebaut)
|
||
|
||
```
|
||
/etc/rc.d/rc.podman # Init-Skript (Symlink-Ziel oder direkt kopiert)
|
||
/etc/containers/{containers,storage,registries}.conf # aus /boot kopiert
|
||
/etc/containers/policy.json
|
||
/etc/cni/ (falls CNI-Fallback statt netavark benötigt)
|
||
/usr/bin/{podman,conmon,crun,fuse-overlayfs,passt,pasta}
|
||
/usr/libexec/podman/{netavark,aardvark-dns} # matches upstream's own layout
|
||
/usr/local/emhttp/plugins/podman/ # WebUI-Stub (statisch aus Paket)
|
||
/var/run/podman/podman.sock # API-Socket (rootful)
|
||
/var/log/podman -> /mnt/cache/system/podman/logs # Symlink, siehe Abschnitt 13
|
||
```
|
||
|
||
### 4.3 Persistente Nutzdaten (Cache-Pool bevorzugt, Array als Fallback)
|
||
|
||
```
|
||
/mnt/cache/system/podman/ # analog /mnt/user/system/docker/
|
||
├── podman.img # Loopback-Datei, XFS (ftype=1) oder BTRFS
|
||
│ # → gemountet auf /var/lib/containers/storage
|
||
├── logs/
|
||
│ ├── containers/<id>.log
|
||
│ └── podman-service.log
|
||
└── networks/ # falls netavark-State nicht im Image liegt
|
||
```
|
||
|
||
**Warum Cache-Pool statt `/mnt/user`:** Der `overlay`-Storage-Driver benötigt native
|
||
Dateisystemsemantik (d_type, xattrs, Hardlinks) ohne den FUSE-Layer von `shfs`. Das
|
||
Docker-Vorbild löst das identisch mit `docker.img`/Directory-Modus auf einem echten
|
||
Mountpoint. Nutzer ohne Cache-Pool müssen einen Array-Disk-Pfad (`/mnt/diskX/system/podman`)
|
||
wählen können — mit deutlicher GUI-Warnung bzgl. Performance und Spin-up-Verhalten.
|
||
|
||
---
|
||
|
||
## 5. Paketmanagement
|
||
|
||
### 5.1 Zu paketierende Komponenten
|
||
|
||
| Paket | Zweck | Bemerkung |
|
||
|---|---|---|
|
||
| `podman` | Kern-Binary | Statisch gegen möglichst wenige glibc-Versionen bauen oder gegen Unraid-Slackware-Base kompilieren |
|
||
| `conmon` | Container-Monitor-Prozess | Pflicht |
|
||
| `crun` (empfohlen) / `runc` | OCI-Runtime | `crun` bevorzugt (leichter, cgroup v2-freundlich, kompatibel zu Unraids Kernel-Config) |
|
||
| `netavark` + `aardvark-dns` | Netzwerk-Backend + DNS | Ersetzt CNI-Plugins als Default seit Podman 4.x |
|
||
| `containers-common` | Default-Configs (`containers.conf`, `seccomp.json`, `registries.conf`) | Wird als Vorlage übernommen, nicht als aktive Config |
|
||
| `fuse-overlayfs` | Fallback-Storage-Driver | Für Rootless-Phase 2 vorbereitet, in Phase 1 optional |
|
||
| `passt`/`pasta` | Rootless-Networking | Nachfolger von slirp4netns, Phase 2, aber Paket schon mitbauen (geringe Kosten) |
|
||
| `catatonit` oder `tini` | Init-Prozess in Containern (optional, falls von Templates genutzt) | |
|
||
| `nftables` | Firewall-Backend für `netavark` | Pflicht seit netavark 2.0 (iptables-Treiber entfernt); Unraid liefert kein `nft` mit — als offizielles Slackware-Paket vendored, nicht selbst gebaut |
|
||
| `docker-compose` (CLI-Plugin) | External-Compose-Provider für `podman compose` | `podman compose` hat keine eigene Compose-Implementierung, sondern sucht ein `docker-compose`-Binary in festen CLI-Plugin-Pfaden; ohne dieses Paket schlägt jede Compose-Panel-Aktion auf einem frischen Unraid-Install fehl |
|
||
|
||
### 5.2 Build-Strategie
|
||
|
||
- Eigene Build-Pipeline (containerisiert, z. B. in einem Slackware-kompatiblen
|
||
Build-Container) statt manuellem Cross-Compile auf laufenden Unraid-Systemen.
|
||
- Zielarchitektur: `x86_64` (Unraid unterstützt aktuell keine anderen Architekturen
|
||
produktiv) — vereinfacht Matrix erheblich.
|
||
- Statisch oder minimal dynamisch gelinkt (Go-Binaries von Podman/netavark/aardvark-dns
|
||
sind ohnehin größtenteils statisch), um Abhängigkeits-Drift gegenüber der jeweils
|
||
aktuellen Unraid-Slackware-Basis zu minimieren.
|
||
- Jedes Paket als eigenständiges `.txz` mit Slackware-Standard-Metadaten
|
||
(`slack-desc`, `doinst.sh`), damit `removepkg`/`upgradepkg` korrekt funktionieren.
|
||
- Versions-Pinning: Das `.plg` referenziert exakte Paketversionen + MD5, kein
|
||
„latest“-Pull zur Laufzeit — reproduzierbare Installationen, Voraussetzung für Rollback.
|
||
|
||
### 5.3 Abhängigkeitsprüfung
|
||
|
||
- Preflight-Check im `.plg`-Postinstall: Kernel-Version, `cgroup v2` aktiv,
|
||
vorhandene `iptables`/`nftables`-Binaries, freier Platz auf Zielpfad für
|
||
`podman.img`. Bei Nichterfüllung: Installation abbrechen mit klarer GUI-Meldung
|
||
statt eines halb-funktionsfähigen Zustands.
|
||
|
||
---
|
||
|
||
## 6. Start-/Stop-Skripte
|
||
|
||
### 6.1 `rc.podman` — Design analog zu `rc.docker`
|
||
|
||
Klassisches Slackware-BSD-Init-Skript mit Case-Dispatch:
|
||
|
||
```
|
||
rc.podman start # Preflight → Storage mounten → API-Service starten → Autostart-Liste abarbeiten
|
||
rc.podman stop # Container geordnet stoppen (Timeout) → API-Service stoppen → Storage unmounten
|
||
rc.podman restart
|
||
rc.podman status # Health-Check-Ausgabe für GUI/CLI
|
||
```
|
||
|
||
Kernschritte von `start` (konzeptionell, kein Code):
|
||
|
||
1. **Preflight** (`podman-preflight.sh`): prüft, ob konfigurierter Storage-Pfad
|
||
(Cache-Pool/Disk) gemountet ist; falls `podman.img` fehlt → anlegen (Erstinstallation)
|
||
mit konfigurierter Größe; falls vorhanden → per Loopback mounten.
|
||
2. **Config-Sync**: Kopiert `/boot/config/plugins/podman/*.conf` nach
|
||
`/etc/containers/` (Boot-Config ist „Source of Truth“, Laufzeit-Kopie ist Cache).
|
||
3. **Socket-Service starten**: `podman system service` im Hintergrund (rootful Unix-Socket
|
||
unter `/var/run/podman/podman.sock`), damit spätere WebUI/API-Konsumenten und CLI
|
||
dieselbe Instanz sehen (statt pro Aufruf neuer Podman-Fork-Prozesse ohne gemeinsamen State
|
||
— State liegt zwar in `/var/lib/containers`, ein Service vereinfacht aber Health-Checks,
|
||
Event-Streaming und spätere WebUI-Anbindung).
|
||
4. **Netzwerke wiederherstellen**: netavark-Netzwerkdefinitionen aus
|
||
`/boot/config/plugins/podman/networks/` nach `/etc/containers/networks/` synchronisieren.
|
||
5. **Autostart** (`podman-autostart.sh`, siehe Abschnitt 10).
|
||
6. **Statusdatei** schreiben (für GUI-Polling), Event ins Unraid-Log (`logger`).
|
||
|
||
`stop` in umgekehrter Reihenfolge, mit konfigurierbarem Stop-Timeout pro Container
|
||
(analog Dockers „Stop timeout“-Einstellung), danach `podman system service` beenden,
|
||
zuletzt Loopback-Storage sauber unmounten (verhindert Dateisystemfehler im `podman.img`).
|
||
|
||
### 6.2 Boot-Integration
|
||
|
||
- **Offizieller Unraid-Plugin-Event-Mechanismus**, kein `/boot/config/go`-Edit:
|
||
Unraids `emhttpd` führt bei jedem Array-/Boot-Event automatisch jedes
|
||
ausführbare Skript unter `/usr/local/emhttp/plugins/<name>/event/<eventname>`
|
||
aus, sofern vorhanden. Dieses Verhalten wurde gegen den echten Quellcode
|
||
etablierter Plugins verifiziert (`unassigned.devices` nutzt exakt dieselbe
|
||
Konvention für seine `disks_mounted`/`started`/`stopping_svcs`-Hooks).
|
||
unraid-podman nutzt zwei Events:
|
||
- `event/disks_mounted` — feuert, sobald Array-Disks **und** Cache-Pools
|
||
gemountet sind (Unraids Event-Reihenfolge: `starting` → `array_started` →
|
||
`disks_mounted` → `svcs_restarted` → `docker_started` → `libvirt_started`
|
||
→ `started`). Ruft `rc.podman start` im Hintergrund auf (`& disown`),
|
||
damit der Array-Start nicht blockiert.
|
||
- `event/stopping` — der **erste** Schritt der Shutdown-Sequenz (vor
|
||
`stopping_docker`, `stopping_svcs`, `unmounting_disks`, `stopping_array`).
|
||
Ruft `rc.podman stop` **synchron** auf, damit Container gestoppt und
|
||
`podman.img` sauber unmountet sind, bevor Unraid die zugrundeliegende
|
||
Disk/den Cache-Pool unmountet.
|
||
|
||
Dadurch kein Start vor Verfügbarkeit von Cache/Array, und beim Deinstallieren
|
||
ist nichts manuell rückgängig zu machen — die Hook-Skripte verschwinden
|
||
automatisch mit `removepkg` des `unraid-podman`-Pakets (siehe Abschnitt 3.2).
|
||
|
||
---
|
||
|
||
## 7. Persistenz-Strategie (Zusammenfassung der Prinzipien)
|
||
|
||
| Datenkategorie | Ablageort | Synchronisationsrichtung |
|
||
|---|---|---|
|
||
| Plugin-Settings (Storage-Pfad, Feature-Flags) | `/boot/config/plugins/podman/podman.cfg` | Boot → Laufzeit (read-only Kopie) |
|
||
| Container-/Netzwerk-/Registry-Config | `/boot/config/plugins/podman/*.conf` | Boot → Laufzeit bei jedem Start |
|
||
| Autostart-Liste & Reihenfolge | `/boot/config/plugins/podman/autostart` | Boot → Laufzeit; GUI schreibt zurück nach `/boot` |
|
||
| Images, Container, named Volumes, Layer-Cache | `podman.img` auf Cache-Pool | Laufzeit-only, Backup optional via Snapshot |
|
||
| Logs | Cache-Pool `logs/` | Laufzeit-only, Rotation |
|
||
| Netzwerk-Definitionen (netavark JSON) | Boot-Kopie + Laufzeit-Kopie | bidirektional bei Änderung über GUI/CLI (Watcher oder expliziter „Apply“-Schritt) |
|
||
|
||
Grundregel: **Jede Änderung, die ein Nutzer über CLI/GUI an persistenzrelevanten
|
||
Objekten vornimmt (neues Netzwerk, geänderte Autostart-Reihenfolge), muss explizit
|
||
oder per Watcher nach `/boot/config/plugins/podman/` zurückgeschrieben werden** —
|
||
sonst geht sie beim nächsten Reboot verloren. Das ist der Kernunterschied zu
|
||
Standard-Linux-Distributionen und der häufigste Fehlerquell-Kandidat bei Docker-artigen
|
||
Unraid-Plugins.
|
||
|
||
---
|
||
|
||
## 8. Netzwerke
|
||
|
||
- **Backend**: `netavark` + `aardvark-dns` (Podman-Default seit 4.x), kein CNI in Phase 1.
|
||
- **Firewall-Treiber**: `netavark` >= 2.0 hat seinen `iptables`-Treiber ersatzlos entfernt —
|
||
nur noch `nftables` oder `firewalld` (Letzteres braucht systemd/dbus, hat Unraid nicht).
|
||
`nftables` ist also zwingend, aber Unraid OS bringt das `nft`-Binary selbst nicht mit
|
||
(nur das ältere `iptables`/`iptables-nft`) — muss vom Plugin bereitgestellt werden
|
||
(verifiziert per Live-Test: `podman run` mit Port-Publishing scheitert ohne `nft`
|
||
mit „Must provide a valid firewall backend“).
|
||
- **Default-Bridge**: eigene Bridge `podman0` (nicht `docker0`), eigener privater
|
||
Adressraum (konfigurierbar, Default-Vorschlag außerhalb von Dockers Default-Range,
|
||
um Kollisionen bei Parallelbetrieb zu vermeiden).
|
||
- **Custom Networks**: analog Docker-für-Unraid „Custom Networks“-Feature — GUI-Verwaltung
|
||
in Phase 2, Config-Persistenz-Mechanismus aber bereits in Phase 1 vorsehen (Abschnitt 7).
|
||
- **macvlan/ipvlan**: gleiche Kernel-Voraussetzungen wie bei Docker; bekannte Unraid-Falle
|
||
„macvlan call trap“ (Kernel-Panic bei bestimmten NIC-Treibern) muss dokumentiert und im
|
||
Preflight als Warnung ausgegeben werden, wenn macvlan-Netzwerke angelegt werden.
|
||
- **iptables/nftables-Koexistenz mit Docker**: netavark legt eigene Chains an
|
||
(`NETAVARK-*` Präfix); explizit verifizieren, dass diese nicht mit Dockers
|
||
`DOCKER`-Chains oder Unraids eigenen Firewall-Regeln interferieren. Firewall-Reload
|
||
durch Docker (bei dessen Start/Stop) darf Podman-Regeln nicht löschen und umgekehrt —
|
||
ggf. eigenes `iptables-restore`-Hook nach jedem `rc.podman start`.
|
||
- **DNS**: `aardvark-dns` für Container-zu-Container-Namensauflösung innerhalb
|
||
benutzerdefinierter Netzwerke, analog Dockers eingebettetem DNS-Server.
|
||
- **Port-Publishing**: Kollisionsprüfung mit bereits von Docker/anderen Diensten
|
||
belegten Ports als GUI-seitige Validierung (spätere Phase), technisch bereits
|
||
durch Kernel/`iptables` ohnehin erzwungen.
|
||
|
||
---
|
||
|
||
## 9. Volumes
|
||
|
||
- **Named Volumes**: liegen innerhalb von `podman.img` unter
|
||
`.../storage/volumes/`, damit sie vom selben Backup-/Rollback-Mechanismus wie Images
|
||
erfasst werden.
|
||
- **Bind-Mounts** auf Unraid-Shares (`/mnt/user/appdata/...`): empfohlener Standardweg
|
||
für Nutzerdaten (analog Dockers „Path“-Mappings in Community-Applications-Templates),
|
||
da `/mnt/user/appdata` bereits vom Nutzer im Backup-/Mover-/Cache-Konzept berücksichtigt
|
||
wird. Bind-Mounts direkt gegen `/mnt/user` (FUSE) sind für Applikationsdaten unkritisch
|
||
(kein Overlay-Storage-Anspruch), nur der Storage-Graph selbst braucht den echten Mount.
|
||
- **Permissions/UID-Mapping**: Phase 1 rootful → Container laufen mit denselben
|
||
UID/GID-Semantiken wie Docker rootful heute; keine zusätzliche User-Namespace-Remapping-
|
||
Komplexität. Wird in Phase 2 (rootless) relevant.
|
||
- **Migration-Hilfe (spätere Phase, nicht MVP)**: Werkzeug zum Referenzieren bestehender
|
||
Docker-Bind-Mount-Pfade beim Anlegen äquivalenter Podman-Container, um Parallelbetrieb
|
||
mit denselben Appdata-Verzeichnissen zu erleichtern (mit klarer Warnung vor
|
||
gleichzeitigem Schreibzugriff durch zwei Runtimes).
|
||
|
||
---
|
||
|
||
## 10. Images
|
||
|
||
- **Storage-Driver**: `overlay` (native, kein `fuse-overlayfs`) auf dem gemounteten
|
||
`podman.img` — Performance-Parität mit Dockers Standard-Setup.
|
||
- **Registries**: Default `registries.conf` mit Docker Hub + ggf. `ghcr.io`, `quay.io`
|
||
vorkonfiguriert, kurz-Namen-Auflösung (`unqualified-search-registries`) explizit
|
||
gesetzt statt interaktivem Prompt (der in einer daemonless/Skript-Umgebung nicht
|
||
funktioniert).
|
||
- **Pull/Push**: Standard-Podman-CLI-Semantik, keine Besonderheiten; Fortschrittsanzeige
|
||
später über API-Service-Events für die WebUI nutzbar.
|
||
- **Image-Größenmanagement**: `podman.img` ist eine feste/dynamisch wachsende
|
||
Loopback-Datei — GUI muss Füllstand anzeigen und Vergrößern anbieten (analog Dockers
|
||
„docker.img full“-Problem, das in der Community bekannt und schmerzhaft ist; hier von
|
||
Anfang an mit klarer Fehlermeldung statt stillem Fehlschlag lösen, siehe Abschnitt 16).
|
||
- **Community-Applications-Kompatibilität**: kein automatischer Import von
|
||
Docker-Templates in Phase 1 (eigenes, separates Vorhaben); Podman-Images werden
|
||
zunächst über CLI/eigene, minimale Template-Definition verwaltet.
|
||
- **Signatur-Policy** (`config/policy.json`): `insecureAcceptAnything` als Default —
|
||
akzeptiert Images ohne Signaturprüfung, entspricht Dockers heutigem
|
||
Standard-Vertrauensmodell auf Unraid. Vor einem 1.0-Release erneut bewerten, falls
|
||
signierte Images ein Ziel werden. Die Datei selbst darf keine Kommentarfelder
|
||
enthalten (`containers/image`s Policy-Parser lehnt unbekannte Top-Level-Keys wie
|
||
`_comment` strikt ab) — Begründung lebt deshalb hier, nicht in der Datei.
|
||
|
||
---
|
||
|
||
## 11. Container (Lifecycle-Management)
|
||
|
||
- Lifecycle-Operationen (`create`, `start`, `stop`, `restart`, `remove`, `exec`,
|
||
`logs`, `inspect`) laufen über den in Abschnitt 6.1 gestarteten Podman-API-Service,
|
||
nicht über Ad-hoc-CLI-Aufrufe aus der GUI heraus — ein gemeinsamer Service reduziert
|
||
Race Conditions und ermöglicht Event-Streaming.
|
||
- **Labels für GUI-Integration**: eigenes Label-Schema (z. B. `net.unraid.podman.icon`,
|
||
`net.unraid.podman.webui`), angelehnt an, aber getrennt von Dockers
|
||
`net.unraid.docker.*`-Konventionen, um spätere GUI-Icons/WebUI-Links analog zur
|
||
Docker-Tab-Darstellung zu ermöglichen, ohne Namensraum-Kollisionen.
|
||
- **Update-Strategie für Container-Images**: „Check for Updates“-Mechanismus
|
||
(Digest-Vergleich gegen Registry) als spätere GUI-Funktion, technisch schon in
|
||
Phase 1 per `podman image inspect`/`skopeo`-Vergleich vorbereitbar.
|
||
|
||
---
|
||
|
||
## 12. Autostart
|
||
|
||
Da kein systemd existiert, wird Autostart **explizit vom Plugin verwaltet**, nicht von
|
||
Podman selbst (Podman hat kein natives „restart on boot“ ohne generierte Unit-Files):
|
||
|
||
- Flache Datei `/boot/config/plugins/podman/autostart`, eine Zeile pro Container
|
||
(Name oder ID), Reihenfolge = Zeilen-Reihenfolge = Startreihenfolge — direktes
|
||
Äquivalent zu Dockers `/boot/config/plugins/dynamix.docker.manager/docker-autostart`
|
||
bzw. der DB-gestützten Nachfolgelösung.
|
||
- Optionale, separate Delay-Datei für Wartezeiten zwischen Starts (Abhängigkeiten
|
||
zwischen Containern, z. B. DB vor App).
|
||
- `rc.podman start` liest die Liste sequenziell, startet jeden Container über den
|
||
API-Service, protokolliert Erfolg/Fehler pro Eintrag, bricht bei Einzelfehlern
|
||
**nicht** die gesamte Kette ab (ein defekter Container darf nicht alle anderen
|
||
blockieren).
|
||
- GUI-Checkbox „Autostart“ pro Container (spätere Phase) schreibt direkt in diese
|
||
Datei zurück — kein separates DB-Layer in Phase 1, um Komplexität niedrig zu halten
|
||
(kann bei Bedarf später durch strukturierteres Format, z. B. JSON, ersetzt werden).
|
||
|
||
---
|
||
|
||
## 13. Updates
|
||
|
||
### 13.1 Plugin-Update (Podman-Version, Init-Skripte)
|
||
|
||
- Über den regulären Unraid-Plugin-Update-Mechanismus: `.plg` mit neuer Version +
|
||
neuen Paket-URLs/MD5s wird erneut ausgeführt.
|
||
- Vor jedem Update: automatisches Backup (siehe Abschnitt 14) der aktuellen
|
||
`.txz`-Pakete und Config-Dateien.
|
||
- **Container laufen während des Plugin-Updates weiter**, sofern nur Binaries
|
||
ausgetauscht werden (laufende `conmon`/Container-Prozesse sind vom
|
||
Dateisystem-Austausch unter `/usr/bin` isoliert, solange der Prozess nicht neu
|
||
exec't wird) — erst ein nachfolgender `rc.podman restart` übernimmt die neue
|
||
Podman-Version für den API-Service. Klar kommunizieren: Update ≠ sofortiger
|
||
Container-Neustart.
|
||
- Config-Migrationen (z. B. neues Feld in `containers.conf`) über ein
|
||
Versions-gestempeltes Migrationsskript, das beim Postinstall geprüft wird
|
||
(`podman.cfg` enthält `CONFIG_SCHEMA_VERSION`).
|
||
|
||
### 13.2 Container-Image-Updates
|
||
|
||
- Getrennt vom Plugin-Update zu betrachten — reine Podman-Funktionalität
|
||
(`podman pull` + Recreate), GUI-Komfortfunktion für Phase 2.
|
||
|
||
---
|
||
|
||
## 14. Rollback
|
||
|
||
- **Paket-Rollback**: Vor jedem Update werden die aktuell installierten `.txz` nach
|
||
`/boot/config/plugins/podman/backup/packages/<alte-version>/` kopiert. Ein
|
||
„Rollback“-Kommando (Postinstall-Skript, später GUI-Button) installiert diese
|
||
Pakete erneut per `upgradepkg --reinstall`.
|
||
- **Config-Rollback**: Vor jeder strukturellen Config-Änderung (Plugin-Update mit
|
||
Schema-Migration) wird ein Snapshot nach
|
||
`/boot/config/plugins/podman/backup/config/<timestamp>/` geschrieben; Rollback
|
||
kopiert diesen Snapshot zurück und setzt `CONFIG_SCHEMA_VERSION` entsprechend zurück.
|
||
- **Storage-Rollback (Images/Container) ist explizit außerhalb des automatischen
|
||
Rollbacks**: `podman.img` wird nicht bei jedem Plugin-Update gesichert (zu groß,
|
||
zu I/O-intensiv). Stattdessen: dokumentierte, manuell auslösbare Snapshot-Funktion
|
||
(z. B. `cp --reflink` auf BTRFS/ZFS-Cache-Pools, wo Reflinks verfügbar sind) als
|
||
optionales Feature, kein Zwang.
|
||
- Rollback-Historie begrenzen (z. B. letzte 3 Versionen), um den knappen
|
||
Flash-Speicher nicht zu erschöpfen.
|
||
|
||
---
|
||
|
||
## 15. Logging
|
||
|
||
- **Problem**: `/var/log` liegt im RAM und ist bei Reboot weg; `journald` existiert
|
||
nicht, daher kann Podmans `journald`-Log-Driver nicht Default sein.
|
||
- **Lösung**: Default-Log-Driver `k8s-file` (JSON-per-Zeile, Podman-nativ) mit
|
||
Zielverzeichnis unter `/mnt/cache/system/podman/logs/containers/`, per
|
||
Symlink von `/var/log/podman` dorthin erreichbar (einheitlicher Pfad für Tools,
|
||
die `/var/log` erwarten, ohne RAM-Verlust).
|
||
- **Log-Rotation**: eigener Cron-Eintrag (Unraid nutzt `cron` bereits für andere
|
||
Plugins über `/boot/config/plugins/dynamix/`-Muster bzw. `/etc/cron.d`) mit
|
||
`logrotate`-Konfiguration oder einfachem Größen-/Alter-basiertem Skript, da
|
||
Flash/Cache-Platz begrenzt ist.
|
||
- **Service-Log** (`podman system service`, `rc.podman`-Ausführung) getrennt von
|
||
Container-Logs, ebenfalls auf Cache-Pool, zusätzlich Kurzfassung wichtiger
|
||
Ereignisse (Start/Stop/Fehler) über `logger` in Unraids zentrales Syslog, damit
|
||
sie in der Standard-„System Log“-GUI sichtbar sind.
|
||
- **GUI-Zugriff (spätere Phase)**: Log-Viewer analog Dockers Container-Log-Fenster,
|
||
liest direkt aus den `k8s-file`-Logs bzw. streamt über den API-Service.
|
||
|
||
---
|
||
|
||
## 16. Fehlerbehandlung
|
||
|
||
### 16.1 Startup-Robustheit
|
||
|
||
- **Preflight-Checks** vor jedem `rc.podman start` (siehe 6.1): Storage-Mount,
|
||
Speicherplatz auf `podman.img`, Kernel-Voraussetzungen, Socket-Verfügbarkeit
|
||
(kein verwaister Socket von vorherigem Absturz).
|
||
- **Storage-Korruption**: Falls `podman.img` beim Mount-Versuch Dateisystemfehler
|
||
zeigt (`xfs_repair`/`btrfs check` schlägt fehl oder wird nicht automatisch
|
||
ausgeführt) → Start abbrechen, klare GUI-Fehlermeldung mit Handlungsempfehlung
|
||
(Recovery-Tool ausführen, Backup einspielen), **kein** automatisches
|
||
Neuanlegen/Formatieren ohne Nutzerbestätigung (Datenverlustrisiko).
|
||
- **Autostart-Fehler pro Container**: einzelner fehlgeschlagener Container wird
|
||
geloggt und übersprungen, blockiert nicht die restliche Kette (siehe Abschnitt 12);
|
||
nach N gescheiterten Autostart-Versuchen in Folge wird der Container automatisch
|
||
aus der Autostart-Kette pausiert („Safe-Mode“ pro Container) mit GUI-Hinweis,
|
||
um Boot-Loops/Ressourcenverschwendung zu vermeiden.
|
||
|
||
### 16.2 Laufzeitfehler
|
||
|
||
- **Health-Check des API-Service**: `rc.podman status` prüft Socket-Erreichbarkeit
|
||
und meldet Diskrepanzen (Prozess läuft, Socket tot o. ä.) verständlich.
|
||
- **Firewall-/Netzwerk-Konflikte**: bei bekannten Fehlerbildern (z. B. Chain-Konflikt
|
||
mit Docker, Port bereits belegt) definierte, für Menschen lesbare Fehlermeldungen
|
||
statt roher `iptables`/Go-Stacktraces — Fehlerkatalog mit Klartext-Ursache +
|
||
nächstem Schritt.
|
||
- **Ressourcenerschöpfung** (`podman.img` voll): aktive Prüfung im Preflight und
|
||
periodisch (Cron), GUI-Warnung bei > 85 % Füllstand, klare Anleitung zum
|
||
Vergrößern des Loopback-Images (bekannte Docker-für-Unraid-Schwachstelle, hier
|
||
von Anfang an proaktiv statt reaktiv lösen).
|
||
- **Unraid-Benachrichtigungssystem**: kritische Fehler (Storage-Mount fehlgeschlagen,
|
||
Autostart-Kette größtenteils fehlgeschlagen, `podman.img` > Schwellwert) werden
|
||
über Unraids Standard-Notify-Mechanismus (`/usr/local/emhttp/webGui/scripts/notify`)
|
||
ausgelöst, damit sie in GUI-Toasts, optional E-Mail/Pushover (falls vom Nutzer
|
||
konfiguriert) erscheinen — kein Parallel-Notify-System erfinden.
|
||
|
||
---
|
||
|
||
## 17. Docker-Parallelbetrieb & spätere Deaktivierung
|
||
|
||
### Phase 1 — Parallelbetrieb (Pflicht)
|
||
|
||
- Getrennte Storage-Roots (`docker.img` vs. `podman.img`), getrennte Default-Bridges,
|
||
getrennte iptables-Chain-Präfixe, getrennte Log-Verzeichnisse — keine gemeinsam
|
||
genutzten mutable Ressourcen außer read-only Kernel-Features (cgroups, netfilter).
|
||
- Ressourcen-Konkurrenz (CPU/RAM/Disk-IO) ist erwartet und wird nicht technisch
|
||
verhindert, aber in der GUI/Doku transparent gemacht.
|
||
- Beide Runtimes dürfen gleichzeitig laufen, ohne dass Start/Stop des einen den
|
||
anderen beeinflusst (insbesondere Firewall-Reloads, siehe Abschnitt 8).
|
||
|
||
### Phase 2+ — Docker optional deaktivierbar
|
||
|
||
- Neuer Schalter (z. B. in den bestehenden Docker-Settings oder einem neuen
|
||
„Container Engine“-Auswahlbereich): „Docker aktiviert / Podman aktiviert / beide“.
|
||
- Deaktivierung von Docker bedeutet: `rc.docker stop` + Entfernen des
|
||
Autostart-Hooks aus `/boot/config/go` für Docker, **kein** Deinstallieren des
|
||
Docker-Plugins selbst (reversibel, Datenerhalt).
|
||
- Voraussetzung für diese Phase: Podman-Pfad muss funktional äquivalent zu den von
|
||
Nutzern tatsächlich genutzten Docker-Features sein (mind. Custom Networks, Autostart,
|
||
Log-Viewer, Update-Check) — technisch als Gate, nicht nur als Empfehlung, im
|
||
Freigabeprozess verankern.
|
||
- CA-Kompatibilität (Community Applications erwartet aktuell Docker) ist der
|
||
wahrscheinlich größte Blocker für „Docker komplett aus“ und sollte als eigenes
|
||
Arbeitspaket (Template-Übersetzung Docker→Podman) vor Freigabe dieser Option
|
||
behandelt werden.
|
||
|
||
---
|
||
|
||
## 18. Zukünftige WebUI
|
||
|
||
### 18.1 Architektur (Zielbild, Umsetzung nach MVP)
|
||
|
||
- Eigene GUI-Seite unter `/usr/local/emhttp/plugins/podman/`, PHP + JS im
|
||
bestehenden Unraid-„Dynamix“-Stil (Konsistenz mit restlicher GUI, wiederverwendbare
|
||
CSS-/JS-Assets), analog zur Docker-Tab-Struktur (`dynamix.docker.manager`).
|
||
- Backend-Kommunikation **nicht** über Shell-Exec von `podman`-CLI-Aufrufen aus PHP
|
||
(fragil, schwer zu parallelisieren), sondern über den in Abschnitt 6.1 laufenden
|
||
Podman-API-Service (Unix-Socket, REST, Docker-kompatible Teilmenge der API) —
|
||
ermöglicht später auch Wiederverwendung bestehender Docker-API-kompatibler
|
||
Frontend-Bibliotheken.
|
||
- Echtzeit-Updates (Container-Status, Logs) über Server-Sent Events oder Polling
|
||
gegen den API-Service, kein WebSocket-Zwang in Phase 1 der WebUI (geringerer
|
||
Implementierungsaufwand, ausreichend für Status-Refresh im Sekundenbereich).
|
||
|
||
### 18.2 Funktionsumfang, gestaffelt
|
||
|
||
1. **Stufe 1**: Read-only Übersicht (laufende Container, Images, Netzwerke),
|
||
Start/Stop/Restart einzelner Container.
|
||
2. **Stufe 2**: Container-Erstellung über einfache Formulare (Image, Ports, Volumes,
|
||
Env, Labels), Autostart-Verwaltung direkt in GUI (schreibt in Abschnitt-12-Datei).
|
||
3. **Stufe 3**: Log-Viewer, Netzwerk-Verwaltung (Custom Networks/macvlan-Anlage),
|
||
Update-Check pro Container.
|
||
4. **Stufe 4**: Community-Applications-Anbindung/Template-Import (separates Vorhaben).
|
||
|
||
### 18.3 Sicherheitsaspekt der WebUI
|
||
|
||
- API-Service-Socket nur lokal (`/var/run/podman/podman.sock`), keine TCP-Exposition
|
||
nach außen ohne explizite, abgesicherte Opt-in-Konfiguration (TLS + Auth), da
|
||
rootful Podman-API faktisch Root-Äquivalent ist — gleiche Vorsicht wie beim
|
||
Docker-Socket.
|
||
|
||
---
|
||
|
||
## 19. Sicherheitsbetrachtungen (Phase 1, rootful)
|
||
|
||
- Rootful Podman-API-Socket ist funktional gleichwertig zu `docker.sock` bzgl.
|
||
Angriffsfläche (Zugriff = Root auf dem Host) — Berechtigungen auf den Socket
|
||
(`0660`, Gruppe analog `docker`-Gruppe, z. B. neue Gruppe `podman`) restriktiv setzen.
|
||
Achtung Docker Sock: root Äquivalenz, daher keine ungeprüfte Gruppenmitgliedschaft
|
||
für WebUI-Prozesse vergeben, die nicht ohnehin schon rootäquivalent laufen (`emhttpd`
|
||
läuft unter Unraid ohnehin als root, insofern kein zusätzliches Risiko gegenüber
|
||
Docker heute — aber explizit dokumentieren, nicht stillschweigend voraussetzen).
|
||
- Keine automatische, ungefragte Netzwerk-Exposition von Container-Ports über die
|
||
Standard-Bridge hinaus.
|
||
- Rollback-/Backup-Mechanismus darf keine Zugangsdaten (Registry-Logins in
|
||
`auth.json`) ungesichert auf dem FAT32-Flash ablegen, ohne dass sich der Nutzer
|
||
dessen bewusst ist (Flash ist physisch leicht auslesbar) — ggf. Hinweis, sensible
|
||
Registry-Credentials bevorzugt nicht dauerhaft dort zu speichern, oder Ablage
|
||
ausschließlich auf dem Cache-Pool statt `/boot`.
|
||
|
||
---
|
||
|
||
## 20. Phasenplan
|
||
|
||
| Phase | Inhalt |
|
||
|---|---|
|
||
| **MVP (Phase 1)** | Plugin-Grundgerüst, Pakete, `rc.podman`, Storage auf Cache-Pool, Autostart-Datei, Basis-Logging, Preflight/Fehlerbehandlung, Rollback für Pakete/Config, **keine WebUI** (CLI-only, `podman` direkt nutzbar) |
|
||
| **Phase 2** | WebUI Stufe 1–2, Custom-Networks-Verwaltung, Log-Viewer, Storage-Snapshot-Feature |
|
||
| **Phase 3** | Rootless-Option, Docker-Deaktivierungs-Schalter, CA-Template-Kompatibilitätsschicht |
|
||
| **Phase 4** | Pods/Quadlet-artige Konzepte (ohne systemd nur eingeschränkt sinnvoll — ggf. eigenes Skript-Äquivalent statt echter Quadlet/systemd-Generatoren) |
|
||
|
||
---
|
||
|
||
## 21. Offene Fragen / Risiken (zur Klärung vor Implementierungsstart)
|
||
|
||
1. Ziel-Podman-Version und Update-Kadenz (Tracking von Upstream-CVEs erfordert
|
||
Paket-Update-Prozess, nicht nur Erstrelease).
|
||
2. Cache-Pool-Pflicht vs. Array-Fallback für `podman.img` — Nutzer ohne Cache-Pool
|
||
sind bei Docker heute ebenfalls im Nachteil; gleiche Community-Erwartungshaltung
|
||
übernehmen oder verbessern?
|
||
2a. Verhalten bei mehreren Cache-Pools (Unraid 6.9+ unterstützt mehrere benannte
|
||
Pools) — welchen Pool per Default vorschlagen, wie in GUI wählbar machen.
|
||
3. `podman system service` als Dauerprozess vs. Socket-Activation-artiges
|
||
On-Demand-Start (ohne systemd nur eingeschränkt nachbaubar) — Dauerprozess ist
|
||
der pragmatischere Start, sollte aber gegen Ressourcenverbrauch im Idle
|
||
evaluiert werden.
|
||
4. Genaues Verhalten bei gleichzeitigem Boot von Docker und Podman bzgl.
|
||
iptables-Reihenfolge/Locking (`iptables`-Aufrufe sind nicht atomar über
|
||
mehrere Prozesse hinweg) — ggf. Locking-Strategie (`xtables_lock`) explizit prüfen.
|
||
5. Lizenz-/Signatur-Anforderungen für Community-Verbreitung des Plugins
|
||
(Unraid-Plugin-Repository-Richtlinien, Signierung der `.plg`/Pakete).
|