This commit is contained in:
2025-12-01 07:59:40 +00:00
parent fc3ed57a40
commit f109423f54
39 changed files with 2914 additions and 2958 deletions
+8 -3
View File
@@ -8,13 +8,18 @@ StackPulse folgt einer klassischen Client/Server-Architektur, bei der das Backen
│ (React) │ ◀───── Auth-Cookie + JSON ─ │ (Express) │ ◀─────────────── │ Business Ed. │
└────────────┘ Redeploy Events └───────────────┘ (Axios Proxy) └────────────────┘
mTLS (optional)│
StackPulse Agent
SQLite Datenbank
```
## Hauptschichten
- **Frontend** (Vite + Material Tailwind): stellt alle Views, Formulare, Tabellen und Echtzeit-Widgets bereit. Die `AuthProvider`-Komponente verwaltet Session, Permissions und Socket-Verbindungen.
- **Backend** (Express + better-sqlite3): aggregiert Daten aus Portainer, persistiert Benutzer/Gruppen/Logs, verwaltet Sessions und stößt Redeploy- sowie Wartungsprozesse an.
- **Frontend** (Vite + Material Tailwind): stellt Views, Tabellen, Setup-Wizard und Echtzeit-Widgets bereit. `AuthProvider` verwaltet Session, Permissions und Socket-Verbindungen.
- **Backend** (Express + better-sqlite3): aggregiert Daten aus Portainer, persistiert Benutzer/Gruppen/Logs, verwaltet Sessions, Redeploy-Queue und Maintenance/Agent-Funktionen.
- **Agent (optional)**: kleiner Node-Dienst, der lokal auf dem Portainer-Host läuft. Liefert Stack-/Portainer-Metadaten per REST, authentifiziert via `X-Agent-Token` und kann mTLS-Zertifikate aus dem Backend beziehen.
- **Persistenz** (SQLite): Datei `backend/data/stackpulse.db`, WAL-Modus aktiviert. Tabellen umfassen u. a. `users`, `groups`, `permissions`, `servers`, `server_api_keys`, `event_logs`, `settings` sowie Hilfstabellen für Tokens und Sicherheitspassphrasen.
## Datenflüsse
@@ -23,7 +28,7 @@ StackPulse folgt einer klassischen Client/Server-Architektur, bei der das Backen
3. **Stack-Übersicht**: Frontend ruft `/api/stacks` auf. Das Backend proxyt `Portainer /api/endpoints/:id/docker/stacks`, ergänzt Caching, interne Metadaten und liefert Redeploy-Status.
4. **Redeploy**: UI stößt `/api/stacks/:id/redeploy`, `/api/stacks/redeploy-selection` oder `/api/stacks/redeploy-all` an. Das Backend ruft Portainer-Endpoints, protokolliert Events und broadcastet Fortschritt via Socket.IO `redeployStatus`.
5. **Logging**: Jeder relevante Vorgang erzeugt Einträge in `event_logs` (siehe `logging/eventLogs.js`). Frontend filtert/paginiert über `/api/logs` und kann Exporte `/api/logs/export` herunterladen.
6. **Wartung**: `/api/maintenance/*` verwaltet Maintenance-Mode, SSH-Zugänge, Update-Skripte und serverseitige Settings (`db/settings.js`).
6. **Wartung**: `/api/maintenance/*` verwaltet Maintenance-Mode, SSH-Zugänge, Update-Skripte sowie weitere Wartungsfunktionen.
## Verzeichnis-Referenz
| Pfad | Inhalt |
+10 -9
View File
@@ -11,10 +11,10 @@ Das Backend implementiert alle Anwendungsfälle über Express-Routen, Socket.IO
| Modul | Pfad | Aufgabe |
|-------|------|---------|
| Auth/Superuser | `auth/superuser.js` | Registrieren/Verifizieren von Superusern, Login, Passwortvalidierung, Sicherheitsphrasen. |
| Users & Groups | `users/*`, `groups/*`, `permissions/*` | CRUD für Benutzer, Gruppen, Rechtezuweisung, Ableitung effektiver Berechtigungen. |
| Users & Groups | `users/*`, `groups/*`, `permissions/*` | CRUD für Benutzer, Gruppen, Rechtezuweisung, Ableitung effektiver Berechtigungen. Rechte-Labels z.B. `Bereich & Navigation`, `Benutzergruppen bearbeiten`, `Benutzer löschen`. |
| Setup | `setup/index.js` | Verwaltung registrierter Portainer-Server, sichere Ablage der API-Keys, Setup-Status. |
| Logging | `logging/eventLogs.js` | Einheitliches Ereignislogging (Insert, Filter, Delete, Export). |
| Maintenance | `maintenance/state.js` + helper in `index.js` | Wartungsmodus, SSH-Konfiguration, Update-Skripte und Ausführung. |
| Maintenance | `maintenance/state.js` + Helper in `index.js` | Wartungsmodus, SSH-Konfiguration, Update-Skripte und Ausführung. |
| Portainer Proxy | Funktionen in `index.js` | Kommunikation mit Portainer (`axiosInstance` + dynamische `baseURL`), Environment-Erkennung und Redeploy-Strecke. |
## API-Überblick (Auszug)
@@ -56,7 +56,7 @@ Das Backend implementiert alle Anwendungsfälle über Express-Routen, Socket.IO
| GET | `/api/stacks` | Aggregierte Liste inkl. Filter, Self-Stack-Blockade und Redeploy-Status. |
| PUT | `/api/stacks/:id/redeploy` | Redeploy eines einzelnen Stacks. |
| PUT | `/api/stacks/redeploy-selection` | Redeploy einer Liste übermittelter `stackIds`. |
| PUT | `/api/stacks/redeploy-all` | Redeploy aller Stacks (Permission `stacks-redeploy-all`). |
| PUT | `/api/stacks/redeploy-all` | Redeploy aller Stacks (Recht `Redeploy Alle`). |
Das Backend veröffentlicht den Redeploy-Fortschritt parallel über Socket.IO (`redeployStatus` Event) und unterscheidet die Phasen `queued`, `started`, `success`, `error`, `info`.
@@ -75,7 +75,7 @@ Das Backend veröffentlicht den Redeploy-Fortschritt parallel über Socket.IO (`
## Datenbank & Schema
- `ensureDatabaseSchema()` erzeugt Tabellen bei jedem Start, inklusive Default-Gruppen, Permissions, Settings, Server-Einträge und Trigger.
- Permissions werden anhand der Blueprint-Datei `backend/db/dbs` eingelesen. Jede Permission definiert Key, Label, Level (`full`, `read`, `none`) und Abhängigkeiten.
- Permissions werden anhand der Blueprint-Datei `backend/db/dbs` eingelesen. Jede Permission definiert Key, Label (z.B. `Bereich & Navigation`, `Server bearbeiten`, `SSH/Update-Skript`, `Update durchführen`, `Doppelte Stacks`), Level (`full`, `read`, `none`) und Abhängigkeiten.
- Events werden in `event_logs` gespeichert. Relevante Felder:
- `category`, `event_type`, `action`, `status`, `severity`
- `entity_type`, `entity_id`, `entity_name`
@@ -85,13 +85,14 @@ Das Backend veröffentlicht den Redeploy-Fortschritt parallel über Socket.IO (`
- Filter-Parameter (`ids`, `categories`, `eventTypes`, `status`, `stackIds`, Zeitfenster) werden in `buildEventLogFilter` zentral verarbeitet.
## Berechtigungssystem
- Jeder Benutzer gehört zu beliebig vielen Gruppen; die effektiven Rechte ergeben sich aus der höchsten Ausprägung pro Permission.
- Jeder Benutzer gehört zu beliebig vielen Gruppen; die effektiven Rechte ergeben sich aus der höchsten Ausprägung pro Permission (Labels wie `Bereich & Navigation`, `Server bearbeiten`, `SSH/Update-Skript`, `Update durchführen`, `Doppelte Stacks`).
- Superuser erhalten alle Berechtigungen und können nicht über das UI entzogen werden.
- `PermissionGate` im Frontend spiegelt die gleichen Keys. Wichtigste Bereiche:
- `stacks-*` (Redeploy)
- `logs-*`
- `users-*` & `user-groups-*`
- `maintenance-*` (inkl. Unterrechte `maintenance-server-*`, `maintenance-ssh-update`, `maintenance-update`)
- `Redeploy einzeln/Auswahl/Alle`
- `Bereich & Navigation (Logs)`, `Logs Exportieren`, `Logs löschen`
- `Bereich & Navigation (Benutzer)`, `Benutzer bearbeiten/löschen`, `Sicherheitsschlüssel`
- `Bereich & Navigation (Benutzergruppen)`, `Benutzergruppen bearbeiten/löschen`
- Wartung: `Bereich & Navigation (Wartung)`, `Server-Sektion`, `Server bearbeiten/löschen`, `SSH/Update-Skript`, `Update durchführen`, `Doppelte Stacks`
## Redeploy-Workflow
1. Eingehender Request wird mit `maintenanceGuard` geprüft (Maintenance-Modus blockiert optional Redeploys).
+59
View File
@@ -0,0 +1,59 @@
# Umgebungsvariablen
Diese Seite sammelt alle relevanten Umgebungsvariablen für StackPulse (Backend) und den optionalen StackPulse Agent. Werte ohne Default sind in der Regel optional, sofern sie nicht explizit als „erforderlich“ markiert sind.
## StackPulse Backend
| Variable | Default | Erforderlich | Beschreibung |
|----------|---------|--------------|--------------|
| `PORTAINER_URL` | | Nein | Basis-URL zu Portainer. Kann im Setup-UI hinterlegt werden; ohne Wert schlägt Portainer-Zugriff fehl, bis ein Server gespeichert ist. |
| `PORTAINER_API_KEY` | | Nein | API-Key für Portainer. Kann im Setup-UI gespeichert (verschlüsselt) werden; ohne Wert keine API-Aufrufe. |
| `PORTAINER_SERVER_NAME` | | Nein | Anzeigename für den initialen Servereintrag (nur kosmetisch). |
| `PORTAINER_API_SECRET` | `stackpulse-portainer-api-key` | Nein | AES-Schlüssel für gespeicherte API-Keys. Stabil halten, sonst müssen Keys neu eingetragen werden. |
| `SUPERUSER_USERNAME` | | Nein | Legt beim Start einen Superuser an, falls noch keiner existiert; alternativ im Setup-UI anlegen. |
| `SUPERUSER_EMAIL` | | Nein | E-Mail des initialen Superusers. |
| `SUPERUSER_PASSWORD` | | Nein | Passwort des initialen Superusers. |
| `SELF_STACK_ID` | | Nein | ID des StackPulse-Stacks; verhindert Self-Redeploy im UI. |
| `AUTH_COOKIE_NAME` | `sp_auth_token` | Nein | Name des Auth-Cookies. |
| `AUTH_SESSION_TTL_MS` | `43200000` (12h) | Nein | Session-Lebensdauer in Millisekunden. |
| `AUTH_COOKIE_SECURE` | `false` | Nein | Setzt Cookie nur über HTTPS, wenn `true`. |
| `SECURITY_PHRASE_SECRET` | `stackpulse-security-phrase-secret` | Nein | Secret für verschlüsselte Sicherheitsphrasen; stabil halten, sonst Phrasen neu verteilen. |
| `PORTAINER_SSH_SECRET` | (Fallback API-Key/Default) | Nein | Secret für verschlüsselte SSH-Passwörter; stabil halten, sonst Passwort neu setzen. |
| `AGENT_MTLS_KEY` | generiert | Nein | Optional: eigenes PEM-Key für internen mTLS-Server, falls nicht automatisch erzeugt. |
| `AGENT_MTLS_CERT` | generiert | Nein | Optional: eigenes PEM-Zertifikat für internen mTLS-Server. |
| `AGENT_MTLS_PORT` | `4441` | Nein | Port des internen mTLS-Endpunkts (Agent). |
| `DISPLAY` | `:9999` | Nein | Wird an Child-Prozesse (Update-Skript) weitergereicht. |
## StackPulse Agent
| Variable | Default | Erforderlich | Beschreibung |
|----------|---------|--------------|--------------|
| `AGENT_PORT` | `7070` | Nein | Listenport des Agents (HTTPS mit mTLS). |
| `AGENT_TOKEN` | | Ja | Shared Secret für Auth (`X-Agent-Token`) bei allen Agent-Endpoints. |
| `DOCKER_SOCKET` | `/var/run/docker.sock` | Nein | Pfad zum Docker-Socket; nötig für Stack-/Image-Infos. |
| `CONTROL_PLANE_URL` | | Ja (für Bootstrap/Restore) | Basis-URL des StackPulse-Backends für Zertifikatsabruf ohne mTLS (z.B. `https://stackpulse:4001`). |
| `CONTROL_PLANE_MTLS_URL` | | Nein (empfohlen) | Bevorzugte mTLS-URL des Backends (z.B. `https://stackpulse:4441`). Wird für alle Agent→Backend-Calls genutzt, sobald Zertifikate vorliegen; fehlt sie, wird aus `CONTROL_PLANE_URL` + `AGENT_MTLS_PORT` abgeleitet. |
| `AGENT_BOOTSTRAP_TOKEN` | | Nein (für Erstbootstrap) | Einmal-Token aus dem Wartungsbereich, um mTLS-Zertifikate zu ziehen. Pflicht, wenn keine Zertifikate vorliegen und das Backend noch kein Material für den Agent gespeichert hat. |
| `AGENT_MTLS_PORT` | `4441` | Nein | Fallback-Port, falls `CONTROL_PLANE_MTLS_URL` keinen Port enthält. |
| `AGENT_SERVER_KEY` / `AGENT_SERVER_CERT` | | Nein | PEM-Material für den Agent-Server; nur nötig bei eigenen Zertifikaten statt Backend-CA. |
| `AGENT_CLIENT_KEY` / `AGENT_CLIENT_CERT` / `AGENT_CA_CERT` | | Nein | PEM-Material für Client/CA; nur bei eigener PKI nötig. |
| `REGISTRY_TOKEN` | | Nein | Bearer-Token für Registry-Abfragen (Digest-Vergleich). |
| `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` | | Nein | Basic-Auth-Creds für Registries. |
| `GITHUB_USERNAME` / `GITHUB_TOKEN` / `GITHUB_PAT` | | Nein | Alternative Credential-Quellen für GitHub Packages. |
Agent-Betrieb (wähle eine Variante):
- **Dynamisch über Backend (empfohlen)**
- Pflicht: `AGENT_TOKEN` + `CONTROL_PLANE_URL` (optional `CONTROL_PLANE_MTLS_URL`).
- Falls keine Zertifikate existieren: einmaliges `AGENT_BOOTSTRAP_TOKEN` setzen.
- Der Agent zieht Zertifikate vom Backend, schaltet auf mTLS um und braucht danach kein Bootstrap-Token mehr.
- **Statisch per ENV**
- Liefere PEMs: `AGENT_SERVER_KEY`/`AGENT_SERVER_CERT` + `AGENT_CLIENT_KEY`/`AGENT_CLIENT_CERT`/`AGENT_CA_CERT`.
- Dann kein `CONTROL_PLANE_URL`/Bootstrap nötig, da mTLS-Material bereits vorhanden ist.
- `AGENT_TOKEN` bleibt erforderlich.
Hinweise:
- Server-URL und API-Key kannst du im Setup-UI pflegen; Umgebungsvariablen setzen nur den Initialzustand.
- Secrets (`SECURITY_PHRASE_SECRET`, `PORTAINER_SSH_SECRET`, `PORTAINER_API_SECRET`) in Produktion einmalig setzen und stabil halten sonst werden bestehende verschlüsselte Werte unlesbar.
- `CONTROL_PLANE_MTLS_URL`: bevorzugte mTLS-Zieladresse. Fehlt sie, leitet der Agent sie aus `CONTROL_PLANE_URL` + `AGENT_MTLS_PORT` ab und nutzt sie für alle Aufrufe, sobald Zertifikate vorliegen.
+44 -68
View File
@@ -1,80 +1,61 @@
# Getting Started
Dieser Leitfaden hilft dir, StackPulse lokal oder als Container aufzusetzen und die ersten Schritte im UI abzuschließen.
Dieser Leitfaden beschreibt ausschließlich den Docker-Deploy über die bereitgestellten GHCR-Images und die anschließende Einrichtung im UI.
## Voraussetzungen
- Node.js **>= 20** und npm für lokale Entwicklung
- Docker & Docker Compose (optional aber empfohlen für Deployment)
- Zugriff auf eine **Portainer Business Edition** samt API-Key
- Shell-Zugang zum Host, auf dem StackPulse laufen soll
- Docker & Docker Compose
- Portainer-Instanz (Business Edition empfohlen; bei Community/Edge zusätzlich Agent einsetzen)
## Repository & Abhängigkeiten
```bash
# Repository klonen
# git clone <repo-url>
cd stackpulse
## Zentrale Umgebungsvariablen (Kurzfassung)
| Variable | Erforderlich | Beschreibung |
|----------|--------------|--------------|
| `PORTAINER_URL` | Nein | Basis-URL zu Portainer; kann im Setup-UI hinterlegt werden, falls nicht gesetzt. |
| `PORTAINER_API_KEY` | Nein | API-Key; kann im Setup gespeichert werden (wird verschlüsselt). |
| `PORTAINER_SERVER_NAME` | Nein | Anzeige-Name für den initialen Servereintrag. |
| `PORTAINER_API_SECRET` | Nein | AES-Schlüssel für gespeicherte API-Keys; setze stabilen Wert, sonst muss der Key neu eingegeben werden. |
| `SUPERUSER_USERNAME`, `SUPERUSER_EMAIL`, `SUPERUSER_PASSWORD` | Nein | Legt automatisch einen Superuser an, falls noch keiner existiert; sonst im Setup-UI anlegen. |
| `SELF_STACK_ID` | Nein | ID des StackPulse-Stacks; schützt vor Self-Redeploy. |
| `AUTH_COOKIE_NAME`, `AUTH_SESSION_TTL_MS`, `AUTH_COOKIE_SECURE` | Nein | Session/Cookie-Tuning (Name, Dauer, Secure-Flag). |
| `SECURITY_PHRASE_SECRET` | Nein | Secret für verschlüsselte Sicherheitsphrasen; stabil halten, sonst Phrasen neu verteilen. |
| `PORTAINER_SSH_SECRET` | Nein | Secret für verschlüsselte SSH-Passwörter; stabil halten, sonst Passwort neu setzen. |
| `DISPLAY` | Nein | Wird an Update-Childprozesse weitergereicht (Default `:9999`). |
# Skript ausführbar machen
chmod +x scripts/start-dev.sh
```
Weitere Variablen (Agent, Registry, mTLS) findest du im Detail unter [Umgebungsvariablen](environment.md). Einstellungen wie Server-URL/API-Key, SSH-Config oder Update-Skript kannst du alternativ im UI (Setup/Wartung) verwalten.
## Lokale Dev-Umgebung
Das Skript `scripts/start-dev.sh` richtet Backend und Frontend automatisch ein:
1. Backend: `npm install`, `npm run migrate` (erstellt/aktualisiert `backend/data/stackpulse.db`), `npm start`
2. Frontend: `npm install`, `npm run dev` (Port 5173) und ein einmaliges `npm run build`, um statische Assets ins Backend zu spiegeln
Nach erfolgreichem Start:
- Frontend dev server: http://localhost:5173
- Backend API & statische Assets: http://localhost:4001
Zum Stoppen STRG+C verwenden.
## Manuelles Starten
```bash
# Backend
cd backend
npm install
npm run migrate
PORTAINER_URL=https://portainer.local npm start
# Frontend in zweiter Shell
cd frontend
npm install
npm run dev
```
Das Backend liest Umgebungsvariablen beim Start. Alternativ kannst du eine `.env` neben `backend/index.js` anlegen.
## Zentrale Umgebungsvariablen
| Variable | Beschreibung |
|----------|--------------|
| `PORTAINER_URL` | Basis-URL zu deiner Portainer-Instanz (inkl. Protokoll). Kann später im Setup-UI überschrieben werden. |
| `PORTAINER_API_KEY` | API-Key für Portainer. Wird in der DB verschlüsselt abgelegt, sobald du ihn im Setup speicherst. |
| `PORTAINER_SERVER_NAME` | Optionaler Anzeigename für den Server während des Setups. |
| `PORTAINER_API_SECRET` | Überschreibt den Schlüssel, der zur Verschlüsselung des API-Keys verwendet wird. |
| `SUPERUSER_USERNAME`, `SUPERUSER_EMAIL`, `SUPERUSER_PASSWORD` | Legt einen Superuser automatisch beim Start an (falls nicht vorhanden). |
| `SELF_STACK_ID` | Stack-ID von StackPulse selbst. Wird genutzt, um eigene Redeploys zu blockieren. |
| `AUTH_COOKIE_NAME`, `AUTH_SESSION_TTL_MS`, `AUTH_COOKIE_SECURE` | Feintuning für die Session-Verwaltung der API. |
| `SECURITY_PHRASE_SECRET` | Seed für die Generierung kryptografischer Sicherheitsphrasen. |
| `PORTAINER_SSH_SECRET` | Secret für SSH-Passwortverschlüsselung (Wartungs-Update). |
| `DISPLAY` | Wird an Kindprozesse weitergereicht, wenn Portainer-Updates ausgelöst werden müssen (Default `:9999`). |
Weitere Einstellungen (SSH-Config, Update-Skripte) verwaltest du später direkt im Maintenance-Bereich des UI.
**Hinweis zu Secrets:**
- `SECURITY_PHRASE_SECRET` und `PORTAINER_SSH_SECRET` steuern die AES-256-GCM-Verschlüsselung von Sicherheitsphrasen bzw. hinterlegten SSH-Passwörtern.
- Wenn sie nicht gesetzt sind, nutzt StackPulse fixe Fallbacks (`stackpulse-security-phrase-secret` bzw. `stackpulse-portainer-ssh-secret` / API-Key). Setze in Produktion eigene, stabile Werte ein späterer Secret-Wechsel macht zuvor gespeicherte Phrasen/Passwörter unlesbar.
- Eine vollständige Übersicht aller Variablen (inkl. Agent) findest du unter „Technik → Umgebungsvariablen“.
## Ersteinrichtung im UI
1. Öffne das Frontend (`/setup` führt dich automatisch durch den Wizard).
2. Lege den Portainer-Server und den zugehörigen API-Key an StackPulse testet die Verbindung per `/api/setup/test-portainer`.
1. Öffne das Frontend.
2. Lege den Portainer-Server und den zugehörigen API-Key an (der Wizard führt durch den Test).
3. Registriere einen Superuser oder verwende den per Umgebungsvariablen automatisch angelegten Account.
4. Nach erfolgreicher Einrichtung kannst du dich anmelden und erhältst Zugriff auf Dashboard, Logs, Benutzer & Wartung.
## Docker-Deployment
## Docker Run (Single Container)
```bash
docker run -d \
-p 4001:4001 \
-e PORTAINER_URL=https://portainer.example.com \
-e PORTAINER_API_KEY=xxxx \
-e SUPERUSER_USERNAME=admin \
-e SUPERUSER_EMAIL=admin@example.com \
-e SUPERUSER_PASSWORD=changeme \
-e SELF_STACK_ID=123 \
-e SECURITY_PHRASE_SECRET=$(openssl rand -hex 32) \
-e PORTAINER_SSH_SECRET=$(openssl rand -hex 32) \
-v stackpulse_data:/app/backend/data \
ghcr.io/mboehmlaender/stackpulse:latest
```
Das Volume `stackpulse_data` persistiert die SQLite-Datenbank. Passen Sie Secrets und Ports an Ihre Umgebung an; weitere Variablen siehe Kapitel „Umgebungsvariablen“.
## Docker-Deployment (Compose)
```yaml
# docker-compose.yml (Auszug)
services:
app:
build:
context: .
dockerfile: Dockerfile
image: ghcr.io/mboehmlaender/stackpulse:latest
ports:
- "4001:4001"
volumes:
@@ -91,13 +72,8 @@ volumes:
stackpulse_data:
```
1. `docker compose up -d --build`
2. Das Frontend ist anschließend unter Port 4001 (via Backend `public/`) erreichbar.
1. `docker compose up -d`
2. Das Frontend ist anschließend unter Port 4001 erreichbar.
3. Datenbank & Einstellungen liegen im benannten Volume `stackpulse_data`.
## Datenbank & Migration
- Datei: `backend/data/stackpulse.db`
- Migration: `npm run migrate` (führt `backend/db/ensure.js` aus und erzeugt Schema, Rechte, Defaults)
- Backup: Datei oder Volume regelmäßig sichern; enthält Benutzer, Logs und gespeicherte Secrets.
Damit bist du bereit für die tieferen Kapitel zu Architektur sowie Backend- und Frontend-Details.
+1
View File
@@ -8,6 +8,7 @@ StackPulse ist eine eigenständige Web-Anwendung, die die Portainer Business Edi
- **Auditierbare Historie** durch strukturierte Event-Logs mit Export-, Lösch- und Filterfunktionen
- **Feingranulare Rechteverwaltung** mit Gruppenrechten, Superuser-Handling und Sicherheitsphrasen
- **Wartungsautomatisierung** (SSH Update-Skripte, Maintenance-Mode) ohne direkten Portainer-Zugang
- **Agent-Integration** (mTLS) für Portainer Community/Edge, um Stacks & Versionen auch ohne Business-API auszulesen
- **Bereitstellung als Docker-Image** sowie als lokale Dev-Umgebung via `scripts/start-dev.sh`
## Technische Eckdaten
+53
View File
@@ -0,0 +1,53 @@
# Lokale Entwicklung & Migration
Dieser Abschnitt richtet sich an Contributor:innen, die StackPulse lokal bauen oder erweitern möchten. Für produktive Deployments nutze die GHCR-Images wie im Getting Started beschrieben.
## Voraussetzungen
- Node.js **>= 20** und npm
- Shell-Zugang zum Host
- Docker (optional) für lokale Tests
## Repository vorbereiten
```bash
# Repository klonen
# git clone <repo-url>
cd stackpulse
# Startskript ausführbar machen
chmod +x scripts/start-dev.sh
```
## Schnellstart (Dev-Skript)
Das Skript `scripts/start-dev.sh` richtet Backend und Frontend ein und startet beide im Dev-Modus:
1. Backend: `npm install`, `npm run migrate`, `npm start`
2. Frontend: `npm install`, `npm run dev` (Port 5173) und einmalig `npm run build` für statische Assets
Nach dem Start:
- Frontend Dev Server: http://localhost:5173
- Backend API & statische Assets: http://localhost:4001
Stoppen mit `STRG+C` in der Shell, in der das Skript läuft.
## Manuelles Starten
```bash
# Backend
cd backend
npm install
npm run migrate
PORTAINER_URL=https://portainer.local npm start
# Frontend (zweite Shell)
cd frontend
npm install
npm run dev
```
Das Backend liest Umgebungsvariablen beim Start. Alternativ kannst du eine `.env` neben `backend/index.js` anlegen.
## Datenbank & Migration
- Datei: `backend/data/stackpulse.db` (SQLite, WAL aktiviert)
- Migration: `npm run migrate` (führt `backend/db/ensure.js` aus, erzeugt/aktualisiert Schema & Defaults)
- Backup: Datei oder Volume regelmäßig sichern; enthält Benutzer, Logs und gespeicherte Secrets
## Hinweise
- Die lokalen Builds sind für Entwicklung gedacht. Für Deployments verwende `ghcr.io/mboehmlaender/stackpulse`.
- Einige Einstellungen (z.B. Server-URL, API-Key, SSH-Config) kannst du im UI setzen; für lokale Tests reichen die ENV-Defaults und das Setup-UI.
+6 -2
View File
@@ -2,6 +2,10 @@
Dieser Abschnitt deckt typische Aufgaben für Betriebsteams ab von Backups über Wartungsmodus bis zu Störungssuche.
**Relevante Rechte**
- `Superuser löschen`
- `Bereich & Navigation (Wartung)`
## Laufender Betrieb
- **Services überwachen**: StackPulse stellt nur einen Prozess bereit (Node.js/Express). Nutze Systemd/Docker Healthchecks, indem du regelmäßig `/api/auth/session` (für Auth) oder `/api/maintenance/update-status` (für Backend + DB) abfragst.
- **Ports**: Standardmäßig lauscht nur Port 4001 (HTTP + Socket.IO). Hinter einem Reverse Proxy sollte TLS terminiert werden.
@@ -13,12 +17,12 @@ Dieser Abschnitt deckt typische Aufgaben für Betriebsteams ab von Backups
3. **Restore**: Ersetze die Datei im Volume und starte die App neu. Beim ersten Start führt `ensureDatabaseSchema` automatisch eventuelle Nachmigrationen aus.
## Benutzer- & Rechteverwaltung
- Superuser können über `/api/auth/superuser/*` oder im UI registriert werden. Entfernen ist nur mit `maintenance-superuser-delete` möglich.
- Superuser können über `/api/auth/superuser/*` oder im UI registriert werden. Entfernen ist nur mit `Superuser löschen` möglich.
- Benutzerkonten lassen sich temporär deaktivieren (`/api/users/:id/active`). Die Historie bleibt erhalten.
- Sicherheitsphrasen sind notwendig für Passwort-Reset. Admins können neue Phrasen erzeugen (`/api/users/:id/security-phrase/renew`), müssen diese aber dem Benutzer sicher zustellen.
## Wartungsmodus & Updates
- Maintenance Mode aktivieren: `curl -X POST http://host:4001/api/maintenance/mode -H 'Content-Type: application/json' -d '{"active":true,"message":"Cluster Upgrade"}'` (Permission `maintenance-access`). Das UI informiert alle Nutzer und blockiert Redeploys.
- Maintenance Mode aktivieren: `curl -X POST http://host:4001/api/maintenance/mode -H 'Content-Type: application/json' -d '{"active":true,"message":"Cluster Upgrade"}'` (Recht `Bereich & Navigation (Wartung)`). Das UI informiert alle Nutzer und blockiert Redeploys.
- SSH-/Update-Setup: Hinterlege Host, Port, Benutzer, Passwort (optional) und zusätzliche SSH-Argumente. Passwörter werden verschlüsselt gespeichert (`PORTAINER_SSH_SECRET`).
- Update-Skript: Das Default-Skript (`DEFAULT_PORTAINER_UPDATE_SCRIPT`) führt `docker stop`, `docker run` etc. aus. Du kannst im UI oder via API ein eigenes Skript setzen wird erst aktualisiert, wenn kein Update läuft.
- Update anstoßen: `POST /api/maintenance/portainer-update` triggert die SSH-Kommandos. Status & Logausgaben können über `/api/maintenance/update-status` überwacht werden.
+8 -3
View File
@@ -1,6 +1,11 @@
# Benutzergruppen & Rechte
Dieser Bereich verwaltet Rollenmodelle und bestimmt, welche Aktionen Benutzer:innen durchführen dürfen. Du benötigst `user-groups-access` zum Lesen sowie `user-groups-edit`/`user-groups-delete` für Änderungen.
Dieser Bereich verwaltet Rollenmodelle und bestimmt, welche Aktionen Benutzer:innen durchführen dürfen.
**Relevante Rechte**
- `Bereich & Navigation (Benutzergruppen)`
- `Benutzergruppen bearbeiten`
- `Benutzergruppen löschen`
## Gruppen anlegen
1. Button **Gruppe erstellen** wählen.
@@ -23,7 +28,7 @@ Der Rechte-Dialog zeigt die gesamte Permissionstruktur in Kategorien (Stacks, Lo
- **none** kein Zugriff
- **read** Zugriff auf Ansicht/Lesen
- **full** volle Bearbeitungsrechte
3. Abhängigkeiten werden automatisch hervorgehoben. Beispiel: Um `logs-delete` nutzen zu dürfen, muss `logs-access` mindestens `full` sein.
3. Abhängigkeiten werden automatisch hervorgehoben. Beispiel: Um `Logs löschen` nutzen zu dürfen, muss `Bereich & Navigation (Logs)` mindestens `Vollzugriff` sein.
4. Speichern bestätigt die Anpassungen. StackPulse aktualisiert sofort die effektiven Rechte aller Benutzer in dieser Gruppe.
## Benutzer zu Gruppen hinzufügen
@@ -36,6 +41,6 @@ Der Rechte-Dialog zeigt die gesamte Permissionstruktur in Kategorien (Stacks, Lo
- Löschen entfernt keine Benutzer, aber deren effektive Rechte können sich dadurch verringern.
## Best Practices
- Erstelle zunächst eine Basisgruppe (z.B. „Viewer“) mit `read`-Rechten für Stacks und Logs.
- Erstelle zunächst eine Basisgruppe (z.B. „Viewer“) mit Leserechten für Stacks und Logs.
- Verwende separate Gruppen für sensible Aktionen wie Wartung oder Superuser-Verwaltung.
- Nutze sprechende Beschreibungen, damit Kolleg:innen sofort erkennen, wofür eine Gruppe gedacht ist.
+50 -31
View File
@@ -1,43 +1,62 @@
# Wartungsbereich
Der Wartungsbereich bündelt alle Funktionen rund um Maintenance-Mode, Serververwaltung, Update-Skripte und SSH-Verbindungen. Sichtbar für Benutzer:innen mit `maintenance-access` (Teilbereiche erfordern zusätzliche Unterrechte).
Der Wartungsbereich bündelt Maintenance-Mode, Serververwaltung (inkl. Agent-Integration), Update-Skripte und SSH-Konfiguration. Sichtbar für Benutzer:innen mit `Bereich & Navigation (Wartung)`; Unterbereiche haben eigene Rechte:
## Portainer-Status
- Klick auf **Status prüfen**, um eine Live-Abfrage gegen Portainer durchzuführen. Ergebnis zeigt API-Verfügbarkeit, Endpoint-IDs und Auth-Status.
- Häufige Fehler werden direkt erklärt (z.B. fehlender API-Key oder Netzwerkprobleme).
**Relevante Rechte**
- `Bereich & Navigation (Wartung)`
- `Server-Sektion`
- `Server bearbeiten` / `Server löschen`
- `SSH/Update-Skript`
- `Update durchführen`
- `Agent`
- `Doppelte Stacks`
- `mTLS Sektion`
- `Superuser löschen`
- `Server-Sektion` (lesen) zeigt die Serverübersicht.
- `Server bearbeiten` (lesen) zeigt Server-Details inkl. Portainer-Status; Felder bleiben schreibgeschützt. Vollzugriff erlaubt Bearbeiten/Speichern.
- `Server löschen` löscht Server (nur bei Vollzugriff).
- `SSH/Update-Skript` und `Update durchführen` hängen am Unterpunkt Portainer/SSH und erfordern Vollzugriff auf Server-Edit.
- `Agent` (lesen/voll) steuert die Agent-Sektion im Server-Detail.
## Maintenance-Mode
1. Schalter **Wartungsmodus aktivieren** toggeln.
2. Optionale Nachricht eingeben (z.B. „Upgrade um 22:00 Uhr“); sie erscheint im gesamten UI als Banner.
3. Aktivieren/Deaktivieren protokolliert automatisch Events in den Logs.
1. Schalter **Wartungsmodus aktivieren** umlegen.
2. Jede Aktivierung/Deaktivierung wird in den Logs protokolliert.
## Server & API-Key verwalten
- Register „Server“ listet alle Portainer-Instanzen.
- Über **Server hinzufügen** kannst du Name + URL ergänzen und anschließend API-Key speichern.
- Buttons in der Tabelle:
- **API-Key aktualisieren** neues Token einsetzen.
- **Server löschen** nur möglich, wenn mindestens ein weiterer Server existiert oder du sofort neue Daten einträgst.
## Serververwaltung & API-Key
- Liste zeigt alle eingetragenen Portainer-Server.
- **Server hinzufügen**/**bearbeiten**/**löschen** nur mit `Server bearbeiten` (Vollzugriff); löschen zusätzlich `Server löschen`.
- Im Server-Detail:
- **Server-URL/Name** und **Portainer API-Key**: editierbar nur mit `Server bearbeiten` Vollzugriff; bei Leserecht sichtbar, aber gesperrt.
- **Self-Stack-ID**: Stack-ID von StackPulse selbst; blockiert Redeploys dieses Stacks.
- **Status prüfen**: Live-Check gegen Portainer (Version, Edition, Update vorhanden). Sichtbar ab `Server bearbeiten` (lesen).
## Self-Stack ID
- Feld „Eigener Stack“ akzeptiert die Stack-ID, in der StackPulse selbst läuft.
- Nach dem Speichern sind Redeploy-Aktionen für diesen Stack im Dashboard deaktiviert.
## Agent-Integration (Portainer CE / Edge)
Für die Community Edition von Stackpulse kannst du je Server einen StackPulse Agent hinterlegen. Er liefert Stack- und Portainer-Metadaten, wenn die Business-API fehlt. Hierzu muss auch der Agent auf dem Server der Portainer Instanz laufen. Der Agent wird für die Business Edition nicht benötigt.
1. Im Server-Detail **Agent konfigurieren** öffnen.
2. **Agent URL** eintragen, der **Agent Token** wird automatisch generiert und kann nicht geändert werden (Token = `AGENT_TOKEN` des Agents).
StackPulse prüft Erreichbarkeit und zeigt Online-/Fehlerstatus. Sichtbar mit `Agent` lesen, Bearbeitung mit `Agent` voll.
3. mTLS-Zertifikate verwalten:
- **Bootstrap-Token erzeugen** (Einmal-Token) und im Agent als `AGENT_BOOTSTRAP_TOKEN` setzen.
- Agent holt Zertifikate automatisch ab; Status im Zertifikate-Abschnitt.
- **Zertifikate anzeigen** (PEM) (nur bei entsprechenden Rechten)
4. Portainer-Version kann gelesen werden, wenn der Agent online ist.
## SSH-Konfiguration
Erforderliche Permission: `maintenance-ssh-update`.
1. Host, Port, Benutzername eintragen. Optional Passwort und zusätzliche SSH-Argumente (z.B. `-o StrictHostKeyChecking=no`).
2. Passwort wird verschlüsselt 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.
Erfordert `SSH/Update-Skript` (sichtbar/bearbeitbar nur bei Vollzugriff auf Server-Edit).
1. Host, Port, Benutzername und Passwort sowie eventuell notwendige Extra-Argumente eintragen.
2. Passwort wird verschlüsselt gespeichert.
3. **Verbindung testen** prüft Erreichbarkeit und meldet Ergebnis direkt.
## Update-Skript
- Standard-Skript wird angezeigt und kann als Ausgangspunkt genutzt werden.
- Eigenes Skript: Inhalt in das Editorfeld kopieren und speichern. StackPulse prüft auf leere Zeilen und Basisbefehle.
- Skript zurücksetzen entfernt die benutzerdefinierte Variante und stellt den Default wieder her.
## Portainer-Update auslösen
1. Stelle sicher, dass Wartungsmodus aktiv ist und SSH-Konfiguration + Skript korrekt sind.
2. Klicke auf **Update starten**. Der aktuelle Fortschritt erscheint in einem Logpanel.
3. Der Button bleibt deaktiviert, solange ein Update läuft. Über **Status aktualisieren** kannst du den Fortschritt erneut abfragen.
## Update-Skript & Portainer-Update
- Standard-Skript ist sichtbar und kann überschrieben werden (Recht `SSH/Update-Skript` + Server-Edit Vollzugriff). **Zurücksetzen** stellt den Standard wieder her.
- Start eines Updates (`Update durchführen` + Server-Edit Vollzugriff):
1) Wartungsmodus wird automatisch aktiviert.
2) SSH-Konfiguration und Skript prüfen.
3) **Update starten** klicken. Der Fortschritt und die Logausgaben erscheinen im Fenster.
4) Während ein Update läuft, sind Änderungen am System gesperrt.
## Fehlerbehandlung
- Bei SSH-Fehlern zeigt StackPulse die genaue Ausgabe an. Passe Host/Port/Benutzer oder Skript an.
- Falls das Update-Skript Probleme verursacht, kannst du es jederzeit stoppen, indem du Portainer manuell prüfst und ggf. das Skript anpasst.
- SSH-/Update-Fehler werden mit Klartextausgabe angezeigt. Bei Bedarf Host/Port/User, Passwort oder Skript anpassen.
- Agent offline: URL/Token prüfen, Bootstrap-Token ggf. neu erzeugen und den Agent neu starten.
+2 -2
View File
@@ -1,6 +1,6 @@
# Setup-Assistent
Beim ersten Start erscheint automatisch der Setup-Bereich. Du erreichst ihn später jederzeit über `/setup`, solange nicht alle Schritte abgeschlossen sind.
Beim ersten Start erscheint automatisch der Setup-Bereich und führt dich durch alle Schritte, bis die Einrichtung abgeschlossen ist.
## Voraussetzungen
- Portainer Business Edition mit gültigem API-Key
@@ -31,5 +31,5 @@ Beim ersten Start erscheint automatisch der Setup-Bereich. Du erreichst ihn spä
## Setup wiederholen oder ändern
- Über das Dashboard → **Wartung** → Abschnitt *Serververwaltung* kannst du zusätzliche Portainer-Server hinzufügen oder entfernen.
- Superuser lässt sich im Bereich **Benutzer** löschen, sofern du `maintenance-superuser-delete` besitzt.
- Superuser lässt sich im Bereich **Benutzer** löschen, sofern du das Recht `Superuser löschen` besitzt.
- Der Self-Stack (StackPulse-eigener Stack) kann in der Wartung gepflegt werden, damit er nicht versehentlich redeployed wird.
+8 -3
View File
@@ -2,6 +2,11 @@
Die Stacks-Ansicht ist der Startpunkt nach dem Login und liefert einen Überblick über alle Stacks der angebundenen Portainer-Instanz.
**Relevante Rechte**
- `Redeploy einzeln`
- `Redeploy Auswahl`
- `Redeploy Alle`
## Aufbau
- **Header** mit Suchfeld, Filterchips für Status sowie Buttons für Redeploy-Aktionen.
- **Tabelle** mit Name, Endpoint, Status, letzte Aktion, Redeploy-Status und verfügbaren Buttons.
@@ -15,9 +20,9 @@ Die Stacks-Ansicht ist der Startpunkt nach dem Login und liefert einen Überblic
## Redeploy-Aktionen
| Aktion | Voraussetzung | Vorgehen |
|--------|---------------|----------|
| **Einzelner Stack** | Permission `stacks-redeploy-single` | Button **Redeploy** in der jeweiligen Zeile klicken und bestätigen. |
| **Mehrere Stacks** | `stacks-redeploy-selection` | Checkboxen der gewünschten Stacks aktivieren, anschließend **Redeploy Auswahl**. |
| **Alle Stacks** | `stacks-redeploy-all` | Button **Redeploy alle** auslösen. Nutze vorher Filter, um sicherzugehen, dass alle Stacks korrekt angezeigt werden. |
| **Einzelner Stack** | Recht `Redeploy einzeln` | Button **Redeploy** in der jeweiligen Zeile klicken und bestätigen. |
| **Mehrere Stacks** | Recht `Redeploy Auswahl` | Checkboxen der gewünschten Stacks aktivieren, anschließend **Redeploy Auswahl**. |
| **Alle Stacks** | Recht `Redeploy Alle` | Button **Redeploy alle** auslösen. Nutze vorher Filter, um sicherzugehen, dass alle Stacks korrekt angezeigt werden. |
Während eines Redeploys erscheint pro Stack ein Fortschrittsbadge. Du kannst das Panel schließen; beim nächsten Besuch wird der aktuelle Status aus dem Backend gelesen.