11 KiB
Betrieb und Wiederherstellung
Für die Installation aus der GitHub Container Registry (GHCR) siehe
Deployment-Anleitung. Alle docker compose-Befehle unten
werden im Deployment-Verzeichnis mit compose.yaml und .env ausgeführt.
PROVISIONER_IMAGE verweist auf das veröffentlichte Image, vorzugsweise per Digest.
Die CLI ist im Container enthalten; auf dem Zielserver ist keine eigene
Python-Installation erforderlich.
Konfiguration
proxmox-ais liest die optionale TOML-Datei aus APP_CONFIG, anschließend
gleichnamige großgeschriebene Umgebungsvariablen. Relative Pfade beziehen sich
auf das Arbeitsverzeichnis.
Die mitgelieferte Compose-Datei übernimmt PROVISIONER_IMAGE, PUBLIC_URL
und MAINTENANCE aus .env. Weitere Anwendungseinstellungen bei Bedarf unter
services.provisioner.environment in compose.yaml ergänzen.
| Einstellung | Standard | Bedeutung |
|---|---|---|
DATA_DIR |
./data |
SQLite, Artefakte und Dienstsperre auf lokalem Speicher |
MASTER_KEY_FILE |
./secrets/master.key |
Separat abgelegter Fernet-Schlüssel |
PUBLIC_URL |
https://localhost:8080 |
Extern erreichbare Basis-URL ohne Pfad |
SECURE_COOKIES |
true |
Sessioncookies nur über HTTPS |
FOUR_EYES |
true |
Autor darf eigene Versionen nicht veröffentlichen |
MAINTENANCE |
false |
Neue Installationsfreigaben aussetzen |
ANSWER_WINDOW_SECONDS |
300 |
Wiederholungsfenster des Antwortabrufs |
ENROLLMENT_HOURS |
4 |
Maximale Registrierungsfrist |
LEASE_SECONDS |
900 |
Gültigkeit der Runner-Ausführungsberechtigung |
RUNNER_CA_FILE |
nicht gesetzt | Vertrauensanker für Runner bei interner CA |
TESTING und Bootstrap-Passwörter nicht im Regelbetrieb setzen. Benutzer werden
interaktiv mit init und danach über die Administrationsoberfläche angelegt.
Das Datenverzeichnis darf den Master-Key nicht enthalten. Unter Windows schützt
zusätzlich eine auf das Dienstkonto beschränkte NTFS-ACL das Schlüsselverzeichnis.
TLS und Reverse-Proxy
Der Compose-Port ist nur an Loopback gebunden. Ein bestehender Proxy terminiert
TLS. Bei externem Proxy das private Container-/Verwaltungsnetz gezielt freigeben.
Der Dienst wertet Proxy-Header standardmäßig nicht aus; alle absoluten URLs
entstehen aus PUBLIC_URL. Bei einer nativen Installation kann der Dienst
TLS auch direkt terminieren:
proxmox-ais serve --host 0.0.0.0 --port 8080 \
--tls-cert /etc/proxmox-ais/fullchain.pem \
--tls-key /etc/proxmox-ais/server.key
Zertifikatskette und DNS müssen im Installer und auf installierten Hosts gültig
sein. Ein ISO-Fingerprint ersetzt nicht automatisch den CA-Vertrauensanker des
Runners. Bei interner CA RUNNER_CA_FILE konfigurieren und die gesamte Kette vom
Installer bis zum Runner prüfen. Keine TLS-Prüfung abschalten. Zertifikatsrotation
erfordert die Prüfung vorhandener Medien.
Capability-Tokens stehen zwangsläufig in Bootstrap-URLs. Der integrierte Server schreibt daher keine Access-Logs. Im vorgeschalteten Proxy Bootstrap- und Installer-Report-Pfade redigieren oder deren Access-Logging deaktivieren. Keine Authorization-Header protokollieren. Skriptausgaben werden zusätzlich redigiert; Skripte sollten Geheimnisse grundsätzlich nie ausgeben.
Betrieb
Der Dienst verwendet genau einen Anwendungsprozess. Mehrere Uvicorn-Worker oder gleichzeitige Dienste für dasselbe Datenverzeichnis verhindert die Dienstsperre. SQLite benötigt lokalen Speicher mit zuverlässigen Dateisperren; kein NFS/SMB-Volume einsetzen. Als Startwert sind 2 vCPU, 2 GB RAM und 20 GB Speicher ohne ISO-Archiv vorgesehen; Kapazität muss unter realer Last geprüft werden.
/health/live prüft den Prozess, /health/ready Datenbank und Konfiguration.
Readiness, freien Speicher, Backupalter und ausbleibende Runner-Meldungen überwachen.
DHCP, DNS, NTP und Paketquellen sind externe Voraussetzungen. Der Server baut keine
eingehenden SSH-Verbindungen zu Hosts auf.
Backup
Beim Registry-Deployment die Sicherung mit der aktuell eingesetzten Image-Version
erstellen, bevor PROVISIONER_IMAGE für ein Update geändert wird. Das
Hostverzeichnis /srv/ais-backups muss vorhanden und für UID/GID 10001
beschreibbar sein. Beispielsweise einmalig vom Administrator anlegen:
sudo install -d -o 10001 -g 10001 -m 0700 /srv/ais-backups
docker compose run --rm --no-deps --volume /srv/ais-backups:/backups \
provisioner backup /backups/2026-09-13
Für jede Sicherung einen neuen Zielnamen wählen. Bei einer nativen
Python-Installation lautet der entsprechende Befehl
proxmox-ais backup /srv/ais-backups/2026-09-13.
Das Ziel muss neu sein und außerhalb von DATA_DIR liegen. Die Anwendung kann
weiterlaufen: Die SQLite-Backup-API erzeugt einen konsistenten Snapshot, anschließend
werden unveränderliche Artefakte kopiert. Artefakte währenddessen nicht manuell
löschen. Die Sicherung enthält database.sqlite3, artifacts/, settings.json
und manifest.json. Der Master-Key wird ausgeschlossen; sein Fingerprint verhindert
die Wiederherstellung mit einem versehentlich falschen Schlüssel.
settings.json enthält die wirksamen Anwendungseinstellungen einschließlich
Standortvorgaben, Fristen und Freigaberegeln. Lokale Daten-/Schlüsselpfade und
Bootstrap-Zugangsdaten sind ausgeschlossen. Individuelle TOML-Datei,
Umgebungsvariablen, Proxykonfiguration, CA-/TLS-Dateien, ursprüngliche
ISOs und Prüfprotokolle separat sichern. Registrierte ISO-Metadaten liegen in der
Datenbank. Backup-Prüfsummen erkennen beschädigte Dateien; sie sind keine Signatur
gegen einen Angreifer mit Schreibzugriff. Backupverzeichnis deshalb schützen.
Den Master-Key aus proxmox-ais-keys über einen getrennten verschlüsselten
Sicherungsweg verwahren.
Eine lokale Kopie in ein bereits vorhandenes Zielverzeichnis ist möglich:
docker compose cp provisioner:/run/secrets/master.key /secure/offline/master.key
Die Schlüsselkopie ist genauso vertraulich wie alle gespeicherten Geheimnisse.
Restore
- Wartungsmodus aktivieren, neue Freigaben stoppen und Anwendungsdienst herunterfahren. Die Host-Runner separat berücksichtigen: ein bereits gestarteter Befehl kann noch laufen.
- Bisheriges Datenverzeichnis erhalten. Ein neues leeres Datenverzeichnis wählen und den zum Backup gehörenden Master-Key separat bereitstellen.
- Die gleiche Anwendungsversion wie beim Backup verwenden. Beim
Registry-Deployment deren Digest in
.envalsPROVISIONER_IMAGEsetzen und herunterladen. Das Schlüsselvolume muss bereits den passenden Master-Key alsmaster.key, lesbar für UID/GID 10001, enthalten. In ein neues, leeres Datenvolume wiederherstellen:
docker compose stop provisioner
docker compose pull provisioner
docker volume create proxmox-ais-data-restored
docker compose run --rm --no-deps \
--volume /srv/ais-backups:/backups:ro \
--volume proxmox-ais-data-restored:/var/lib/proxmox-ais \
provisioner restore /backups/2026-09-13
proxmox-ais-data-restored muss neu sein; existiert es schon, einen anderen
unbenutzten Namen wählen. Nach erfolgreichem Restore in compose.yaml unter
volumes.ais-data.name diesen neuen Namen eintragen. Das bisherige Datenvolume
bleibt erhalten. Bei einer nativen Python-Installation alternativ:
export DATA_DIR=/srv/proxmox-ais-restored
export MASTER_KEY_FILE=/secure/offline/master.key
proxmox-ais restore /srv/ais-backups/2026-09-13
- Individuelle Konfiguration und Zertifikate wiederherstellen. Im Wartungsmodus
starten, anmelden und Inventar sowie aktuelle Hostzustände abgleichen.
Beim Registry-Deployment dafür
MAINTENANCE=truein.envsetzen unddocker compose up -d --no-build --waitausführen. - Aktive Läufe stehen auf
needs_review. Alte Sessions, Gerätezugänge, Bootstrap-/Enrollment-/Report-Capabilities und Gruppentokens gelten nicht mehr; offene Installationsfreigaben sind gesperrt. Gruppentokens und davon abhängige Medien neu ausgeben. Zuvor ausgelieferte Installer nicht ungeprüft neu booten. - Installer und Runner auf jedem betroffenen Host lokal stoppen und den
tatsächlichen Zustand prüfen. Danach den verlassenen Lauf über
POST /api/v1/runs/{id}/reconcileabschließen: aktuelleexpected_version, aussagekräftigereason,confirmationmit dem Host-FQDN undexecution_stopped: trueübermitteln. Die Aktion beendet den Lauf alscancelled, sperrt seine Berechtigungen und schreibt einen Auditeintrag. Erst danach ist eine neue ausdrückliche Installationsfreigabe möglich. Der automatische Wiederanschluss alter Geräteidentitäten nach Restore ist nicht Teil dieser Version.
Außerhalb eines Restore zuerst /cancel anfordern. Ein offline befindlicher
Runner kann seine bereits erhaltene Lease bis zum Ablauf behalten; eine
Abbruchanforderung zieht diese nicht zurück. /reconcile weist den Abgleich
deshalb zurück, solange eine zuvor ausgestellte Lease oder das
Antwortauslieferungsfenster noch gültig ist. Auch nach deren Ablauf ist die
ausdrückliche Bestätigung erforderlich, dass Installer und Runner lokal gestoppt
und kontrolliert wurden. Eine nicht mehr erreichbare Maschine ist kein Nachweis
dafür. Das Verfahren erteilt selbst keine Neuinstallationsfreigabe.
Restore überschreibt keine bestehende Datenbank. Die Dienstsperre verhindert
Restore während eines laufenden Dienstes im Zielverzeichnis. Ein fehlgeschlagener
Restore hinterlässt RESTORE_FAILED; der CLI-Start verweigert dann den Betrieb.
Nach Ursachenklärung erneut in ein neues leeres Ziel restaurieren.
Bereits heruntergeladene Antwortdateien kann der Server nicht zurückziehen. Ebenso beendet eine Credential-Sperrung einen lokal laufenden Skriptprozess nicht unmittelbar. Restore erfordert deshalb den physischen Zustandsabgleich der Hosts.
RPO 24 Stunden und RTO zwei Stunden sind Ziele aus dem Konzept. Erst wiederholte Sicherung und zeitlich gemessene Wiederherstellung unter realen Bedingungen weisen diese Ziele nach.
Updates
Der vollständige Ablauf für Registry-Images steht unter
Deployment aktualisieren.
Vor dem ersten Neustart PROVISIONER_IMAGE auf den Digest des tatsächlich
laufenden Images festlegen, wie dort beschrieben. Anschließend
MAINTENANCE=true in .env setzen und die laufende Version mit
docker compose up -d --no-build --wait neu erstellen. Der Wartungsmodus
sperrt neue Freigaben; bereits gestartete Installations- und Modulabläufe werden
dadurch nicht beendet. Diese vor dem Update kontrolliert abschließen lassen.
Mit der bisherigen Version Daten und Schlüssel sichern und den alten
Image-Digest festhalten. Erst danach PROVISIONER_IMAGE ändern, das neue Image
mit docker compose pull provisioner laden, den Dienst mit
docker compose stop provisioner stoppen und mit
docker compose up -d --no-build --wait neu starten. Nach Prüfung von Anmeldung,
Inventar und Readiness MAINTENANCE=false setzen und erneut up ausführen.
Bei Updates wird init nicht wiederholt.
Die Datenbank
führt eine Migrationstabelle und PRAGMA user_version. Neuere unbekannte Schemas
werden abgewiesen. Downgrades erfolgen über die zur Sicherung passende Version
und den beschriebenen Restore; keine alte Anwendung auf eine bereits migrierte
Produktivdatenbank starten.