§ DOCUMENTATION
Self-Hosted-Deployment
Betreiben Sie die vollständige Execlave-Governance-Plattform auf Ihrer eigenen Infrastruktur mit den veröffentlichten Docker-Images und einem Lizenzschlüssel. Agenten- und Trace-Daten bleiben in Ihrem Netzwerk — das Einzige, was die Grenze überschreitet, ist ein täglicher Lizenz-Heartbeat (Lizenzschlüssel, Instanz-Fingerabdruck, Hostname, Version sowie Trace-/Agenten-/Nutzerzahlen — keine Trace-Inhalte oder Kundendatensätze); im Air-Gapped-Modus wird nichts gesendet.
Datenschutz: standardmäßig keine externen KI-API-Aufrufe
Das Standard-Self-Hosted-Deployment sendet keinerlei Prompts, Traces oder Modelleingaben an externe KI-Anbieter. Semantische Klassifizierung und Richtliniengenerierung können ein optionales lokales LLM nutzen (Ollama, mitgeliefert oder Ihr eigener Server), konfiguriert über LOCAL_LLM_URL (§06). Ohne LLM, oder wenn es nicht erreichbar ist, nutzen diese Funktionen deterministische Heuristiken — die Durchsetzung arbeitet weiter, nur die beratenden Klassifizierungen entfallen.
Was das für Beschaffungsprüfungen bedeutet
- Prompts und Traces verlassen Ihr Netzwerk nie.
- In der Standardkonfiguration werden keine API-Schlüssel für Anthropic, OpenAI, Google oder andere externe LLM-Anbieter benötigt — oder akzeptiert.
- Die Anmeldung läuft über einen mitgelieferten Identitätsdienst (Logto) innerhalb des Stacks; Benutzerkonten und Passwörter bleiben auf Ihrer Infrastruktur.
- Wenn Sie für einen bestimmten Workflow einen externen Anbieter einbinden möchten, sind Sie für die Compliance-Folgen der Datenübermittlung verantwortlich.
Voraussetzungen
- Linux-Host (beliebige Cloud oder Bare Metal) mit mindestens 4 CPU und 8 GB RAM; das optionale lokale LLM (§06) benötigt weitere 8 GB
- Docker 24+ mit Docker Compose v2
- PostgreSQL (mit TimescaleDB), Redis und der Anmeldedienst sind enthalten — eine externe Datenbank ist nicht nötig
- Ein Lizenzschlüssel und sein öffentlicher Signaturschlüssel (anfordern unter /get-license)
- Ausgehendes HTTPS zu
license.execlave.comfür den täglichen Heartbeat — oderLICENSE_AIRGAPPED=truefür keinerlei ausgehende Aufrufe (siehe §10)
Schnellstart
# 1. Compose-Datei laden und .env mit generierten Passwörtern anlegencurl -fsSL https://get.execlave.com/install.sh | sh # 2. Lizenz in .env eintragen (beide Werte erhalten Sie mit der Lizenz):# LICENSE_KEY=exe_lic_...# LICENSE_SIGNING_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----" # 3. Stack startendocker compose up -d # 4. http://localhost:3000 öffnen und als Administrator anmeldenDer Installer legt .env (nur für Sie lesbar) mit zufälligen Passwörtern für die Datenbanken, Redis, das interne Service-Token und den Dashboard-Administrator an und gibt das Administrator-Passwort einmal aus. Der Benutzername ist admin (EXECLAVE_ADMIN_USERNAME). Der erste Start lädt die Images und führt die Datenbankmigrationen aus, was einige Minuten dauert; docker compose ps zeigt alle Dienste als healthy, sobald der Stack bereit ist.
Den ersten Trace senden
Legen Sie im Dashboard unter Einstellungen → API-Schlüssel einen API-Schlüssel an, registrieren Sie dann einen Agenten und senden Sie einen Trace:
export EXECLAVE_API_KEY=exe_prod_...curl -X POST http://localhost:4000/api/v1/agents \ -H "Authorization: Bearer $EXECLAVE_API_KEY" -H 'Content-Type: application/json' \ -d '{"agentId":"my-agent","name":"My agent","type":"chatbot","platform":"custom","environment":"production"}'curl -X POST http://localhost:4000/api/v1/traces/ingest \ -H "Authorization: Bearer $EXECLAVE_API_KEY" -H 'Content-Type: application/json' \ -d "{\"traces\":[{\"traceId\":\"tr_1\",\"agentId\":\"my-agent\",\"status\":\"success\",\"durationMs\":120,\"environment\":\"production\",\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}]}"Die SDKs funktionieren genauso: Richten Sie sie mit baseUrl: 'http://localhost:4000' auf Ihre API aus (siehe Erste Schritte).
Einen Lizenzschlüssel erhalten
Kostenlose und kostenpflichtige Self-Hosted-Lizenzen werden derzeit manuell ausgestellt. Fordern Sie eine an unter /get-license.
- Free-Plan: Die Lizenz trifft innerhalb von 1 Geschäftsstunde ein
- Kostenpflichtige Pläne: Wir melden uns zuerst zur Einrichtung der Zahlung
- Enterprise: Wir vereinbaren ein 30-minütiges Gespräch
Der Lizenzschlüssel ist ein signiertes JWT (exe_lic_…); Sie erhalten ihn zusammen mit dem öffentlichen Schlüssel, der ihn verifiziert. Der Plan der Lizenz gilt für jede Organisation auf Ihrer Instanz.
Architektur
Alles läuft innerhalb Ihres Netzwerks. Der einzige ausgehende Verkehr ist der tägliche Lizenz-Heartbeat, im Air-Gapped-Modus gar keiner.
+----------------------------------------------------------+| Ihre Infrastruktur || || Browser --> +----------+ +---------+ +-----------+ || | Next.js |-->| Express |-->| Postgres | || | (3000) | | (4000) | | (5432) | || +----------+ +---------+ +-----------+ || | | || v v || +----------+ +---------+ +-----------+ || | Logto | | Worker |-->| Redis | || | Anmeldung| | (BullMQ)| | (6379) | || | (3301) | +---------+ +-----------+ || +----------+ || +---------------------------+ || | Processing (PDF, Scans) | || +---------------------------+ |+----------------------------------------------------------+ | | ausgehendes HTTPS, einmal täglich (Air-Gapped: nie) v+-----------------------------+| license.execlave.com || (Schlüssel, Fingerabdruck, || Zähler) |+-----------------------------+Konfiguration
Alle Einstellungen stehen in .env neben docker-compose.yml; die heruntergeladene .env.example dokumentiert jede einzelne. Passwörter und Tokens müssen mindestens 16 URL-sichere Zeichen lang sein (der Installer verwendet openssl rand -hex 32).
Erforderlich
| Variable | Beschreibung |
|---|---|
LICENSE_KEY | Ihr Lizenzschlüssel (exe_lic_…) |
LICENSE_SIGNING_PUBLIC_KEY | Öffentlicher Schlüssel, der die Lizenz verifiziert; wird mit ihr geliefert. Eine Zeile in doppelten Anführungszeichen, mit wörtlichem \n zwischen den PEM-Zeilen. |
LICENSE_INSTANCE_ID | Identifiziert dieses Deployment gegenüber dem Lizenzserver (generiert). Nie ändern — ein neuer Wert registriert eine neue Instanz (§09) — und nie in ein anderes Deployment kopieren. |
POSTGRES_PASSWORD | Datenbank-Superuser — nur für Migrationen und Rolleneinrichtung (generiert) |
APP_USER_DB_PASSWORD | Laufzeit-Datenbankrolle app_user (generiert; siehe §08) |
BOOTSTRAP_PASSWORD | Rolle app_bootstrap für Anmelde-Lookups (generiert) |
LOGTO_DB_PASSWORD | Eigene Datenbank des Anmeldedienstes (generiert) |
PROCESSING_INTERNAL_TOKEN | Gemeinsames Geheimnis zwischen API und Processing-Dienst (generiert) |
REDIS_PASSWORD | Redis-Passwort (generiert) |
EXECLAVE_ADMIN_USERNAME / _PASSWORD | Erster Dashboard-Administrator, beim ersten Start angelegt (Passwort generiert) |
Optional
| Variable | Standard | Beschreibung |
|---|---|---|
FRONTEND_URL | http://localhost:3000 | Öffentliche Dashboard-URL (Zugriff von anderen Rechnern: §07) |
NEXT_PUBLIC_API_URL | http://localhost:4000 | Öffentliche API-URL; wird beim Start des Containers gelesen |
LOGTO_PUBLIC_URL / LOGTO_ADMIN_PUBLIC_URL | :3301 / :3302 | Öffentliche Anmelde-URL (zugleich Token-Aussteller) und Benutzerverwaltungskonsole |
SIGNING_PRIVATE_KEY / SIGNING_PUBLIC_KEY | nicht gesetzt | RSA-Schlüsselpaar, das Audit-Checkpoints versiegelt und Compliance-Exporte signiert; ohne es bleiben beide unsigniert. Erzeugung: siehe .env.example. |
SIGNING_REQUIRED | false | true = ohne funktionierende Signaturschlüssel nicht starten |
LICENSE_AIRGAPPED | false | true = Lizenz nur offline prüfen, keine Aufrufe des Lizenzservers (§10) |
LICENSE_SERVER_URL | https://license.execlave.com/api/v1 | Lizenzserver für Prüfung und Heartbeat |
LOCAL_LLM_URL | nicht gesetzt | Lokales LLM für semantische Klassifizierung und Richtliniengenerierung (siehe unten); nicht gesetzt = Heuristiken |
EXECLAVE_VERSION | main | Image-Tag; für eine reproduzierbare Installation einen Commit-SHA-Tag festlegen |
*_BIND | 127.0.0.1 | Auf welcher Schnittstelle jeder Dienst lauscht (das Dashboard: auf allen) |
Lokales LLM (optional)
Der mitgelieferte Ollama-Dienst startet nur mit dem Profil llm und benötigt etwa 8 GB zusätzlichen RAM. Setzen Sie LOCAL_LLM_URL=http://llm:11434 in .env, starten Sie ihn und laden Sie die beiden Modelle einmalig:
docker compose --profile llm up -ddocker compose exec llm ollama pull mistral:7b-instruct-v0.3-q4_K_Mdocker compose exec llm ollama pull qwen2.5:14b-instruct-q4_K_MGeben Sie --profile llm auch bei späteren pull- und up-Befehlen an. Um einen bereits laufenden Ollama-Server zu nutzen, setzen Sie LOCAL_LLM_URL auf ihn, laden dort dieselben Modelle und lassen das Profil weg.
Anmeldung und Benutzer
- Die Anmeldung übernimmt der mitgelieferte Dienst Logto. Bei jedem Start stellt der einmalige Job
logto-initsicher, dass die Dashboard- und API-Anwendungen sowie der Administrator existieren, und übergibt ihre IDs an die anderen Dienste. - Die öffentliche Registrierung ist geschlossen. Weitere Benutzer legen Sie in der Logto-Admin-Konsole unter
LOGTO_ADMIN_PUBLIC_URLan (Standardhttp://localhost:3302, nur vom Host aus erreichbar). Bei der ersten Anmeldung erhält jeder Benutzer eine eigene Organisation mit der Rolle Inhaber. - Eine Änderung von
EXECLAVE_ADMIN_PASSWORDnach dem ersten Start ändert den bestehenden Benutzer nicht; ändern Sie das Passwort in der Admin-Konsole.
Zugriff von anderen Rechnern
Der Browser spricht mit drei Diensten: Dashboard, API und Anmeldung. Setzen Sie FRONTEND_URL, NEXT_PUBLIC_API_URL und LOGTO_PUBLIC_URL auf Adressen, die der Browser erreicht, öffnen Sie BACKEND_BIND und LOGTO_BIND nur hinter einer Firewall, einem VPN oder einem TLS-Reverse-Proxy, und führen Sie docker compose up -d erneut aus. Logto prüft seine eigenen Tokens über seine öffentliche URL aus dem eigenen Container heraus: Bei einfachen host:port-URLs müssen LOGTO_PORT / LOGTO_ADMIN_PORT den Ports in diesen URLs entsprechen; hinter einem Reverse-Proxy muss der Logto-Container den Hostnamen des Proxys erreichen können.
Datenbankrollen und Mandantentrennung
Organisationen sind durch PostgreSQL Row-Level Security getrennt, die ein Superuser umgeht. Der Stack verwendet daher drei Rollen:
| Rolle | Verwendet von | Rechte |
|---|---|---|
execlave | Nur Migrationen und Rolleneinrichtung | Superuser |
app_user | API, Worker, Processing | Kein Superuser, kein BYPASSRLS — Row-Level Security greift |
app_bootstrap | Anmelde- und API-Schlüssel-Lookups, bevor die Organisation bekannt ist | BYPASSRLS, minimale Rechte |
Die API setzt die Passwörter von app_user und app_bootstrap bei jedem Start aus .env; eine Änderung dort plus Neustart rotiert sie. API und Worker verweigern den Start, wenn ihre Datenbankverbindung Row-Level Security umgehen kann.
Lizenzschlüssel: wie sie funktionieren
- Prüfung beim Start — API und Worker verifizieren die JWT-Signatur mit
LICENSE_SIGNING_PUBLIC_KEYund prüfen Plan und Ablauf. Eine ungültige Lizenz verhindert ihren Start. - Instanz-Registrierung — außer im Air-Gapped-Modus registriert das Deployment beim Lizenzserver einen Fingerabdruck (Hash aus
LICENSE_INSTANCE_ID); der Server zählt unterschiedliche Fingerabdrücke gegen die Lizenz. API und Worker teilen ihn, sodass ein Deployment auch über Neustarts und Updates hinweg eine Instanz bleibt. Das Helm-Chart leitet ihn aus Namespace und Release-Namen ab. - Offline-Toleranz — ist der Lizenzserver nicht erreichbar, startet die Instanz allein auf Basis der signierten Lizenz, solange diese gültig ist.
- Heartbeat — einmal täglich sendet der Worker Lizenzschlüssel, Fingerabdruck, Hostname, Version sowie Trace-/Agenten-/Nutzerzahlen. Meldet der Server die Lizenz als widerrufen, fährt die Instanz herunter. Im Air-Gapped-Modus wird nichts gesendet.
- Kulanzzeitraum — nach Ablauf funktioniert eine Lizenz noch für den in ihr festgelegten Kulanzzeitraum (standardmäßig 14 Tage), die Organisationen werden als überfällig markiert; danach startet die Instanz erst nach Verlängerung der Lizenz wieder.
Aktualisierung, Backups und Air-Gapped-Modus
Aktualisierung
docker compose pulldocker compose up -dDatenbankmigrationen laufen beim Start der API automatisch. Erstellen Sie vorher ein Backup. Für eine neuere docker-compose.yml führen Sie den Installer im selben Verzeichnis erneut aus: Er behält Ihre .env und ergänzt inzwischen erforderliche Einstellungen.
Backups
Sichern Sie beide Datenbanken. Traces und Audit-Einträge liegen in TimescaleDB-Hypertables, die ein reines SQL-pg_dumpall nicht wiederherstellt: Sichern Sie die Rollen separat und die Execlave-Datenbank im Custom-Format von pg_dump. Die Logto-Datenbank enthält Ihre Benutzer.
docker compose exec -T postgres pg_dumpall -U execlave --roles-only > execlave-roles.sqldocker compose exec -T postgres pg_dump -U execlave -Fc execlave > execlave.dumpdocker compose exec -T logto-db pg_dumpall -U logto > logto.sqlpg_dump warnt vor zirkulären Fremdschlüsseln im TimescaleDB-Katalog; das ist erwartet. Bewahren Sie .env zusammen mit den Backups auf: Sie enthält die Passwörter, die die wiederhergestellten Datenbanken erwarten.
Wiederherstellung
Stellen Sie in leere Datenbanken wieder her (ein neuer Host, oder nach docker compose down -v, das alle Daten löscht), mit derselben .env und derselben EXECLAVE_VERSION. Starten Sie nur die Datenbanken, stellen Sie wieder her und starten Sie dann den Rest:
docker compose up -d postgres logto-dbdocker compose exec -T postgres psql -U execlave -d postgres < execlave-roles.sqldocker compose exec -T postgres psql -U execlave -d execlave -c "SELECT timescaledb_pre_restore();"docker compose exec -T postgres pg_restore -U execlave -d execlave < execlave.dumpdocker compose exec -T postgres psql -U execlave -d execlave -c "SELECT timescaledb_post_restore();"docker compose exec -T logto-db psql -U logto -d postgres < logto.sqldocker compose up -dDie Fehler role "execlave" already exists, role "logto" already exists und database "logto" already exists sind erwartet: Die Container legen diese beim ersten Start an. Jeder andere Fehler bedeutet, dass die Wiederherstellung unvollständig ist.
Air-Gapped-Modus
Setzen Sie LICENSE_AIRGAPPED=true in .env. Die Lizenz wird dann allein anhand ihrer Signatur geprüft, und die Instanz ruft den Lizenzserver nie auf — keine Registrierung, kein Heartbeat. Da sie nicht online verlängert werden kann, fordern Sie bei uns eine Lizenz an, deren Laufzeit zu Ihrem Update-Zyklus passt; E-Mail an support@execlave.com.
Fehlerbehebung
- Compose nennt die Variable. Setzen Sie sie in
.env— der Installer erzeugt alles außer den beiden Lizenzwerten.
- Prüfen Sie
LICENSE_KEYundLICENSE_SIGNING_PUBLIC_KEY(eine Zeile, doppelte Anführungszeichen, wörtliches\nzwischen den PEM-Zeilen) docker compose logs backend | grep -i licensezeigt den Grund (z. B. abgelaufen und Kulanzzeitraum überschritten)
- Ihre Datenbankverbindung könnte Row-Level Security umgehen. Richten Sie
DATABASE_URLnicht auf den Superuserexeclave; die Compose-Datei verwendet bereitsapp_user.
docker compose logs logto-initzeigt den fehlgeschlagenen Schritt- Wenn Sie die öffentlichen URLs geändert haben, halten Sie
LOGTO_PORT/LOGTO_ADMIN_PORTgleich deren Ports (§07) und führen Siedocker compose up -derneut aus
- Die API protokolliert "Signing keys not configured": Setzen Sie
SIGNING_PRIVATE_KEYundSIGNING_PUBLIC_KEY(§06)
- Ihr Lizenzplan begrenzt die Zahl der registrierten Instanz-Fingerabdrücke
- Jedes Deployment braucht eine eigene
LICENSE_INSTANCE_ID; ein geänderter Wert zählt 30 Tage lang als neue Instanz - Wenden Sie sich an den Support, um veraltete Instanzen freizugeben, oder wechseln Sie den Plan
docker compose logs backendzeigt die fehlgeschlagene Migration. Stellen Sie aus Ihrem Backup wieder her und wenden Sie sich an den Support.
Support
- Dokumentation: execlave.com/docs
- E-Mail: support@execlave.com
- Lizenz anfordern: /get-license