Authorization Code mit PKCE, State und Nonce über openid-client 6.8.8; die Rolle kommt bei jeder Anmeldung aus dem Gruppen-Claim. Lokale Konten werden nie über den Namen übernommen, verknüpfen geht nur angemeldet. Getestet gegen einen Mock-IdP inklusive gefälschtem State, falscher Nonce und fremder Audience. Closes #016 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ProxDeploy
VMs und LXC-Container auf Proxmox VE ausrollen, per Web oder CLI.
ProxDeploy ist eine selbst gehostete Webanwendung mit einer CLI (proxdeploy). Damit wählt man einen von
mehreren Proxmox-VE-Servern (8.x/9.x, Einzelhost oder Cluster) und rollt darauf vollständig unattended
eine VM oder einen LXC-Container mit Debian oder Ubuntu aus, inklusive Profilen wie base, docker
oder zabbix-agent. Weitere Distributionen und Profile sind YAML-Dateien im Katalog, kein Code.
ProxDeploy ist ein unabhängiges Werkzeug und stammt nicht von Proxmox Server Solutions GmbH. „Proxmox“ ist eine Marke der Proxmox Server Solutions GmbH.
Stand
In Entwicklung. Version und Fortschritt stehen im CHANGELOG, der Plan in docs/architektur.md, die Aufgaben in docs/issues/.
| Etappe | Inhalt | Stand |
|---|---|---|
| 1 · v0.1.0 | Server-Verwaltung, Fingerprint-Pinning, Verbindungstest mit Fähigkeitserkennung | ✓ fertig, auf PVE 9.2 geprüft |
| 2 · v0.2.0 | Katalog, Template-Bau, Debian-13-VM, Live-Fortschritt, Assistent | ✓ fertig, auf PVE 9.2 geprüft |
| 3 · v0.3.0 | LXC, Ubuntu, Profile, Vorlagen, Profile im Template, SSH-Schlüssel | ✓ fertig, auf PVE 9.2 geprüft (Bau-Adresse #021: Abnahme offen) |
| 4 · v0.4.0 | CLI proxdeploy (Go), API-Tokens |
✓ fertig, auf PVE 9.2 geprüft |
| 5 · v0.5.0 | Verlauf, Audit-Log, Rollen, OIDC | ◐ als Nächstes |
| 6 · v0.6.0 | Branding, README mit Screenshots, Installer | ○ geplant |
Was ProxDeploy auf einem Server kann
Der Verbindungstest prüft jeden Server und zeigt, welcher Vorgang per API, per SSH oder gar nicht geht. Maßgeblich ist die Proxmox-API (geprüft gegen PVE 8.x und 9.2):
- Template bauen: per API ab PVE 8.4 (
download-url+import-from), davor per SSH - VM provisionieren: über den Guest-Agent, ohne SSH
- LXC provisionieren: braucht SSH (Proxmox hat keine Exec-API für Container)
- cloud-init-Snippets: nur per SSH (keine API)
Das API-Token braucht eine eigene Rolle; die Befehle stehen in docs/proxmox-rechte.md.
CLI
proxdeploy ist ein einzelnes Binary (Linux, macOS, Windows; amd64 und arm64) und spricht nur die
REST-API – dieselbe wie die Web-GUI, mit denselben Phasentexten.
proxdeploy login https://proxdeploy.example # fragt Benutzer und Passwort, speichert ein Token
proxdeploy servers
proxdeploy distros --type lxc
proxdeploy profiles
proxdeploy vm web01 --server rz1 --distro debian-13 --profile base,docker --ip 10.0.20.15/24 --gw 10.0.20.1 --vlan 20
proxdeploy lxc dns01 --server rz1 --distro ubuntu-24.04 --dry-run
proxdeploy template build --server rz1 --distro debian-13 --profile base,docker
proxdeploy batch gaeste.yaml
proxdeploy status a-7f3k
proxdeploy logs a-7f3k --follow
proxdeploy history --type lxc --status fehlgeschlagen
proxdeploy cleanup a-7f3k # halb angelegten Gast nach Fehlschlag löschen (mit Rückfrage)
⬡ ProxDeploy v0.4 · Server rz1 · Node pve01 · Debian 13 (Template 9013)
✓ Prüfungen VMID 120 frei · local-zfs · vmbr0 VLAN 20
✓ Klonen full clone 9013 → 120 · Disk auf 40G
✓ cloud-init user florian · SSH-Key · Profile base, docker
✓ Start VM 120 läuft
✓ Guest-Agent antwortet nach 18s
◐ Provisionierung cloud-init läuft … 1m 12s
- Was nicht angegeben ist, füllt der Server: Storage, Bridge und Node aus den Server-Einstellungen
bzw. dem Verbindungstest, Benutzer = eigener Benutzername, SSH-Schlüssel = die in den Einstellungen
hinterlegten.
--presetbelegt aus einer Vorlage vor; Flags gehen vor. - Konfiguration in
~/.config/proxdeploy/config.toml(Rechte 0600):url,token, optionalserverals Standard für--serverund[instances.<name>]für weitere Instanzen (--instance).PROXDEPLOY_URL,PROXDEPLOY_TOKEN,PROXDEPLOY_INSTANCEgehen vor. - Tokens für Skripte und CI: Web-GUI → Einstellungen → API-Tokens, dann
proxdeploy login <url> --token pd_…. - Ausgabe: Farben (24-bit, sonst 256) nur im Terminal und ohne
NO_COLOR/--no-color;--asciiersetzt Symbole durch[OK],[..],[!!];--quietzeigt nur die Abschlussbox;--jsonist maschinenlesbar. Ohne Terminal (Pipe, CI) erscheint jede Phase als eine Zeile, sobald sie fertig ist. - Exit-Codes:
0Erfolg,1Auftrag fehlgeschlagen,2Bedienfehler,3Verbindung/Anmeldung. Strg+Chängt nur ab – der Auftrag läuft weiter (proxdeploy status <id>); abbrechen mitproxdeploy cancel <id>.
batch rollt mehrere Gäste aus; die Schlüssel heißen wie die Flags. Die Datei wird vollständig
geprüft, bevor der erste Auftrag startet:
defaults:
server: rz1
distro: debian-13
profile: [base]
guests:
- name: web01
type: vm
profile: [base, docker]
ip: 10.0.20.15/24
gw: 10.0.20.1
memory: 4096
- name: mon01
type: lxc
profile: [base, zabbix-agent]
vars: { zabbix-agent: { server: zbx.example } }
Bauen: cli/bauen.sh 0.4.0 legt die sechs Binaries und SHA256SUMS unter cli/bin/ ab (Go 1.27).
Anmeldung per OIDC (z. B. authentik)
Optional zusätzlich zu lokalen Konten. Beim Identity Provider einen vertraulichen Client anlegen,
Redirect-URI <APP_URL>/api/v1/auth/oidc/rueckruf, Scopes openid profile email, den
Gruppen-Claim ins ID-Token geben. Dann in der .env:
OIDC_AKTIV=true
OIDC_ISSUER=https://auth.example/application/o/proxdeploy/
OIDC_CLIENT_ID=…
OIDC_CLIENT_SECRET=…
OIDC_ANZEIGENAME=authentik
OIDC_GRUPPEN_CLAIM=groups
OIDC_GRUPPE_ADMIN=proxdeploy-admins
OIDC_GRUPPE_OPERATOR=proxdeploy-operators
- Ablauf: Authorization Code mit PKCE, State und Nonce; das ID-Token wird gegen die Schlüssel des IdP geprüft.
- Die Rolle kommt bei jeder Anmeldung aus den Gruppen; wer in keiner der beiden Gruppen ist, kommt nicht hinein.
- Neue SSO-Benutzer werden beim ersten Anmelden angelegt. Ein vorhandenes lokales Konto wird nie über den Namen übernommen; verknüpfen geht angemeldet unter Einstellungen → „Mit … verknüpfen“.
- Gesperrte Konten bleiben gesperrt, auch per SSO. Getestet gegen einen Mock-IdP (
tests/oidc.test.ts); ein echter IdP folgt beim Feldtest.
Entwicklung
Voraussetzungen: Node 24 (z. B. über nvm), pnpm 12 (corepack), Docker für PostgreSQL.
pnpm install
cp .env.example .env # Schlüssel erzeugen: openssl rand -base64 32 / 48, ADMIN_PASSWORT setzen
pnpm db:up # PostgreSQL 17 auf 127.0.0.1:5437 (inkl. Testdatenbank)
pnpm db:migrate
pnpm build && PORT=3310 APP_URL=http://127.0.0.1:3310 pnpm start
Prüfen vor jedem Commit:
pnpm lint && pnpm typecheck && pnpm format:pruefen && pnpm test
pnpm test:e2e # Browser-Abläufe gegen den gebauten Stand (Desktop und 390 px)
pnpm cli:pruefen # openapi.json und Go-Typen aktuell, go vet, go test (Golden-Files)
Ändert sich ein Schema der API, erst pnpm openapi, dann in cli/ go generate ./... – der
Go-Client nutzt die aus cli/api/openapi.json erzeugten Typen.
Konventionen (deutsche Bezeichner, Schichtung, Versionen) stehen in CLAUDE.md.
Betrieb
Docker Compose (app, worker, postgres) und ein Installer für einen Debian-LXC auf Proxmox folgen mit
Etappe 6. ProxDeploy ist für den Betrieb hinter einem Reverse-Proxy mit TLS gedacht
(TRUST_PROXY=true, APP_URL auf die öffentliche Adresse).
Lizenz
Noch nicht festgelegt.