1 line
54 KiB
JSON
1 line
54 KiB
JSON
{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"StackPulse","text":"<p>StackPulse ist eine eigenst\u00e4ndige Web-Anwendung, die die Portainer Business Edition \u00fcber deren API steuert und dadurch Redeploys, Wartungsskripte sowie das Berechtigungs- und Logging-Konzept zentralisiert. Die L\u00f6sung besteht aus einem Node.js/Express Backend, einem React-Frontend auf Basis von Material Tailwind sowie einer eingebetteten SQLite-Datenbank, die ohne zus\u00e4tzliche Infrastruktur betrieben werden kann.</p>"},{"location":"#warum-stackpulse","title":"Warum StackPulse?","text":"<ul> <li>Schneller \u00dcberblick \u00fcber s\u00e4mtliche Stacks einer Portainer-Instanz inkl. Status, Filter und Suche</li> <li>Redeploy-Orchestrierung aus einem UI heraus \u2013 einzelne Stacks, Auswahlen oder komplette Umgebungen</li> <li>Auditierbare Historie durch strukturierte Event-Logs mit Export-, L\u00f6sch- und Filterfunktionen</li> <li>Feingranulare Rechteverwaltung mit Gruppenrechten, Superuser-Handling und Sicherheitsphrasen</li> <li>Wartungsautomatisierung (SSH Update-Skripte, Maintenance-Mode) ohne direkten Portainer-Zugang</li> <li>Bereitstellung als Docker-Image sowie als lokale Dev-Umgebung via <code>scripts/start-dev.sh</code></li> </ul>"},{"location":"#technische-eckdaten","title":"Technische Eckdaten","text":"Baustein Technologie Beschreibung Backend Node.js 20, Express, Axios, Socket.IO, better-sqlite3 Stellt REST-API, Authentifizierung, Rechte, Logging, Redeploy-Queue und Portainer-Proxy bereit. Datenhaltung SQLite (Datei <code>backend/data/stackpulse.db</code>) Persistente Speicherung von Benutzern, Gruppen, Servern, API-Keys, Logs und Einstellungen. Frontend React 18, Vite, Material Tailwind Dashboard Dashboard mit Auth-Flow, Stacks, Logs, Benutzer- und Wartungsansichten. Container Dockerfile + Compose Multi-Stage Build f\u00fcr Frontend + Backend, Datenvolumen f\u00fcr SQLite."},{"location":"#release-status","title":"Release-Status","text":"<ul> <li>v0.5 (aktuell) \u2013 vollst\u00e4ndiges Auth/Berechtigungssystem, Benutzer- & Gruppenverwaltung, erweiterte Logs</li> <li>v0.4 \u2013 neues UI auf Basis des Material Tailwind Dashboards</li> <li>v0.3 \u2013 Such- & Filterfunktionen, Konfliktbehandlung f\u00fcr Stack-IDs, UI-Benachrichtigungen</li> <li>v0.2 \u2013 SQLite-Logging inkl. Export/Pagination, Redeploy-Selektor</li> <li>v0.1 \u2013 Grundstruktur, API-Anbindung, erstes Redeploy</li> </ul> <p>Weitere geplante Features (Notifications, Monitoring, Multi-Server, Portainer CE) findest du in der Roadmap im README.</p>"},{"location":"#wie-geht-es-weiter","title":"Wie geht es weiter?","text":"<ul> <li>Getting Started erl\u00e4utert Installation, Konfiguration und erste Schritte.</li> <li>Architektur beschreibt Aufbau, Verzeichnisse und Datenfl\u00fcsse.</li> <li>Backend fasst API, Datenbank und Sicherheitsschichten zusammen.</li> <li>Frontend dokumentiert Layout, Routen und Komponenten.</li> <li>Operations & Wartung enth\u00e4lt Betriebshinweise und Troubleshooting.</li> </ul>"},{"location":"architecture/","title":"Architektur","text":"<p>StackPulse folgt einer klassischen Client/Server-Architektur, bei der das Backend den Single-Source-of-Truth darstellt und das Frontend ausschlie\u00dflich \u00fcber wohldefinierte REST- und Socket.IO-Schnittstellen kommuniziert.</p> <pre><code>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 HTTPS + WebSocket \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 HTTPS \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Frontend \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25b6 \u2502 Backend \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25b6 \u2502 Portainer API \u2502\n\u2502 (React) \u2502 \u25c0\u2500\u2500\u2500\u2500\u2500 Auth-Cookie + JSON \u2500 \u2502 (Express) \u2502 \u25c0\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2502 Business Ed. \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Redeploy Events \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 (Axios Proxy) \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u2502\n \u25bc\n SQLite Datenbank\n</code></pre>"},{"location":"architecture/#hauptschichten","title":"Hauptschichten","text":"<ul> <li>Frontend (Vite + Material Tailwind): stellt alle Views, Formulare, Tabellen und Echtzeit-Widgets bereit. Die <code>AuthProvider</code>-Komponente verwaltet Session, Permissions und Socket-Verbindungen.</li> <li>Backend (Express + better-sqlite3): aggregiert Daten aus Portainer, persistiert Benutzer/Gruppen/Logs, verwaltet Sessions und st\u00f6\u00dft Redeploy- sowie Wartungsprozesse an.</li> <li>Persistenz (SQLite): Datei <code>backend/data/stackpulse.db</code>, WAL-Modus aktiviert. Tabellen umfassen u. a. <code>users</code>, <code>groups</code>, <code>permissions</code>, <code>servers</code>, <code>server_api_keys</code>, <code>event_logs</code>, <code>settings</code> sowie Hilfstabellen f\u00fcr Tokens und Sicherheitspassphrasen.</li> </ul>"},{"location":"architecture/#datenflusse","title":"Datenfl\u00fcsse","text":"<ol> <li>Setup-Phase: <code>/api/setup/*</code> nimmt Serverdaten entgegen, verschl\u00fcsselt API-Keys (<code>aes-256-gcm</code> via <code>PORTAINER_API_SECRET</code>) und erstellt Eintr\u00e4ge in <code>servers</code>/<code>server_api_keys</code>.</li> <li>Authentication: <code>/api/auth/login</code> erstellt Sessions (JWT-\u00e4hnliche Tokens in Cookies), <code>AuthProvider</code> ruft <code>/api/auth/session</code> zyklisch ab und speichert Berechtigungen.</li> <li>Stack-\u00dcbersicht: Frontend ruft <code>/api/stacks</code> auf. Das Backend proxyt <code>Portainer /api/endpoints/:id/docker/stacks</code>, erg\u00e4nzt Caching, interne Metadaten und liefert Redeploy-Status.</li> <li>Redeploy: UI st\u00f6\u00dft <code>/api/stacks/:id/redeploy</code>, <code>/api/stacks/redeploy-selection</code> oder <code>/api/stacks/redeploy-all</code> an. Das Backend ruft Portainer-Endpoints, protokolliert Events und broadcastet Fortschritt via Socket.IO <code>redeployStatus</code>.</li> <li>Logging: Jeder relevante Vorgang erzeugt Eintr\u00e4ge in <code>event_logs</code> (siehe <code>logging/eventLogs.js</code>). Frontend filtert/paginiert \u00fcber <code>/api/logs</code> und kann Exporte <code>/api/logs/export</code> herunterladen.</li> <li>Wartung: <code>/api/maintenance/*</code> verwaltet Maintenance-Mode, SSH-Zug\u00e4nge, Update-Skripte und serverseitige Settings (<code>db/settings.js</code>).</li> </ol>"},{"location":"architecture/#verzeichnis-referenz","title":"Verzeichnis-Referenz","text":"Pfad Inhalt <code>backend/index.js</code> Herzst\u00fcck der API inkl. Routing, Socket.IO, Redeploy, Setup, Auth. <code>backend/auth/</code> Superuser-Verwaltung, Passwort- und Tokenfunktionen, Sicherheitsphrasen. <code>backend/db/</code> SQLite-Initialisierung (<code>ensure.js</code>/<code>schemaEnsure.js</code>), Settings-Layer, DB-Blueprints. <code>backend/logging/</code> Event-Log Modellierung, Filter/Export/Delete. <code>backend/groups/</code>, <code>backend/users/</code>, <code>backend/permissions/</code> Domain-Logik f\u00fcr Benutzer- & Rechteverwaltung. <code>backend/maintenance/</code> Maintenance-Mode sowie SSH-/Update-Konfiguration. <code>frontend/src/</code> React-App (Layouts, Pages, Widgets, Provider). <code>routes.jsx</code> definiert Navigation & Permissions. <code>scripts/</code> Hilfsskripte (z.\u202fB. <code>start-dev.sh</code>). <code>Dockerfile</code>, <code>docker-compose*.yml</code> Build- & Deployment-Spezifikation."},{"location":"architecture/#konfiguration-secrets","title":"Konfiguration & Secrets","text":"<ul> <li>API-Keys und Passw\u00f6rter werden verschl\u00fcsselt in SQLite abgelegt (<code>server_api_keys</code>, <code>settings</code>).</li> <li>Settings (Maintenance, Update-Skripte, SSH) nutzen <code>db/settings.js</code> mit JSON-Serialisierung.</li> <li>Das Backend erzwingt HTTPS-Requests Richtung Portainer (<code>https.Agent</code> mit deaktivierter Zertifikatspr\u00fcfung f\u00fcr interne Netze).</li> <li>Socket.IO lauscht auf demselben Port wie Express (<code>/socket.io</code>). CORS ist aktuell f\u00fcr alle Origins offen \u2013 f\u00fcr produktive Deployments empfiehlt sich ein Reverse Proxy mit Authentifizierung.</li> </ul>"},{"location":"architecture/#skalierung-grenzen","title":"Skalierung & Grenzen","text":"<ul> <li>SQLite eignet sich f\u00fcr Einzelinstanzen. F\u00fcr h\u00f6here Last empfiehlt sich eine Umstellung auf Postgres/MySQL (der Code kapselt Zugriffe weitgehend in <code>db/*</code>).</li> <li>Redeploy-Operationen werden seriell behandelt (<code>redeployingStacks</code> + Status-Caching). Parallele Ausf\u00fchrung ist m\u00f6glich, solange Portainer dies unterst\u00fctzt.</li> <li>Logging wird ausschlie\u00dflich serverseitig betrieben; Client-seitige Filterung erfolgt \u00fcber Query-Parameter.</li> </ul> <p>Die weiteren Kapitel vertiefen Backend- und Frontend-spezifische Details.</p>"},{"location":"backend/","title":"Backend & API","text":"<p>Das Backend implementiert alle Anwendungsf\u00e4lle \u00fcber Express-Routen, Socket.IO f\u00fcr Echtzeit-Events und eine SQLite-Datenbank als Persistenzschicht. Dieser Abschnitt fasst die wichtigsten Module, Entit\u00e4ten und Endpunkte zusammen.</p>"},{"location":"backend/#laufzeit-einstiegspunkte","title":"Laufzeit & Einstiegspunkte","text":"<ul> <li><code>backend/index.js</code> initialisiert Express, Socket.IO, l\u00e4dt <code>.env</code>, sorgt f\u00fcr Schema-Validierung (<code>ensureDatabaseSchema</code>) und Default-Daten (<code>ensureSuperuserFromEnv</code>, <code>ensureDefaultsFromEnv</code>).</li> <li>Start via <code>npm start</code> (siehe <code>package.json</code>); Migrationen \u00fcber <code>npm run migrate</code>.</li> <li>Datenbankdatei: <code>backend/data/stackpulse.db</code>, WAL-Modus aktiv.</li> </ul>"},{"location":"backend/#module","title":"Module","text":"Modul Pfad Aufgabe Auth/Superuser <code>auth/superuser.js</code> Registrieren/Verifizieren von Superusern, Login, Passwortvalidierung, Sicherheitsphrasen. Users & Groups <code>users/*</code>, <code>groups/*</code>, <code>permissions/*</code> CRUD f\u00fcr Benutzer, Gruppen, Rechtezuweisung, Ableitung effektiver Berechtigungen. Setup <code>setup/index.js</code> Verwaltung registrierter Portainer-Server, sichere Ablage der API-Keys, Setup-Status. Logging <code>logging/eventLogs.js</code> Einheitliches Ereignislogging (Insert, Filter, Delete, Export). Maintenance <code>maintenance/state.js</code> + helper in <code>index.js</code> Wartungsmodus, SSH-Konfiguration, Update-Skripte und Ausf\u00fchrung. Portainer Proxy Funktionen in <code>index.js</code> Kommunikation mit Portainer (<code>axiosInstance</code> + dynamische <code>baseURL</code>), Environment-Erkennung und Redeploy-Strecke."},{"location":"backend/#api-uberblick-auszug","title":"API-\u00dcberblick (Auszug)","text":""},{"location":"backend/#setup-server","title":"Setup & Server","text":"Methode Route Beschreibung GET <code>/api/setup/status</code> Gibt zur\u00fcck, ob Server/API-Key/Superuser vorhanden sind. POST <code>/api/setup/test-portainer</code> Verifiziert URL + API-Key gegen Portainer. POST <code>/api/setup/portainer-stacks</code> Listet Stacks (f\u00fcr Preview im Wizard). POST <code>/api/setup/complete</code> Markiert Setup als abgeschlossen und hinterlegt Server/API-Key. DELETE <code>/api/setup/servers/:id</code> Entfernt einen registrierten Portainer-Server. PUT <code>/api/setup/servers/:id/api-key</code> \u00dcberschreibt API-Key. PUT <code>/api/setup/self-stack</code> Speichert die ID des StackPulse-Stacks, damit dieser nicht redeployed wird."},{"location":"backend/#authentifizierung","title":"Authentifizierung","text":"Methode Route Beschreibung POST <code>/api/auth/login</code> Username/Passwort-Login, setzt HTTP-only Cookie. POST <code>/api/auth/logout</code> Session beenden & Cookie l\u00f6schen. GET <code>/api/auth/session</code> Liefert eingeloggten Benutzer + Permissions. POST <code>/api/auth/recover/verify</code> & <code>/reset</code> Passwortreset \u00fcber Sicherheitsphrase. GET/POST/DELETE <code>/api/auth/superuser/*</code> Abfrage, Registrierung oder Entfernen des Superusers."},{"location":"backend/#benutzer-gruppen","title":"Benutzer & Gruppen","text":"Methode Route Beschreibung GET/POST <code>/api/users</code> Liste anlegen, neue Benutzer erstellen. GET/PUT/DELETE <code>/api/users/:id</code> Details lesen, bearbeiten oder l\u00f6schen. PUT <code>/api/users/:id/groups</code> Gruppenmitgliedschaften aktualisieren. PUT <code>/api/users/:id/active</code> Benutzer aktivieren/deaktivieren. GET/POST <code>/api/users/:id/security-phrase</code>, <code>/renew</code> Sicherheitsphrase anzeigen bzw. neu generieren. GET/POST <code>/api/groups</code> Gruppen auflisten oder neu anlegen. PUT/DELETE <code>/api/groups/:id</code> Gruppe editieren oder entfernen. GET/PUT <code>/api/groups/:id/permissions</code> Berechtigungen lesen/setzen."},{"location":"backend/#stacks-redeploy","title":"Stacks & Redeploy","text":"Methode Route Beschreibung GET <code>/api/stacks</code> Aggregierte Liste inkl. Filter, Self-Stack-Blockade und Redeploy-Status. PUT <code>/api/stacks/:id/redeploy</code> Redeploy eines einzelnen Stacks. PUT <code>/api/stacks/redeploy-selection</code> Redeploy einer Liste \u00fcbermittelter <code>stackIds</code>. PUT <code>/api/stacks/redeploy-all</code> Redeploy aller Stacks (Permission <code>stacks-redeploy-all</code>). <p>Das Backend ver\u00f6ffentlicht den Redeploy-Fortschritt parallel \u00fcber Socket.IO (<code>redeployStatus</code> Event) und unterscheidet die Phasen <code>queued</code>, <code>started</code>, <code>success</code>, <code>error</code>, <code>info</code>.</p>"},{"location":"backend/#logging-wartung","title":"Logging & Wartung","text":"Methode Route Beschreibung GET <code>/api/logs</code> Filterbare/Paginierbare Event-Logs. DELETE <code>/api/logs/:id</code> oder <code>/api/logs</code> Einzelne oder gefilterte Logs l\u00f6schen. GET <code>/api/logs/export</code> CSV-Export anhand der Query-Filter. GET/POST <code>/api/maintenance/mode</code> Status abfragen oder toggeln. GET <code>/api/maintenance/config</code> Liefert Maintenance-Status, Update-Skript & SSH-Config. PUT/DELETE <code>/api/maintenance/ssh-config</code> SSH-Credentials speichern/entfernen. POST <code>/api/maintenance/test-ssh</code> Verbindungstest mit optionalem Override. PUT/DELETE <code>/api/maintenance/update-script</code> Custom Update-Skript pflegen. POST <code>/api/maintenance/portainer-update</code> Update-Kommando per SSH ausf\u00fchren (mit Custom/Default-Skript)."},{"location":"backend/#datenbank-schema","title":"Datenbank & Schema","text":"<ul> <li><code>ensureDatabaseSchema()</code> erzeugt Tabellen bei jedem Start, inklusive Default-Gruppen, Permissions, Settings, Server-Eintr\u00e4ge und Trigger.</li> <li>Permissions werden anhand der Blueprint-Datei <code>backend/db/dbs</code> eingelesen. Jede Permission definiert Key, Label, Level (<code>full</code>, <code>read</code>, <code>none</code>) und Abh\u00e4ngigkeiten.</li> <li>Events werden in <code>event_logs</code> gespeichert. Relevante Felder:</li> <li><code>category</code>, <code>event_type</code>, <code>action</code>, <code>status</code>, <code>severity</code></li> <li><code>entity_type</code>, <code>entity_id</code>, <code>entity_name</code></li> <li><code>actor_type</code>, <code>actor_id</code>, <code>actor_name</code></li> <li><code>context_type</code>, <code>context_id</code>, <code>context_label</code></li> <li><code>message</code>, <code>metadata (JSON)</code></li> <li>Filter-Parameter (<code>ids</code>, <code>categories</code>, <code>eventTypes</code>, <code>status</code>, <code>stackIds</code>, Zeitfenster) werden in <code>buildEventLogFilter</code> zentral verarbeitet.</li> </ul>"},{"location":"backend/#berechtigungssystem","title":"Berechtigungssystem","text":"<ul> <li>Jeder Benutzer geh\u00f6rt zu beliebig vielen Gruppen; die effektiven Rechte ergeben sich aus der h\u00f6chsten Auspr\u00e4gung pro Permission.</li> <li>Superuser erhalten alle Berechtigungen und k\u00f6nnen nicht \u00fcber das UI entzogen werden.</li> <li><code>PermissionGate</code> im Frontend spiegelt die gleichen Keys. Wichtigste Bereiche:</li> <li><code>stacks-*</code> (Redeploy)</li> <li><code>logs-*</code></li> <li><code>users-*</code> & <code>user-groups-*</code></li> <li><code>maintenance-*</code> (inkl. Unterrechte <code>maintenance-server-*</code>, <code>maintenance-ssh-update</code>, <code>maintenance-update</code>)</li> </ul>"},{"location":"backend/#redeploy-workflow","title":"Redeploy-Workflow","text":"<ol> <li>Eingehender Request wird mit <code>maintenanceGuard</code> gepr\u00fcft (Maintenance-Modus blockiert optional Redeploys).</li> <li>Das Backend ermittelt den zugeh\u00f6rigen Portainer-Endpoint (<code>resolvePortainerEnvironmentId</code>).</li> <li>Der Redeploy wird \u00fcber Portainer ausgef\u00fchrt (<code>/api/stacks/:id/redeploy</code>), Log-Eintr\u00e4ge werden erstellt.</li> <li><code>broadcastRedeployStatus()</code> aktualisiert das In-Memory-Tracking (<code>redeployingStacks</code>) und sendet Socket.IO Events.</li> <li>Fehler f\u00fchren zu <code>event_logs</code>-Eintr\u00e4gen mit <code>severity=error</code>, UI zeigt Toasts via <code>ToastProvider</code>.</li> </ol>"},{"location":"backend/#wartungs-und-updatepfad","title":"Wartungs- und Updatepfad","text":"<ul> <li><code>maintenance/state.js</code> persistiert Aktivierung & Nachricht im Setting <code>maintenance_mode</code>.</li> <li>SSH-Konfigurationen (Host, Port, User, Passwort, extra args) werden verschl\u00fcsselt gespeichert (<code>getPortainerSshConfig</code>).</li> <li>Update-Skripte lassen sich \u00fcberschreiben, Standard-Skript liegt in <code>DEFAULT_PORTAINER_UPDATE_SCRIPT</code> (Bash-Befehle).</li> <li>Update-Status h\u00e4lt Laufzeiten, letzte Ergebnisse und Logausz\u00fcge in-memory & Settings bereit.</li> </ul>"},{"location":"backend/#erweiterungstipps","title":"Erweiterungstipps","text":"<ul> <li>Neue API-Routen sollten <code>requirePermission(..)</code> nutzen, Logging via <code>logEvent()</code> hinzuf\u00fcgen und \u2013 falls Portainer-Aufrufe stattfinden \u2013 das <code>axiosInstance</code> verwenden.</li> <li>Einstellungen stets \u00fcber <code>db/settings.js</code> verwalten, damit UI & CLI konsistent bleiben.</li> <li>F\u00fcr breaking DB-\u00c4nderungen existiert kein Migrations-Framework \u2013 erweitere <code>ensureDatabaseSchema</code> inkl. Versionsflag, um Idempotenz sicherzustellen.</li> </ul>"},{"location":"frontend/","title":"Frontend","text":"<p>Das Frontend basiert auf React 18, Vite und dem Material Tailwind Dashboard. Es nutzt Context Provider f\u00fcr Authentifizierung, Seitenstatus, Toaster und Wartungsinformationen.</p>"},{"location":"frontend/#build-skripte","title":"Build & Skripte","text":"Befehl Beschreibung <code>npm run dev</code> Startet den Vite Dev-Server (Port 5173, HMR aktiviert). <code>npm run build</code> Erstellt ein Production-Bundle (<code>frontend/dist</code>). Das Dockerfile kopiert dieses Paket ins Backend (<code>backend/public</code>). <code>npm run preview</code> Vorschau auf das gebaute Bundle."},{"location":"frontend/#projektstruktur","title":"Projektstruktur","text":"<pre><code>frontend/src\n\u251c\u2500\u2500 App.jsx # Entry-Point, registriert Layouts & Provider\n\u251c\u2500\u2500 components/ # AuthProvider, PermissionGate, Toast/Maintenance/PageProvider\n\u251c\u2500\u2500 layouts/ # Dashboard-Layout (Sidebar, Navbar) & Auth-Layout\n\u251c\u2500\u2500 pages/\n\u2502 \u251c\u2500\u2500 auth/ # SignIn, SignUp, ForgotPassword, SignOut\n\u2502 \u251c\u2500\u2500 dashboard/ # Stacks, Logs, Maintenance, Users, Usergroups, Detailseiten\n\u2502 \u2514\u2500\u2500 setup/ # Setup-Wizard & Helper Screens\n\u251c\u2500\u2500 routes.jsx # zentrale Navigationsdefinition inkl. Permissions\n\u251c\u2500\u2500 widgets/, data/, configs/, assets/\n\u2514\u2500\u2500 tailwind.css # Tailwind Layer & Custom Styles\n</code></pre>"},{"location":"frontend/#routing-navigation","title":"Routing & Navigation","text":"<ul> <li><code>routes.jsx</code> beschreibt sowohl Dashboard- als auch Auth-Routen. Jede Dashboard-Seite besitzt optional ein <code>permission</code>-Objekt, das vom <code>PermissionGate</code> ausgewertet wird.</li> <li>Der Layout-Switch erfolgt \u00fcber <code>layouts/index.jsx</code>, das wiederum Sidebar/Topbar-Komponenten aus dem Material Tailwind Dashboard nutzt.</li> <li>Auth-Routen (<code>/sign-in</code>, <code>/sign-up</code>, <code>/forgot-password</code>, <code>/logout</code>) werden im Auth-Layout ohne Sidebar dargestellt.</li> </ul>"},{"location":"frontend/#state-management-contexts","title":"State-Management & Contexts","text":"Provider Aufgabe <code>AuthProvider</code> Speichert User, Permissions, Session-Status. Stellt <code>refreshSession</code>, <code>logout</code>, <code>hasPermission</code> bereit. <code>PageProvider</code> Zentrale UI-Zust\u00e4nde (z.\u202fB. Ladeanzeigen, modale Dialoge) f\u00fcr Dashboard-Komponenten. <code>ToastProvider</code> Globale Notifications (z.\u202fB. Redeploy-Erfolg/Fehler). <code>MaintenanceProvider</code> Cached Maintenance-Status, erkennt aktive Maintenance Modes und zeigt Hinweise."},{"location":"frontend/#wichtige-seiten","title":"Wichtige Seiten","text":"<ul> <li>Stacks (<code>pages/dashboard/stacks.jsx</code>): Haupt\u00fcbersicht mit Tabellen, Suche, Filtern, Bulk- und Einzelredeploy. Bindet <code>socket.io-client</code> f\u00fcr Live-Updates (<code>redeployStatus</code>).</li> <li>Logs (<code>pages/dashboard/logs.jsx</code>): Tabellenansicht mit Statusfarben, Filterchips, Export-/Delete-Aktionen. Nutzt axios-Queries gegen <code>/api/logs</code>.</li> <li>Maintenance (<code>pages/dashboard/maintenance.jsx</code>): Formulare zur Verwaltung von Update-Skript, SSH-Konfiguration, Maintenance-Mode-Toggle und Portainer-Statuspr\u00fcfung.</li> <li>Users / Usergroups: CRUD-Oberfl\u00e4che f\u00fcr Benutzer, Gruppen, Berechtigungszuweisung inkl. Sicherheitsphrasen-Handling.</li> <li>Setup (<code>pages/setup</code>): Schrittweiser Wizard (Server -> API-Key -> Superuser). Wird solange angezeigt, bis <code>/api/setup/status</code> vollst\u00e4ndig ist.</li> </ul>"},{"location":"frontend/#datenzugriff","title":"Datenzugriff","text":"<ul> <li>HTTP-Anfragen erfolgen via <code>axios</code> (global konfiguriert in <code>frontend/src/components/AuthProvider</code> bzw. direkt in den Seiten). Cookies werden automatisch vom Browser beigesteuert (<code>credentials: 'include'</code>).</li> <li>Socket.IO wird nur im Stack-Dashboard verwendet; Verbindungsaufbau erfolgt in <code>stacks.jsx</code> (<code>io('/', { path: '/socket.io' })</code>).</li> <li>Fehlerbehandlung: Jede Seite zeigt Toasts und/oder Inline-Warnungen. Auth-Fehler leiten zur Loginseite um.</li> </ul>"},{"location":"frontend/#styling-komponenten","title":"Styling & Komponenten","text":"<ul> <li>Tailwind Utility-Klassen liefert Material Tailwind bereits vordefiniert (Theme in <code>configs</code>).</li> <li>Custom-Komponenten wie Tabellen, Filterchips oder Formulare sind \u00fcberwiegend in <code>widgets/</code> ausgelagert.</li> <li>Icons stammen aus <code>@heroicons/react</code>. Farben/Typografie folgen Creative Tim Vorgaben, k\u00f6nnen aber zentral in <code>frontend/src/configs</code> angepasst werden.</li> </ul>"},{"location":"frontend/#erweiterungshinweise","title":"Erweiterungshinweise","text":"<ol> <li>Neue Seiten: Route in <code>routes.jsx</code> erg\u00e4nzen, optional <code>PermissionGate</code> konfigurieren und Seite unter <code>pages/dashboard</code> oder <code>pages/auth</code> anlegen.</li> <li>API-Anbindungen: Verwende <code>axios</code> und achte auf <code>try/catch</code>, damit 401/403 sauber abgefangen werden. Bei kritischen Anforderungen <code>refreshSession</code> aufrufen.</li> <li>State teilen: Nutze bestehende Provider bzw. erzeuge einen eigenen Context in <code>components/</code>.</li> <li>Deployment: <code>npm run build</code> liefert ein Self-Contained Bundle. Das Backend dient anschlie\u00dfend als Static Host (<code>express.static</code>).</li> </ol> <p>Damit bietet das Frontend eine anpassbare, klar strukturierte Oberfl\u00e4che, die eng mit den Backend-Permissions verzahnt ist.</p>"},{"location":"getting-started/","title":"Getting Started","text":"<p>Dieser Leitfaden hilft dir, StackPulse lokal oder als Container aufzusetzen und die ersten Schritte im UI abzuschlie\u00dfen.</p>"},{"location":"getting-started/#voraussetzungen","title":"Voraussetzungen","text":"<ul> <li>Node.js >= 20 und npm f\u00fcr lokale Entwicklung</li> <li>Docker & Docker Compose (optional aber empfohlen f\u00fcr Deployment)</li> <li>Zugriff auf eine Portainer Business Edition samt API-Key</li> <li>Shell-Zugang zum Host, auf dem StackPulse laufen soll</li> </ul>"},{"location":"getting-started/#repository-abhangigkeiten","title":"Repository & Abh\u00e4ngigkeiten","text":"<pre><code># Repository klonen\n# git clone <repo-url>\ncd stackpulse\n\n# Skript ausf\u00fchrbar machen\nchmod +x scripts/start-dev.sh\n</code></pre>"},{"location":"getting-started/#lokale-dev-umgebung","title":"Lokale Dev-Umgebung","text":"<p>Das Skript <code>scripts/start-dev.sh</code> richtet Backend und Frontend automatisch ein:</p> <ol> <li>Backend: <code>npm install</code>, <code>npm run migrate</code> (erstellt/aktualisiert <code>backend/data/stackpulse.db</code>), <code>npm start</code></li> <li>Frontend: <code>npm install</code>, <code>npm run dev</code> (Port 5173) und ein einmaliges <code>npm run build</code>, um statische Assets ins Backend zu spiegeln</li> </ol> <p>Nach erfolgreichem Start: - Frontend dev server: http://localhost:5173 - Backend API & statische Assets: http://localhost:4001</p> <p>Zum Stoppen STRG+C verwenden.</p>"},{"location":"getting-started/#manuelles-starten","title":"Manuelles Starten","text":"<pre><code># Backend\ncd backend\nnpm install\nnpm run migrate\nPORTAINER_URL=https://portainer.local npm start\n\n# Frontend in zweiter Shell\ncd frontend\nnpm install\nnpm run dev\n</code></pre> <p>Das Backend liest Umgebungsvariablen beim Start. Alternativ kannst du eine <code>.env</code> neben <code>backend/index.js</code> anlegen.</p>"},{"location":"getting-started/#zentrale-umgebungsvariablen","title":"Zentrale Umgebungsvariablen","text":"Variable Beschreibung <code>PORTAINER_URL</code> Basis-URL zu deiner Portainer-Instanz (inkl. Protokoll). Kann sp\u00e4ter im Setup-UI \u00fcberschrieben werden. <code>PORTAINER_API_KEY</code> API-Key f\u00fcr Portainer. Wird in der DB verschl\u00fcsselt abgelegt, sobald du ihn im Setup speicherst. <code>PORTAINER_SERVER_NAME</code> Optionaler Anzeigename f\u00fcr den Server w\u00e4hrend des Setups. <code>PORTAINER_API_SECRET</code> \u00dcberschreibt den Schl\u00fcssel, der zur Verschl\u00fcsselung des API-Keys verwendet wird. <code>SUPERUSER_USERNAME</code>, <code>SUPERUSER_EMAIL</code>, <code>SUPERUSER_PASSWORD</code> Legt einen Superuser automatisch beim Start an (falls nicht vorhanden). <code>SELF_STACK_ID</code> Stack-ID von StackPulse selbst. Wird genutzt, um eigene Redeploys zu blockieren. <code>AUTH_COOKIE_NAME</code>, <code>AUTH_SESSION_TTL_MS</code>, <code>AUTH_COOKIE_SECURE</code> Feintuning f\u00fcr die Session-Verwaltung der API. <code>SECURITY_PHRASE_SECRET</code> Seed f\u00fcr die Generierung kryptografischer Sicherheitsphrasen. <code>PORTAINER_SSH_SECRET</code> Secret f\u00fcr SSH-Passwortverschl\u00fcsselung (Wartungs-Update). <code>DISPLAY</code> Wird an Kindprozesse weitergereicht, wenn Portainer-Updates ausgel\u00f6st werden m\u00fcssen (Default <code>:9999</code>). <p>Weitere Einstellungen (SSH-Config, Update-Skripte) verwaltest du sp\u00e4ter direkt im Maintenance-Bereich des UI.</p>"},{"location":"getting-started/#ersteinrichtung-im-ui","title":"Ersteinrichtung im UI","text":"<ol> <li>\u00d6ffne das Frontend (<code>/setup</code> f\u00fchrt dich automatisch durch den Wizard).</li> <li>Lege den Portainer-Server und den zugeh\u00f6rigen API-Key an \u2013 StackPulse testet die Verbindung per <code>/api/setup/test-portainer</code>.</li> <li>Registriere einen Superuser oder verwende den per Umgebungsvariablen automatisch angelegten Account.</li> <li>Nach erfolgreicher Einrichtung kannst du dich anmelden und erh\u00e4ltst Zugriff auf Dashboard, Logs, Benutzer & Wartung.</li> </ol>"},{"location":"getting-started/#docker-deployment","title":"Docker-Deployment","text":"<pre><code># docker-compose.yml (Auszug)\nservices:\n app:\n build:\n context: .\n dockerfile: Dockerfile\n ports:\n - \"4001:4001\"\n volumes:\n - stackpulse_data:/app/backend/data\n restart: unless-stopped\n environment:\n - PORTAINER_URL=https://portainer.example.com\n - PORTAINER_API_KEY=xxxx\n - SUPERUSER_USERNAME=admin\n - SUPERUSER_EMAIL=admin@example.com\n - SUPERUSER_PASSWORD=changeme\n - SELF_STACK_ID=123\nvolumes:\n stackpulse_data:\n</code></pre> <ol> <li><code>docker compose up -d --build</code></li> <li>Das Frontend ist anschlie\u00dfend unter Port 4001 (via Backend <code>public/</code>) erreichbar.</li> <li>Datenbank & Einstellungen liegen im benannten Volume <code>stackpulse_data</code>.</li> </ol>"},{"location":"getting-started/#datenbank-migration","title":"Datenbank & Migration","text":"<ul> <li>Datei: <code>backend/data/stackpulse.db</code></li> <li>Migration: <code>npm run migrate</code> (f\u00fchrt <code>backend/db/ensure.js</code> aus und erzeugt Schema, Rechte, Defaults)</li> <li>Backup: Datei oder Volume regelm\u00e4\u00dfig sichern; enth\u00e4lt Benutzer, Logs und gespeicherte Secrets.</li> </ul> <p>Damit bist du bereit f\u00fcr die tieferen Kapitel zu Architektur sowie Backend- und Frontend-Details.</p>"},{"location":"operations/","title":"Operations & Wartung","text":"<p>Dieser Abschnitt deckt typische Aufgaben f\u00fcr Betriebsteams ab \u2013 von Backups \u00fcber Wartungsmodus bis zu St\u00f6rungssuche.</p>"},{"location":"operations/#laufender-betrieb","title":"Laufender Betrieb","text":"<ul> <li>Services \u00fcberwachen: StackPulse stellt nur einen Prozess bereit (Node.js/Express). Nutze Systemd/Docker Healthchecks, indem du regelm\u00e4\u00dfig <code>/api/auth/session</code> (f\u00fcr Auth) oder <code>/api/maintenance/update-status</code> (f\u00fcr Backend + DB) abfragst.</li> <li>Ports: Standardm\u00e4\u00dfig lauscht nur Port 4001 (HTTP + Socket.IO). Hinter einem Reverse Proxy sollte TLS terminiert werden.</li> <li>Protokolle: Das Backend loggt ausf\u00fchrlich auf STDOUT/STDERR (<code>console.log</code>). Sammle diese via Docker-Logs oder Journal.</li> </ul>"},{"location":"operations/#backups-wiederherstellung","title":"Backups & Wiederherstellung","text":"<ol> <li>Container-Setup: Mount <code>backend/data</code> via benanntem Volume (siehe <code>docker-compose.yml</code>).</li> <li>Backup: Stoppe kurz den Container oder nutze <code>sqlite3 stackpulse.db \".backup 'stackpulse.db.bak'\"</code> innerhalb der laufenden Instanz.</li> <li>Restore: Ersetze die Datei im Volume und starte die App neu. Beim ersten Start f\u00fchrt <code>ensureDatabaseSchema</code> automatisch eventuelle Nachmigrationen aus.</li> </ol>"},{"location":"operations/#benutzer-rechteverwaltung","title":"Benutzer- & Rechteverwaltung","text":"<ul> <li>Superuser k\u00f6nnen \u00fcber <code>/api/auth/superuser/*</code> oder im UI registriert werden. Entfernen ist nur mit <code>maintenance-superuser-delete</code> m\u00f6glich.</li> <li>Benutzerkonten lassen sich tempor\u00e4r deaktivieren (<code>/api/users/:id/active</code>). Die Historie bleibt erhalten.</li> <li>Sicherheitsphrasen sind notwendig f\u00fcr Passwort-Reset. Admins k\u00f6nnen neue Phrasen erzeugen (<code>/api/users/:id/security-phrase/renew</code>), m\u00fcssen diese aber dem Benutzer sicher zustellen.</li> </ul>"},{"location":"operations/#wartungsmodus-updates","title":"Wartungsmodus & Updates","text":"<ul> <li>Maintenance Mode aktivieren: <code>curl -X POST http://host:4001/api/maintenance/mode -H 'Content-Type: application/json' -d '{\"active\":true,\"message\":\"Cluster Upgrade\"}'</code> (Permission <code>maintenance-access</code>). Das UI informiert alle Nutzer und blockiert Redeploys.</li> <li>SSH-/Update-Setup: Hinterlege Host, Port, Benutzer, Passwort (optional) und zus\u00e4tzliche SSH-Argumente. Passw\u00f6rter werden verschl\u00fcsselt gespeichert (<code>PORTAINER_SSH_SECRET</code>).</li> <li>Update-Skript: Das Default-Skript (<code>DEFAULT_PORTAINER_UPDATE_SCRIPT</code>) f\u00fchrt <code>docker stop</code>, <code>docker run</code> etc. aus. Du kannst im UI oder via API ein eigenes Skript setzen \u2013 wird erst aktualisiert, wenn kein Update l\u00e4uft.</li> <li>Update ansto\u00dfen: <code>POST /api/maintenance/portainer-update</code> triggert die SSH-Kommandos. Status & Logausgaben k\u00f6nnen \u00fcber <code>/api/maintenance/update-status</code> \u00fcberwacht werden.</li> </ul>"},{"location":"operations/#logs-compliance","title":"Logs & Compliance","text":"<ul> <li>Ereignislogs enthalten jede Redeploy-, Auth- und Verwaltungsaktion. Export \u00fcber <code>GET /api/logs/export</code> (CSV) oder automatisiert mittels Cron (Query-Parameter \u00fcbernehmen Filter).</li> <li>Datenbereinigung: Nutze <code>DELETE /api/logs/:id</code> oder <code>DELETE /api/logs?before=<ISO></code> um alte Eintr\u00e4ge zu entfernen. Achtung: Aktionen sind nicht reversibel.</li> <li>F\u00fcr Offload kannst du per Script regelm\u00e4\u00dfig Exporte ziehen und anschlie\u00dfend l\u00f6schen.</li> </ul>"},{"location":"operations/#troubleshooting","title":"Troubleshooting","text":"Symptom Pr\u00fcfschritte Setup schl\u00e4gt fehl (PORTAINER_URL_NOT_CONFIGURED) Stelle sicher, dass entweder <code>PORTAINER_URL</code> gesetzt ist oder im Setup-UI ein Server gespeichert wurde (<code>servers</code>-Tabelle pr\u00fcfen). Redeploy h\u00e4ngt in <code>queued</code> <code>/api/maintenance/update-status</code> auf laufende Updates pr\u00fcfen, <code>redeployingStacks</code> im Log verfolgen; ggf. Portainer-API erreichbar? Login nicht m\u00f6glich \u00dcber <code>backend/logs</code> nach Auth-Fehlern suchen, Cookie-Konfiguration pr\u00fcfen (<code>AUTH_COOKIE_SECURE</code> bei HTTP?). SSH-Test fehlgeschlagen <code>POST /api/maintenance/test-ssh</code> mit tempor\u00e4ren Credentials testen, Container-Logs auf <code>SSH Test fehlgeschlagen</code> untersuchen. SQLite Locked Stelle sicher, dass kein paralleler Backup-Prozess l\u00e4uft. WAL-Modus erlaubt mehrere Leser, blockiert aber bei langen Schreibtransaktionen (Check Logs auf <code>SQLITE_BUSY</code>)."},{"location":"operations/#sicherheitsempfehlungen","title":"Sicherheitsempfehlungen","text":"<ul> <li>Setze <code>AUTH_COOKIE_SECURE=true</code> hinter TLS und konfiguriere einen Reverse Proxy (z.\u202fB. Traefik, Nginx).</li> <li>Isoliere das Admin-Interface durch VPN oder IP-Filter.</li> <li>Drehe API-Keys regelm\u00e4\u00dfig: <code>/api/setup/servers/:id/api-key</code> aktualisiert Schl\u00fcssel ohne Neuinstallation.</li> <li>Nutze dedizierte StackPulse-Benutzer in Portainer, damit Berechtigungen klar getrennt bleiben.</li> </ul> <p>Mit diesen Richtlinien l\u00e4sst sich StackPulse sicher betreiben und warten.</p>"},{"location":"user-guide/","title":"Benutzerhandbuch","text":"<p>Dieses Kapitel beschreibt die Bedienung von StackPulse aus Sicht von Administrator:innen und Operators. Es orientiert sich an den Seiten im Dashboard und erkl\u00e4rt f\u00fcr jeden Bereich typische Abl\u00e4ufe sowie die notwendigen Berechtigungen. Screenshots kannst du sp\u00e4ter erg\u00e4nzen; die Texte nennen bereits alle Buttons, Eingabefelder und Statusanzeigen.</p> <p>Reihenfolge 1. Setup \u2013 richtet Portainer-Anbindung und Superuser ein. 2. Stacks \u2013 zeigt alle Stacks, Redeploy-Aktionen und Filter. 3. Logs \u2013 Nachvollziehbarkeit, Filter & Export. 4. Wartung \u2013 Maintenance-Mode, Updates und SSH-Konfiguration. 5. Benutzer \u2013 Konten verwalten, Phrasen ausgeben, Passw\u00f6rter setzen. 6. Benutzergruppen & Rechte \u2013 Rollen modellieren und Berechtigungen zuweisen.</p> <p>Jede Seite nennt die erforderlichen Permissions. Sobald du dich anmeldest, f\u00fchrt dich StackPulse zun\u00e4chst automatisch durch den Setup-Assistenten; danach landet man auf der Stacks-\u00dcbersicht.</p>"},{"location":"user-guide/groups/","title":"Benutzergruppen & Rechte","text":"<p>Dieser Bereich verwaltet Rollenmodelle und bestimmt, welche Aktionen Benutzer:innen durchf\u00fchren d\u00fcrfen. Du ben\u00f6tigst <code>user-groups-access</code> zum Lesen sowie <code>user-groups-edit</code>/<code>user-groups-delete</code> f\u00fcr \u00c4nderungen.</p>"},{"location":"user-guide/groups/#gruppen-anlegen","title":"Gruppen anlegen","text":"<ol> <li>Button Gruppe erstellen w\u00e4hlen.</li> <li>Pflichtfelder:</li> <li>Name (z.\u202fB. \u201eOps Team\u201c)</li> <li>Beschreibung (Hilfestellung f\u00fcr Kolleg:innen)</li> <li>Optional Tag-Farbe oder Icon setzen (f\u00fcr bessere \u00dcbersicht in der Benutzerliste).</li> <li>Speichern \u2013 die Gruppe erscheint sofort in der \u00dcbersicht.</li> </ol>"},{"location":"user-guide/groups/#gruppen-bearbeiten","title":"Gruppen bearbeiten","text":"<ul> <li>Zeile anklicken, um das Detailpanel zu \u00f6ffnen.</li> <li>Du kannst Name, Beschreibung und Zugeh\u00f6rige Benutzer (nur Anzeige) sehen.</li> <li>Zum Bearbeiten der Rechte klicke auf Berechtigungen bearbeiten.</li> </ul>"},{"location":"user-guide/groups/#rechte-vergeben","title":"Rechte vergeben","text":"<p>Der Rechte-Dialog zeigt die gesamte Permissionstruktur in Kategorien (Stacks, Logs, Benutzer, Wartung etc.).</p> <ol> <li>W\u00e4hle die gew\u00fcnschte Kategorie aus.</li> <li>Setze f\u00fcr jede Permission einen Level:</li> <li>none \u2013 kein Zugriff</li> <li>read \u2013 Zugriff auf Ansicht/Lesen</li> <li>full \u2013 volle Bearbeitungsrechte</li> <li>Abh\u00e4ngigkeiten werden automatisch hervorgehoben. Beispiel: Um <code>logs-delete</code> nutzen zu d\u00fcrfen, muss <code>logs-access</code> mindestens <code>full</code> sein.</li> <li>Speichern best\u00e4tigt die Anpassungen. StackPulse aktualisiert sofort die effektiven Rechte aller Benutzer in dieser Gruppe.</li> </ol>"},{"location":"user-guide/groups/#benutzer-zu-gruppen-hinzufugen","title":"Benutzer zu Gruppen hinzuf\u00fcgen","text":"<ul> <li>Dies geschieht im Benutzer-Detailpanel (siehe Benutzerverwaltung).</li> <li>Die Liste zeigt alle vorhandenen Gruppen; ein Benutzer kann mehreren Gruppen angeh\u00f6ren.</li> <li>Die effektiven Rechte sind die jeweils h\u00f6chsten Levels aller Gruppen.</li> </ul>"},{"location":"user-guide/groups/#gruppen-loschen","title":"Gruppen l\u00f6schen","text":"<ul> <li>Nur m\u00f6glich, wenn keine Benutzer ausschlie\u00dflich von dieser Gruppe abh\u00e4ngen (es erfolgt ein Warnhinweis).</li> <li>L\u00f6schen entfernt keine Benutzer, aber deren effektive Rechte k\u00f6nnen sich dadurch verringern.</li> </ul>"},{"location":"user-guide/groups/#best-practices","title":"Best Practices","text":"<ul> <li>Erstelle zun\u00e4chst eine Basisgruppe (z.\u202fB. \u201eViewer\u201c) mit <code>read</code>-Rechten f\u00fcr Stacks und Logs.</li> <li>Verwende separate Gruppen f\u00fcr sensible Aktionen wie Wartung oder Superuser-Verwaltung.</li> <li>Nutze sprechende Beschreibungen, damit Kolleg:innen sofort erkennen, wof\u00fcr eine Gruppe gedacht ist.</li> </ul>"},{"location":"user-guide/logs/","title":"Logs-Seite","text":"<p>Die Logs-Seite dient der Nachvollziehbarkeit aller Aktionen (Redeploy, Login, Wartung, Benutzerverwaltung). Sie steht Benutzer:innen mit der Permission <code>logs-access</code> zur Verf\u00fcgung.</p>"},{"location":"user-guide/logs/#uberblick","title":"\u00dcberblick","text":"<ul> <li>Filterleiste mit Suchfeld, Zeitspanne, Kategorie und Status.</li> <li>Tabelle mit Severity-Farben, Nachricht, Zeitstempel und Kontextinformationen.</li> <li>Aktionen oberhalb der Tabelle: Exportieren und L\u00f6schen.</li> </ul>"},{"location":"user-guide/logs/#filtern","title":"Filtern","text":"<ol> <li>Zeitfenster: Datumsfelder \u201eVon\u201c und \u201eBis\u201c setzen. Standardm\u00e4\u00dfig zeigt StackPulse die letzten 24 Stunden.</li> <li>Kategorie/Status: Dropdowns nutzen, um z.\u202fB. <code>redeploy</code> oder <code>wartung</code> auszuw\u00e4hlen.</li> <li>Freitext: Suchfeld durchsucht <code>message</code>, <code>entity_name</code> und <code>metadata</code>.</li> <li>Erweiterte Filter: Klick auf \u201eWeitere Filter\u201c \u00f6ffnet zus\u00e4tzliche Optionen (Actor, Stack-ID, Severity).</li> </ol>"},{"location":"user-guide/logs/#export","title":"Export","text":"<ul> <li>Button CSV exportieren klickst du erst, nachdem die Filter stehen. StackPulse erstellt eine CSV-Datei mit denselben Parametern.</li> <li>Der Download startet im Browser; in containerisierten Umgebungen kannst du denselben Endpoint (<code>/api/logs/export</code>) auch automatisiert aufrufen.</li> </ul>"},{"location":"user-guide/logs/#loschen","title":"L\u00f6schen","text":"<ul> <li>Einzelne Logs: Papierkorb in der Zeile (Permission <code>logs-delete</code>).</li> <li>Batch-L\u00f6schung: Button Gefilterte Eintr\u00e4ge l\u00f6schen; es erscheint ein Sicherheitsdialog mit Zusammenfassung der aktiven Filter.</li> <li>Beachte, dass gel\u00f6schte Logs nicht wiederhergestellt werden k\u00f6nnen.</li> </ul>"},{"location":"user-guide/logs/#detailansicht","title":"Detailansicht","text":"<ul> <li>Klick auf eine Tabellenzeile, um ein Seitenpanel mit vollst\u00e4ndigem JSON (<code>metadata</code>), Kontext (Stack, Benutzer, Quelle) und ggf. Redeploy-Timings zu \u00f6ffnen.</li> <li>\u00dcber Stack \u00f6ffnen gelangst du direkt zur Stacks-Seite mit gesetztem Filter.</li> </ul>"},{"location":"user-guide/maintenance/","title":"Wartungsbereich","text":"<p>Der Wartungsbereich b\u00fcndelt alle Funktionen rund um Maintenance-Mode, Serververwaltung, Update-Skripte und SSH-Verbindungen. Sichtbar f\u00fcr Benutzer:innen mit <code>maintenance-access</code> (Teilbereiche erfordern zus\u00e4tzliche Unterrechte).</p>"},{"location":"user-guide/maintenance/#portainer-status","title":"Portainer-Status","text":"<ul> <li>Klick auf Status pr\u00fcfen, um eine Live-Abfrage gegen Portainer durchzuf\u00fchren. Ergebnis zeigt API-Verf\u00fcgbarkeit, Endpoint-IDs und Auth-Status.</li> <li>H\u00e4ufige Fehler werden direkt erkl\u00e4rt (z.\u202fB. fehlender API-Key oder Netzwerkprobleme).</li> </ul>"},{"location":"user-guide/maintenance/#maintenance-mode","title":"Maintenance-Mode","text":"<ol> <li>Schalter Wartungsmodus aktivieren toggeln.</li> <li>Optionale Nachricht eingeben (z.\u202fB. \u201eUpgrade um 22:00 Uhr\u201c); sie erscheint im gesamten UI als Banner.</li> <li>Aktivieren/Deaktivieren protokolliert automatisch Events in den Logs.</li> </ol>"},{"location":"user-guide/maintenance/#server-api-key-verwalten","title":"Server & API-Key verwalten","text":"<ul> <li>Register \u201eServer\u201c listet alle Portainer-Instanzen.</li> <li>\u00dcber Server hinzuf\u00fcgen kannst du Name + URL erg\u00e4nzen und anschlie\u00dfend API-Key speichern.</li> <li>Buttons in der Tabelle:</li> <li>API-Key aktualisieren \u2013 neues Token einsetzen.</li> <li>Server l\u00f6schen \u2013 nur m\u00f6glich, wenn mindestens ein weiterer Server existiert oder du sofort neue Daten eintr\u00e4gst.</li> </ul>"},{"location":"user-guide/maintenance/#self-stack-id","title":"Self-Stack ID","text":"<ul> <li>Feld \u201eEigener Stack\u201c akzeptiert die Stack-ID, in der StackPulse selbst l\u00e4uft.</li> <li>Nach dem Speichern sind Redeploy-Aktionen f\u00fcr diesen Stack im Dashboard deaktiviert.</li> </ul>"},{"location":"user-guide/maintenance/#ssh-konfiguration","title":"SSH-Konfiguration","text":"<p>Erforderliche Permission: <code>maintenance-ssh-update</code>. 1. Host, Port, Benutzername eintragen. Optional Passwort und zus\u00e4tzliche SSH-Argumente (z.\u202fB. <code>-o StrictHostKeyChecking=no</code>). 2. Passwort wird verschl\u00fcsselt gespeichert; alternativ kannst du Public-Key-Auth nutzen und das Feld leer lassen. 3. Verbindung testen: StackPulse baut eine SSH-Verbindung auf und zeigt das Ergebnis in Echtzeit.</p>"},{"location":"user-guide/maintenance/#update-skript","title":"Update-Skript","text":"<ul> <li>Standard-Skript wird angezeigt und kann als Ausgangspunkt genutzt werden.</li> <li>Eigenes Skript: Inhalt in das Editorfeld kopieren und speichern. StackPulse pr\u00fcft auf leere Zeilen und Basisbefehle.</li> <li>Skript zur\u00fccksetzen entfernt die benutzerdefinierte Variante und stellt den Default wieder her.</li> </ul>"},{"location":"user-guide/maintenance/#portainer-update-auslosen","title":"Portainer-Update ausl\u00f6sen","text":"<ol> <li>Stelle sicher, dass Wartungsmodus aktiv ist und SSH-Konfiguration + Skript korrekt sind.</li> <li>Klicke auf Update starten. Der aktuelle Fortschritt erscheint in einem Logpanel.</li> <li>Der Button bleibt deaktiviert, solange ein Update l\u00e4uft. \u00dcber Status aktualisieren kannst du den Fortschritt erneut abfragen.</li> </ol>"},{"location":"user-guide/maintenance/#fehlerbehandlung","title":"Fehlerbehandlung","text":"<ul> <li>Bei SSH-Fehlern zeigt StackPulse die genaue Ausgabe an. Passe Host/Port/Benutzer oder Skript an.</li> <li>Falls das Update-Skript Probleme verursacht, kannst du es jederzeit stoppen, indem du Portainer manuell pr\u00fcfst und ggf. das Skript anpasst.</li> </ul>"},{"location":"user-guide/setup/","title":"Setup-Assistent","text":"<p>Beim ersten Start erscheint automatisch der Setup-Bereich. Du erreichst ihn sp\u00e4ter jederzeit \u00fcber <code>/setup</code>, solange nicht alle Schritte abgeschlossen sind.</p>"},{"location":"user-guide/setup/#voraussetzungen","title":"Voraussetzungen","text":"<ul> <li>Portainer Business Edition mit g\u00fcltigem API-Key</li> <li>Superuser-Zugangsdaten (entweder schon per Umgebungsvariablen gesetzt oder \u00fcber diesen Assistenten festlegen)</li> </ul>"},{"location":"user-guide/setup/#schritt-1-portainer-server-anlegen","title":"Schritt 1: Portainer-Server anlegen","text":"<ol> <li>Formularfelder Server-URL und optional Name ausf\u00fcllen.</li> <li>URL inkl. Protokoll (z.\u202fB. <code>https://portainer.example.com</code>).</li> <li>Bezeichnung dient ausschlie\u00dflich als Anzeige im Dashboard.</li> <li>Auf Verbindung testen klicken.</li> <li>Erfolgreich: gr\u00fcner Hinweis, die Endpoints werden erkannt.</li> <li>Fehlgeschlagen: Fehlermeldung pr\u00fcfen (h\u00e4ufig Zertifikats-/Firewall-Themen).</li> <li>Mit Speichern & Weiter best\u00e4tigst du den Servereintrag. StackPulse legt ihn verschl\u00fcsselt in SQLite ab.</li> </ol>"},{"location":"user-guide/setup/#schritt-2-api-key-hinterlegen","title":"Schritt 2: API-Key hinterlegen","text":"<ol> <li>API-Key im Feld Portainer API Key einf\u00fcgen.</li> <li>Optional kannst du \u00fcber Stacks laden kontrollieren, ob Portainer Stacks zur\u00fcckliefert.</li> <li>Mit Speichern wird der Schl\u00fcssel verschl\u00fcsselt gespeichert. Du kannst ihn sp\u00e4ter im Maintenance-Bereich austauschen.</li> </ol>"},{"location":"user-guide/setup/#schritt-3-superuser-registrieren","title":"Schritt 3: Superuser registrieren","text":"<ol> <li>Falls du <code>SUPERUSER_*</code> Variablen gesetzt hast, zeigt StackPulse an, dass bereits ein Superuser existiert \u2013 du kannst direkt weiter.</li> <li>Ansonsten Benutzername, E-Mail und Passwort vergeben. Das Passwort dient nur f\u00fcr diesen Account; weitere Benutzer folgen sp\u00e4ter.</li> <li>Auf Superuser anlegen klicken. Nach Erfolg wird der Login-Button eingeblendet.</li> </ol>"},{"location":"user-guide/setup/#abschluss-login","title":"Abschluss & Login","text":"<ul> <li>Sobald alle drei Schritte abgeschlossen sind, erscheint die Schaltfl\u00e4che Zum Login.</li> <li>Melde dich mit dem Superuser an. StackPulse legt im Hintergrund initiale Berechtigungen, Default-Gruppen und Sicherheitspassphrasen an.</li> </ul>"},{"location":"user-guide/setup/#setup-wiederholen-oder-andern","title":"Setup wiederholen oder \u00e4ndern","text":"<ul> <li>\u00dcber das Dashboard \u2192 Wartung \u2192 Abschnitt Serververwaltung kannst du zus\u00e4tzliche Portainer-Server hinzuf\u00fcgen oder entfernen.</li> <li>Superuser l\u00e4sst sich im Bereich Benutzer l\u00f6schen, sofern du <code>maintenance-superuser-delete</code> besitzt.</li> <li>Der Self-Stack (StackPulse-eigener Stack) kann in der Wartung gepflegt werden, damit er nicht versehentlich redeployed wird.</li> </ul>"},{"location":"user-guide/stacks/","title":"Stacks-Seite","text":"<p>Die Stacks-Ansicht ist der Startpunkt nach dem Login und liefert einen \u00dcberblick \u00fcber alle Stacks der angebundenen Portainer-Instanz.</p>"},{"location":"user-guide/stacks/#aufbau","title":"Aufbau","text":"<ul> <li>Header mit Suchfeld, Filterchips f\u00fcr Status sowie Buttons f\u00fcr Redeploy-Aktionen.</li> <li>Tabelle mit Name, Endpoint, Status, letzte Aktion, Redeploy-Status und verf\u00fcgbaren Buttons.</li> <li>Live-Status: \u00dcber Socket.IO wird jede Ver\u00e4nderung (queued/started/success/error) sofort eingeblendet.</li> </ul>"},{"location":"user-guide/stacks/#filter-suche","title":"Filter & Suche","text":"<ol> <li>Verwende das Suchfeld oben rechts, um nach Namen oder IDs zu filtern.</li> <li>Statuschips (z.\u202fB. \u201erunning\u201c, \u201ewarning\u201c) toggeln per Klick und lassen sich kombinieren.</li> <li>\u00dcber die Spaltenk\u00f6pfe kannst du sortieren; ein erneuter Klick kehrt die Reihenfolge um.</li> </ol>"},{"location":"user-guide/stacks/#redeploy-aktionen","title":"Redeploy-Aktionen","text":"Aktion Voraussetzung Vorgehen Einzelner Stack Permission <code>stacks-redeploy-single</code> Button Redeploy in der jeweiligen Zeile klicken und best\u00e4tigen. Mehrere Stacks <code>stacks-redeploy-selection</code> Checkboxen der gew\u00fcnschten Stacks aktivieren, anschlie\u00dfend Redeploy Auswahl. Alle Stacks <code>stacks-redeploy-all</code> Button Redeploy alle ausl\u00f6sen. Nutze vorher Filter, um sicherzugehen, dass alle Stacks korrekt angezeigt werden. <p>W\u00e4hrend eines Redeploys erscheint pro Stack ein Fortschrittsbadge. Du kannst das Panel schlie\u00dfen; beim n\u00e4chsten Besuch wird der aktuelle Status aus dem Backend gelesen.</p>"},{"location":"user-guide/stacks/#redeploy-status-verstehen","title":"Redeploy-Status verstehen","text":"<ul> <li>Queued \u2013 Auftrag ist vorgemerkt.</li> <li>Started \u2013 Portainer verarbeitet Redeploy.</li> <li>Success \u2013 Vorgang erfolgreich abgeschlossen.</li> <li>Error \u2013 Fehlerdetails findest du in der Logs-Seite.</li> <li>Info \u2013 Informative Hinweise, etwa wenn Portainer einen Stack \u00fcberspringt.</li> </ul>"},{"location":"user-guide/stacks/#selbstschutz","title":"Selbstschutz","text":"<ul> <li>Falls du die Variable <code>SELF_STACK_ID</code> gesetzt hast, markiert StackPulse den eigenen Stack als \u201egesch\u00fctzt\u201c. Redeploy-Buttons werden deaktiviert und mit einem Info-Tooltip versehen.</li> </ul>"},{"location":"user-guide/stacks/#troubleshooting-aus-der-ansicht","title":"Troubleshooting aus der Ansicht","text":"<ul> <li>Klicke auf das Warnsymbol in der Tabellenzeile, um Fehlerdetails einzublenden.</li> <li>Nutze den Link \u201eZu Logs springen\u201c, der direkt eine gefilterte Ansicht in der Log-Seite \u00f6ffnet (Stack-ID ist vorausgew\u00e4hlt).</li> </ul>"},{"location":"user-guide/users/","title":"Benutzerverwaltung","text":"<p>Die Benutzerseite erm\u00f6glicht das Anlegen, Bearbeiten und Deaktivieren von Konten. Du ben\u00f6tigst mindestens die Permission <code>users-access</code> (lesen) bzw. <code>users-edit</code>/<code>users-delete</code> f\u00fcr \u00c4nderungen.</p>"},{"location":"user-guide/users/#benutzer-anlegen","title":"Benutzer anlegen","text":"<ol> <li>Button Benutzer anlegen klicken.</li> <li>Formularfelder ausf\u00fcllen:</li> <li>Benutzername (eindeutig, wird f\u00fcr Login genutzt)</li> <li>Anzeigename (optional)</li> <li>E-Mail-Adresse</li> <li>Passwort (kann sp\u00e4ter ge\u00e4ndert werden)</li> <li>Gruppen ausw\u00e4hlen (siehe Abschnitt \u201eBenutzergruppen\u201c)</li> <li>Optional: Benutzer sofort aktivieren/deaktivieren.</li> <li>Mit Speichern best\u00e4tigen. Der Benutzer erscheint in der Tabelle und erh\u00e4lt automatisch eine Sicherheitspassphrase.</li> </ol>"},{"location":"user-guide/users/#benutzer-bearbeiten","title":"Benutzer bearbeiten","text":"<ul> <li>In der Tabelle auf eine Zeile klicken, um das Detailpanel zu \u00f6ffnen.</li> <li>Du kannst Anzeigename, E-Mail, Passwort und Gruppen \u00e4ndern.</li> <li>\u00c4nderungen an Gruppen erfordern <code>users-edit</code> sowie Gruppenrechte (<code>user-groups-access</code>).</li> </ul>"},{"location":"user-guide/users/#konto-deaktivierenreaktivieren","title":"Konto deaktivieren/reaktivieren","text":"<ul> <li>Toggle Aktiv im Detailpanel.</li> <li>Deaktivierte Konten k\u00f6nnen sich nicht mehr anmelden, bleiben aber in der Historie.</li> </ul>"},{"location":"user-guide/users/#sicherheitspassphrase","title":"Sicherheitspassphrase","text":"<ol> <li>Button Sicherheitspassphrase anzeigen im Detailpanel.</li> <li>StackPulse zeigt einen QR-Code und den alphanumerischen Code. Dieser wird nur einmal angezeigt, bis du best\u00e4tigst, dass er heruntergeladen wurde.</li> <li>\u00dcber Neu generieren kannst du eine neue Phrase erstellen (Permission <code>users-security-phrase</code>). Informiere den Benutzer \u00fcber die neue Phrase und markiere anschlie\u00dfend \u201eheruntergeladen\u201c.</li> </ol>"},{"location":"user-guide/users/#passwort-zurucksetzen","title":"Passwort zur\u00fccksetzen","text":"<ul> <li>Admins k\u00f6nnen direkt im Detailpanel ein neues Passwort setzen.</li> <li>Benutzer:innen selbst nutzen die Auth-Seite \u201ePasswort vergessen\u201c: Sie geben Username + Sicherheitsphrase ein und definieren anschlie\u00dfend ein neues Passwort.</li> </ul>"},{"location":"user-guide/users/#suche-filter","title":"Suche & Filter","text":"<ul> <li>Nutze das Suchfeld, um nach Benutzername oder E-Mail zu suchen.</li> <li>Filterchips f\u00fcr Status (aktiv/inaktiv) erleichtern das Auffinden gesperrter Accounts.</li> </ul>"},{"location":"user-guide/users/#massenaktionen","title":"Massenaktionen","text":"<ul> <li>Mehrfachauswahl (Checkboxen) erlaubt das gleichzeitige Aktivieren/Deaktivieren oder L\u00f6schen mehrerer Benutzer. Vorsicht: L\u00f6schen entfernt auch Audit-Verweise.</li> </ul>"}]} |