Betrieb und Aktualisierung
Zielgruppe: Technische Administration
Überblick
Für den täglichen Betrieb brauchst du zwei Skripte im Projektverzeichnis: start.sh und stop.sh. Dieses Kapitel beschreibt außerdem, wo du Logs und Zustand der Dienste findest, wie du oPBWeb aktualisierst und was du auf der opsi-Seite beachten musst. Alle Befehle führst du im Projektverzeichnis aus.
Stack starten und stoppen
start.sh
./start.sh [--build] [--logs] [--dev | --test] [--lang de|en]
| Option | Wirkung |
|---|---|
| (keine) | startet den Produktiv-Stack (docker-compose.yml) mit den vorhandenen Images |
--build | baut die eigenen Images vor dem Start neu |
--logs | folgt nach dem Start den Logs aller Container (logs -f --tail=50); Strg+C beendet nur die Anzeige |
--dev | nimmt docker-compose.dev.yml hinzu (Entwicklungs-Stack, siehe unten); nur im Klon mit Quellen |
--test | nimmt docker-compose.test.yml hinzu: zwei opsi-Mocks als Configserver Test und Produktion, siehe Testumgebung |
--lang de bzw. --lang en | Sprache der Ausgaben für diesen Aufruf (sonst OPBWEB_LANG aus der .env) |
-h, --help | zeigt die Hilfe |
Ablauf: Das Skript bricht ab, wenn .env fehlt („.env fehlt – bitte ./setup-opbweb.sh ausführen (im Entwickler-Checkout: ./setup-opbweb.sh –dev).“), ruft scripts/init-secrets.sh auf, führt docker compose up -d aus und zeigt mit docker compose ps den Status. Laufende Container, deren Konfiguration sich nicht geändert hat, bleiben dabei unberührt. start.sh holt keine neuen Fremd-Images; dafür siehe Aktualisieren
.
stop.sh
./stop.sh
Das Skript hat keine Optionen. Es führt docker compose down mit docker-compose.yml und den vorhandenen Overlays (docker-compose.dev.yml, docker-compose.test.yml) aus und stoppt damit Produktiv-, Dev- und Testdienste gleichermaßen. Container und Netze werden entfernt, die Volumes mit Datenbank und Objektspeicher bleiben erhalten.
Einzelne Dienste neu starten
docker restart opbweb-worker
docker restart opbweb-frontend # z. B. nach einem Zertifikatswechsel
Ein Neustart des Workers unterbricht laufende Jobs. Prüfe vorher unter Jobs, ob gerade Installationen laufen.
Container
| Container | Dienst | Hinweis |
|---|---|---|
opbweb-frontend | nginx | Weboberfläche, Handbuch, Proxy |
opbweb-api | API | führt beim Start die Migrationen aus |
opbweb-worker | Worker | Jobs, Cron, opsi-Verbindung |
opbweb-db | MariaDB | |
opbweb-redis | Redis | |
opbweb-garage | Garage | Objektspeicher |
opbweb-garage-init | Einrichtung Garage | läuft bei jedem Start kurz und endet mit Exit-Code 0 |
opbweb-opsi-mock | nur Dev | nachgebauter opsiconfd (erstes opsi-System) |
opbweb-opsi-mock2 | nur Dev | nachgebauter opsiconfd (zweites opsi-System) |
opbweb-frontend-dev | nur Dev | Vite-Dev-Server |
opbweb-manual-dev | nur Dev | Hugo-Vorschau des Handbuchs |
opbweb-launcher-build | nur Dev | baut die Launcher-ZIPs beim Start und endet mit Exit-Code 0 |
opbweb-launcher-dev | nur Dev | liefert die Launcher-ZIPs aus |
Den Zustand zeigt docker compose ps (Produktiv-Stack) bzw. docker compose ps -a einschließlich beendeter Container wie garage-init.
Logs
docker logs -f --tail=100 opbweb-api
docker logs -f --tail=100 opbweb-worker
docker compose logs -f --tail=50 # alle Dienste
| Container | Was du dort findest |
|---|---|
opbweb-api | Migrationen und Start von uvicorn, Anlegen des ersten Admins, HTTP-Zugriffe (eine Zeile je Anfrage), Probleme bei der LDAP-Anmeldung |
opbweb-worker | Job-Ausführung, opsi-Prüfung (Standard alle 5 Minuten), Fehler bei Verbindungen zu opsiconfd |
opbweb-frontend | Wahl von HTTP oder HTTPS, Zugriffe und nginx-Fehler |
opbweb-garage-init | Einrichtung von Layout, Schlüssel und Bucket |
Den Detailgrad von api und worker steuert LOG_LEVEL in der .env (DEBUG, INFO, WARNING, ERROR; Standard INFO). Eine Änderung wird mit dem nächsten ./start.sh wirksam.
Bei der LDAP-Anmeldung protokolliert die API, woran eine Anmeldung scheitert: Benutzer nicht gefunden (null Treffer für den Suchfilter) und falsches Passwort auf Stufe INFO, keine Gruppe mit einer Rolle auf Stufe WARNING. Mit LOG_LEVEL=WARNING oder ERROR siehst du die ersten beiden Fälle also nicht. Zum Beispiel:
docker logs opbweb-api 2>&1 | grep "LDAP login"
python-opsi und der HTTP-Client httpx geben nur Warnungen und Fehler aus. Ihre Debug-Ausgaben schaltet erst DEBUG=true ein; das startet die API aber auch mit Hot Reload und ist nur für die Entwicklung gedacht, siehe Konfiguration
.
Das vollständige Protokoll jedes Jobs findest du zusätzlich in der Oberfläche unter Jobs, siehe Jobs .
Zustand prüfen
| Endpunkt | Anmeldung | Antwort |
|---|---|---|
/health | nein | statisch healthy von nginx; prüft nur, ob nginx antwortet |
/api/health | nein | {"status":"ok","version":"…"}; die API ist über nginx erreichbar |
/api/health/details | ja (Bearer-Token) | Prüfungen database, redis, storage, worker, opsi mit ok, Details und Dauer |
/api/system/database | ja, Admin | Zeilen und Größe je Datenbanktabelle |
/api/system/storage | ja, Admin | Belegung des Objektspeichers je Bereich, Deduplizierung, nicht verwendete und fehlende Blobs |
/api/system/storage/objects | ja, Admin | Objekte eines Bereichs mit den Paketversionen, die sie verwenden (Grundlage des Bucket-Browsers) |
| Seite Systemstatus | ja, alle Rollen | dieselben Prüfungen als Tabelle, alle 10 Sekunden aktualisiert |
Für ein einfaches Monitoring eignet sich /api/health:
curl -fsS https://opbweb.example.local/api/health
Die Detailprüfung bewertet so:
| Prüfung | Fehler, wenn … |
|---|---|
| Datenbank | keine Verbindung; die Details nennen sonst MariaDB-Version und Schema-Revision |
| Redis | keine Verbindung |
| Objektspeicher | keine Verbindung oder Bucket fehlt („Bucket ‘…’ fehlt“) |
| Worker | kein Heartbeat („kein Lebenszeichen“) oder letzter Heartbeat älter als 90 Sekunden |
| opsi-Server | noch nicht geprüft, kein Configserver eingerichtet oder bei mindestens einem Configserver: Verbindung fehlgeschlagen, keine Admin-Rechte, neues CA-Zertifikat noch nicht übernommen oder Warnung vor dem Ablauf |
Administratoren sehen im Systemstatus zusätzlich Tabellengrößen der Datenbank, die Belegung des Objektspeichers und den Bucket-Browser, siehe Systemstatus .
Zeitgesteuerte Aufgaben
Der Worker führt diese Aufgaben selbst aus; einen Cron-Eintrag auf dem Host brauchst du nicht.
| Aufgabe | Zeitpunkt | Wirkung |
|---|---|---|
| Heartbeat | alle 30 Sekunden | Lebenszeichen für den Systemstatus |
| opsi-Prüfung | alle 5 Minuten (Standard) | Verbindung, Depot-Abgleich, CA-Vergleich, Ablaufwarnung 60 Tage vorher |
| Aufräumen temporärer Dateien | täglich 03:17 Uhr (Standard) | löscht uploads/ und downloads/ älter als 24 Stunden |
Die Zeiten der opsi-Prüfung und des Aufräumens stellst du unter Einstellungen → Worker ein; sie gelten ohne Neustart.
Nicht mehr verwendete Paketdateien (Blobs) und Build-Ergebnisse entfernt die automatische Aufgabe nicht. Das macht ein Administrator bei Bedarf mit Bereinigen … im Systemstatus : erst ein Probelauf, dann das bestätigte Löschen.
Aktualisieren
Sichere Datenbank und Objektspeicher, siehe Sicherung und Wiederherstellung . Datenbankmigrationen lassen sich nicht ohne Weiteres rückgängig machen.
Prüfe unter Jobs, dass keine Installationen laufen.
Hole den neuen Stand, zum Beispiel mit
git pulloder mit einem neuen Stack-ZIP , das du über die Installation entpackst..env,secrets/undcerts/enthält das ZIP nicht, sie bleiben erhalten.Bringe die
.envauf den neuen Stand:./setup-opbweb.sh --updateonlyDas Skript übernimmt alle vorhandenen Werte, ergänzt neue Variablen mit ihrem Standardwert und legt neue Secrets an; vorhandene Secrets bleiben unverändert. Willst du dabei Werte ändern, rufe
./setup-opbweb.shohne Option auf.Aktualisiere die Images und starte den Stack:
Lokal gebaute Images:
./start.sh --build--buildnutzt den Build-Cache von Docker. Sicherheitsupdates der Basis-Images und der Systempakete kommen so nicht unbedingt an. Bau deshalb bei einem Sicherheitsupdate ohne Cache und mit frischen Basis-Images, danach./start.sh:docker compose build --pull --no-cacheImages aus einer Registry: Trage die neuen Image-Versionen ein, entweder interaktiv mit
./setup-opbweb.sh(Fragen nach den Versionen der Images; die Vorgabe ist die bisherige Version) oder direkt inBACKEND_IMAGE,FRONTEND_IMAGEundGARAGE_INIT_IMAGEin der.env.--updateonlybehält die bisherigen Versionen. Liegt eineversions.envdaneben (Stack-ZIP), sind ihre Versionen die Vorgaben, auch für--updateonly; das Entpacken eines neuen ZIPs und--updateonlystellen die Images also auf dessen Versionen um. Danach:docker compose pull ./start.shVerwendest du die Tags
latest, genügendocker compose pullund./start.sh.
Die API führt beim Start automatisch
alembic upgrade headaus. Prüfe danach das Log:docker logs opbweb-api 2>&1 | head -50Kontrolliere in der Oberfläche die Versionen in der Statusleiste („Frontend …“, „Backend …“) und den Systemstatus.
Neue Versionen der Fremd-Images (MariaDB 11.4, Redis 7, Garage v2.2.0) innerhalb ihrer Tags holt start.sh nicht automatisch. Beispiel, bei Bedarf auszuführen:
docker compose pull db redis garage
./start.sh
Um auch die Basis-Images der eigenen Images (node, nginx, python) zu aktualisieren, baue mit docker compose build --pull und starte danach mit ./start.sh. Das betrifft nur lokal gebaute Images.
Versionierung
Backend und Frontend haben getrennte Versionsnummern nach dem Schema MAJOR.MINOR.PATCH (Meilenstein, Phase, Fehlerbehebung). Die Oberfläche zeigt beide in der Statusleiste, /api/health liefert die Backend-Version.
Gesetzt werden die Versionen mit set-version.sh; welche Dateien betroffen sind, steht in version.yaml (Backend: backend/src/core/version.py und backend/pyproject.toml, Frontend: frontend/package.json über npm version).
| Aufruf | Wirkung |
|---|---|
./set-version.sh | zeigt die aktuellen Versionen |
./set-version.sh 0.14.0 | setzt alle Komponenten (mit Rückfrage; --force ohne) |
./set-version.sh --backend 0.13.1 | setzt nur das Backend |
./set-version.sh --frontend 0.13.1 | setzt nur das Frontend |
./set-version.sh --component <name> <version> | setzt eine Komponente aus version.yaml |
./set-version.sh --config <datei> | verwendet eine andere Konfigurationsdatei |
Eine geänderte Versionsdatei auf dem Standard-Branch löst in der GitLab-CI den Build des passenden Images aus, siehe Build und Auslieferung .
opsiconfd: admin-networks
Der Worker ruft opsiconfd mit Admin-Rechten auf. Ist in der Konfiguration von opsiconfd die Option admin-networks gesetzt, muss die Absenderadresse des Workers darin liegen, sonst antwortet opsiconfd mit HTTP 403.
Welche Adresse opsiconfd sieht, hängt vom Standort ab (abgeleitet aus dem Docker-Netzverhalten, bitte im opsiconfd-Log gegenprüfen):
oPBWeb auf dem Configserver selbst: die Adresse des Workers im Docker-Netz
opbweb_opsi-net. Das Subnetz zeigt:docker network inspect opbweb_opsi-net --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'oPBWeb auf einem anderen Host: in der Regel die Adresse des Docker-Hosts, weil Docker ausgehenden Verkehr maskiert.
./stop.sh entfernt die Docker-Netze; beim nächsten Start kann opbweb_opsi-net ein anderes Subnetz bekommen. Trage daher entweder den gesamten Adressbereich ein, aus dem Docker seine Netze vergibt, oder prüfe das Subnetz nach jedem Neustart. Die Syntax der Option beschreibt das opsi-Handbuch; nach der Änderung muss opsiconfd neu starten.
Entwicklungs-Stack
Der Entwicklungs-Stack ist für die Weiterentwicklung gedacht, nicht für den Betrieb. In einem frischen Entwickler-Checkout legst du zuerst die .env an (aus .env.example, ohne Rückfragen) und startest dann mit lokal gebauten Images:
./setup-opbweb.sh --dev
./start.sh --dev --build
Er ergänzt den Produktiv-Stack um Hot Reload (Quellen als Bind-Mounts, DEBUG=true), zwei nachgebaute opsiconfd, eine Vorschau des Handbuchs und die Launcher-ZIPs. API und Worker laufen mit dem Image opbweb-backend:dev.
| Was | Adresse |
|---|---|
| Vite-Dev-Server (Oberfläche mit Hot Reload) | http://localhost:3100 |
Handbuch-Vorschau (manual-dev, über den Vite-Proxy) | http://localhost:3100/manual/ |
Launcher-ZIPs (launcher-dev, über den Vite-Proxy) | http://localhost:3100/downloads/ |
| API mit OpenAPI-Oberfläche | http://localhost:8100/api/docs |
| nginx-Frontend | Port aus FRONTEND_HTTP_PORT bzw. FRONTEND_HTTPS_PORT |
| MariaDB | Port 3307 |
| Redis | Port 6380 |
| Garage S3 | Port 3910 |
opsiconfd-Mock (opsi-mock) | opsi-config.mock und depot1.mock, nur im Docker-Netz |
zweiter opsiconfd-Mock (opsi-mock2) | opsi-config2.mock und depot2.mock, nur im Docker-Netz |
Jeder Mock bildet einen Configserver und ein Depot nach, einschließlich Installieren, Deinstallieren und WebDAV. opbweb-opsi-mock ist das erste opsi-System: Solange kein Configserver eingerichtet ist, trägt die API ihn beim Start als „opsiconfd-Mock“ mit der Stufe Test ein (URL http://opsi-config.mock:4447, Benutzer opsiadm, Passwort mock, ohne TLS-Prüfung). opbweb-opsi-mock2 ist ein zweites, unabhängiges opsi-System für Tests mit mehreren Configservern; er wird nicht automatisch eingetragen. Wer ihn in der Oberfläche nutzen will, legt ihn unter Depots mit + an (URL http://opsi-config2.mock:4447, Benutzer opsiadm, Passwort mock, TLS-Prüfung aus).
Die End-to-End-Tests tragen beide Mocks selbst als Configserver ein (als „t-Mock 1“ und „t-Mock 2“, falls noch nicht vorhanden), entfernen sie danach wieder und arbeiten nur auf deren Depots. Sie setzen nicht voraus, dass der Mock der einzige oder voreingestellte Configserver ist, und laufen auch dann, wenn zusätzlich ein echter opsi-Server eingerichtet ist. Die Handbuch-Vorschau aktualisiert sich nicht von selbst; lade die Seite nach einer Änderung neu.
Dev- und Produktiv-Stack verwenden dieselben Containernamen und dieselben Volumes. Sie können nicht gleichzeitig laufen und teilen sich Datenbank und Objektspeicher. Starte den Entwicklungs-Stack daher nie auf einem produktiven Host. Zum Wechseln stoppst du mit ./stop.sh und startest mit bzw. ohne --dev neu.