# provisioning-server Maschinen-zu-Maschine-API für Geräteaktivierung, Agent-Check-in/Report und den Self-Service-ISO-Bau (anode) — von `kundenplattform` bewusst getrennter Dienst, siehe [ADR-0011](https://git.tuxflotte.de/admin/platform-docs/raw/branch/main/adr/0011-kundenplattform-getrennter-dienst.md). ## Architektur - FastAPI, reine Maschinen-Endpoints (kein Frontend) - Aktivierung, Agent-Bootstrap/Checkin/Report, Auftragskatalog, Self-Service-ISO-Bau. - Eigene Postgres-Datenbank (`tuxflotte`), getrennt von kundenplattforms Datenbank - Migrationen unter `migrations/`. - Läuft unter einem eigenen, unprivilegierten System-User `provisioning-server` (nicht root - siehe `provisioning-server.service` und [ADR-0027](https://git.tuxflotte.de/admin/platform-docs/raw/branch/main/adr/0027-provisioning-server-de-root-per-scoped-sudo.md)). Seit 03.10.2026 braucht auch der Self-Service-ISO-Bau (`run_iso_build()` in `app.py`) kein root mehr: `build_customer_iso.sh` legt die Kundendaten als eigene Squashfs-Schicht auf das Boot-Medium. Die frühere sudo-Regel (ADR-0027) ist entfallen, die Unit hat die volle Härtung. ## Setup (lokal) ``` python3 -m venv .venv .venv/bin/pip install -r requirements.txt TUXFLOTTE_DATABASE_URL=postgresql://... .venv/bin/psql ... -f migrations/0001_*.sql # + alle weiteren migrations/ der Reihe nach ``` Wichtige Env-Variablen (`/etc/tuxflotte/provisioning-server.env` im Betrieb): - `TUXFLOTTE_DATABASE_URL` - `TUXFLOTTE_ADMIN_TOKEN` - `TUXFLOTTE_KUNDENPLATTFORM_TOKEN` - muss mit dem gleichnamigen Wert in kundenplattforms Env übereinstimmen - `TUXFLOTTE_ANSIBLE_CONTENT_REPO` - URL des `ansible-content`-Repos - `TUXFLOTTE_INSTALLER_DIR` (Default `/root/tuxflotte-installer` - im produktiven De-Root-Setup stattdessen explizit auf einen für den `provisioning-server`-User lesbaren Pfad setzen, z.B. `/opt/tuxflotte-installer`) - `TUXFLOTTE_BOOT_MEDIUM_PATH` (früher `TUXFLOTTE_MINT_ISO_PATH`), `TUXFLOTTE_ISO_BUILD_OUTPUT_DIR` - relativ zum Arbeitsverzeichnis des Dienstes (`data/upstream/...`, `data/iso-builds`) Start: `.venv/bin/uvicorn app:app --port 8080` ## Deploy (anode) Über die Betriebs-Wrapper aus `infra/anode-ops` (ADR-0036), nicht von Hand: ``` ssh claude-ops@anode sudo tuxflotte-deploy provisioning-server ssh claude-ops@anode sudo tuxflotte-migrate provisioning-server ``` Erfolgreiche Deploys und Migrationen tragen die Wrapper in `plattform_ereignisse` ein (Migration 0071); neue Ansible-Stände vorab und stabil trägt der Spiegel-Thread des Servers selbst ein. Das Admin-Dashboard zeigt sie unter „Änderungen an der Plattform“. Port `8080` (kundenplattform belegt `8081`). Bei einer Neuinstallation zusätzlich zum Code-Deploy nötig (einmalig, nicht Teil von `git pull`): 1. System-User `provisioning-server` anlegen, `/opt/provisioning-server` diesem User gehörend. 2. `provisioning-server.service` nach `/etc/systemd/system/` kopieren, `systemctl daemon-reload && systemctl enable --now provisioning-server`. 3. `tuxflotte-installer`-Repo an den Pfad aus `TUXFLOTTE_INSTALLER_DIR` klonen (für den Dienstbenutzer lesbar). 4. Arbeitsverzeichnis für den ISO-Bau `/srv/tuxflotte/build-tmp` dem Dienstbenutzer übereignen (ohne dieses Verzeichnis `/var/tmp`). **Öffentliche Erreichbarkeit über Pangolin ist nicht Teil dieses Repos** — das ist ein separater Ops/DNS/Reverse-Proxy-Schritt.