Self-Hosting-Konfiguration

Vollständige Referenz für Docker-Umgebungsvariablen, Convex-Backend-Variablen, Service-Topologie und Persistenz von Volumes.

Diese Seite ist die vollständige Konfigurationsreferenz für eine selbst gehostete Owlat-Instanz. Eine Schritt-für-Schritt-Einrichtung finden Sie unter Self-Hosting.

Zwei Konfigurationsebenen

Docker-.env vs. Convex-Umgebungsvariablen

Owlat nutzt zwei getrennte Konfigurationsebenen. Sie zu verwechseln ist der häufigste Fehler bei der Einrichtung.

  • Docker-.env — wird von Docker Compose beim Start der Container gelesen. Steuert Ports, zwischen Containern geteilte Secrets und die vom Browser aufgerufenen URLs.
  • Convex-Umgebungsvariablen — werden von den Serverless-Functions innerhalb des Convex-Backends gelesen. Werden nach dem Deployment über npx convex env set gesetzt. Steuern das Anwendungsverhalten: E-Mail-Provider, Auth-Secrets, Absenderidentität, Integrationen.

Docker-Umgebungsvariablen

Diese gehören in die Datei .env im Projektstammverzeichnis. Docker Compose liest sie beim Starten der Container.

Convex-Backend

VariableErforderlichStandardBeschreibung
INSTANCE_SECRETJaInstanzidentität des Convex-Backends. Mit openssl rand -hex 32 erzeugen.
CONVEX_ADMIN_KEYJaAdmin-Key zum Deployen der Functions. Wird nach dem ersten Start über docker compose exec convex ./generate_admin_key.sh erzeugt.

Öffentliche URLs

Diese müssen aus dem Browser des Nutzers erreichbar sein — verwenden Sie keine Docker-internen Hostnamen.

VariableErforderlichStandardBeschreibung
NUXT_PUBLIC_CONVEX_URLJahttp://localhost:3210URL des Convex-Backends (Browser → Convex).
NUXT_PUBLIC_CONVEX_SITE_URLJahttp://localhost:3211URL des Convex-Site-Proxys (Browser → HTTP-Actions).
NUXT_PUBLIC_SITE_URLJahttp://localhost:3000URL der Webanwendung.

MTA-Konfiguration

Der MTA ist ein optionaler Service

Der eingebaute MTA läuft nur, wenn er der Zustell-Provider ist (EMAIL_PROVIDER=mta) oder wenn postbox/inbox ihn für eingehende Mail benötigen — gesteuert über das Docker-Compose-Profil mta. Der Standard-Self-Host liefert COMPOSE_PROFILES=mta aus; ein Deployment mit Resend/SES, ein reines Empfangs- oder ein reines IMAP-Deployment lässt mta weg und betreibt ihn nicht. Diese Variablen gelten nur, wenn der MTA aktiv ist. Siehe Betriebsmodi.

VariableErforderlichStandardBeschreibung
MTA_API_KEYJaGemeinsames Secret für die Authentifizierung Convex → MTA. Mit openssl rand -base64 32 erzeugen.
MTA_WEBHOOK_SECRETJaHMAC-Secret für Webhook-Callbacks MTA → Convex. Mit openssl rand -base64 32 erzeugen.
EHLO_HOSTNAMEFür Zustellungmail.localhostHostname für SMTP EHLO/HELO. Der Platzhalter lässt den Service starten, dessen IP bleibt jedoch in Quarantäne, bis der Hostname zu einem Forward-Confirmed PTR passt.
EHLO_HOSTNAMESNeinJSON-Zuordnung von Versand-IP zu EHLO-Hostname für Deployments mit mehreren IPs.
MTA_GENERIC_PTR_SUFFIXESNeinZusätzliche, kommagetrennte Provider-Standard-PTR-Suffixe, die als reputationsschwach markiert werden sollen.
MTA_ALLOW_UNVERIFIED_FCRDNSNeinfalseNur für Laborumgebungen: Umgehung der FCrDNS-Quarantäne. Niemals für die Zustellung ins Internet aktivieren.
MTA_IPV6_ENABLEDNeinfalseAusdrückliche Freigabe für ausgehendes IPv6. Solange false, werden IPv6-Pool-Einträge abgelehnt; bei true bleiben sie an IPv4-Identität, PTR/AAAA und die SPF-Bereitschaft des Return-Path gebunden.
RETURN_PATH_DOMAINFür Zustellungbounces.localhostDomain für VERP-Return-Path-Adressen bei Bounces. Der Standard bounces.localhost startet problemlos; für den produktiven Versand erforderlich, dort mit einem MX-Record auf Ihren Server.
IP_POOLS_TRANSACTIONALNein127.0.0.1Kommagetrennte IPs für die Zustellung transaktionaler E-Mails.
IP_POOLS_CAMPAIGNNein127.0.0.1Kommagetrennte IPs für die Zustellung von Kampagnen-/Marketing-E-Mails.
DKIM_KEYSNein{}DKIM-Signaturschlüssel als JSON. Siehe DNS- & E-Mail-Setup.
WORKER_CONCURRENCYNein50Anzahl paralleler MTA-Worker-Threads.
MTA_LOG_LEVELNeininfoLog-Ausführlichkeit des MTA: debug, info, warn, error.

Port-Überschreibungen

Alle Ports lassen sich ändern, falls die Standardwerte mit vorhandenen Services kollidieren.

VariableStandardService
CONVEX_PORT3210Convex-Backend-API
CONVEX_SITE_PORT3211Convex-HTTP-Actions
DASHBOARD_PORT6791Convex-Dashboard (erfordert --profile dashboard; nur an 127.0.0.1 gebunden — Zugriff über SSH-Tunnel)
WEB_PORT3000Webanwendung
MTA_HTTP_PORT3100MTA-HTTP-API
MTA_SMTP_PORT25MTA-SMTP (Bounce-Verarbeitung)

Die Ports von Convex, MTA-HTTP und Dashboard binden standardmäßig nur an localhost (127.0.0.1). CONVEX_BIND (Standard 127.0.0.1) legt fest, an welches Interface das Convex-Backend bindet, und REDIS_PASSWORD setzt das Redis-Authentifizierungspasswort.

Redis und ClamAV veröffentlichen keinen Host-Port — sie sind ausschließlich über das interne Docker-Netzwerk erreichbar (redis:6379, clamav:3310); es gibt daher keinen Schalter REDIS_PORT/CLAMAV_PORT zur Host-Überschreibung. (CLAMAV_PORT wird am MTA-Container als die interne Adresse gesetzt, die dessen Scan-Client anspricht; ein Host-Port wird damit nicht gemappt.)

Analytics (optional)

VariableStandardBeschreibung
NUXT_PUBLIC_POSTHOG_API_KEYPostHog-Projekt-API-Key für clientseitiges Tracking.
NUXT_PUBLIC_POSTHOG_HOSThttps://eu.i.posthog.comURL der PostHog-Instanz.

Deployment-Modus

Diese Variablen steuern, welche Oberfläche die Web-App anzeigt und ob In-App-Updates ausgeführt werden können. Die Standardwerte passen zu einer selbst gehosteten Installation — Sie müssen sie selten ändern.

VariableStandardBeschreibung
OWLAT_DEPLOYMENT_MODEselfhostWird von der Web-App gelesen (config.public.deploymentMode). Steuert das Onboarding-Banner für Self-Hosting. Für ein OSS-Deployment auf selfhost belassen.
OWLAT_INSTALL_DIR./Absoluter Pfad zu diesem Repository auf dem Host. Der updater-Sidecar bindet ihn ein, um Compose-Templates zu schreiben und docker compose pull && up -d auszuführen. Für In-App-Updates erforderlich.
OWLAT_HOSTED_MODE ist im OSS-Repo wirkungslos

Das owlat-Setup-CLI schreibt einen Wert für OWLAT_HOSTED_MODE in die .env, kein Service in diesem OSS-Repository liest ihn jedoch — die Control Plane der gehosteten Cloud (und deren Abrechnung) wurde in ein separates, privates Repository ausgelagert. Ihn zu setzen hat auf eine selbst gehostete Instanz keine Auswirkung.

Image-Pinning (optional)

Die Compose-Datei pinnt Upstream-Images über eigene *_VERSION-Variablen auf Minor-Versionen, jeweils mit einem fest hinterlegten Standardwert. Überschreiben Sie sie nur, um eine andere Version zu pinnen; die Compose-Dateien produktiver Releases fixieren diese zusätzlich auf @sha256-Digests.

VariableStandardImage
CONVEX_BACKEND_VERSIONlatestghcr.io/get-convex/convex-backend
CONVEX_DASHBOARD_VERSIONlatestghcr.io/get-convex/convex-dashboard
REDIS_VERSION7.4-alpineredis
CLAMAV_VERSIONstableclamav/clamav
CADDY_VERSION2.8-alpinecaddy (nur mit --profile tls verwendet)

Die eigenen Images von Owlat (web, mta, updater, convex-deploy, code-worker) werden mit OWLAT_VERSION getaggt — der Tag für den Image-Pull ist standardmäßig latest, während das Build-Argument im Container standardmäßig auf dem Sentinel dev für lokale Builds steht. Die Release-Pipeline schreibt den gepinnten Tag; bearbeiten Sie OWLAT_VERSION, OWLAT_GIT_SHA oder OWLAT_BUILD_DATE daher nicht von Hand.

Convex-Umgebungsvariablen

Diese werden nach dem Deployen der Functions gesetzt. Sie steuern das Verhalten auf Anwendungsebene innerhalb des Convex-Backends.

npx convex env set VAR_NAME "value" \
  --url http://localhost:3210 \
  --admin-key <your-admin-key>

Diese für den Normalbetrieb setzen

Setzen Sie alle diese Variablen in jedem echten Deployment. Im Code werden die meisten mit sinnvollen Fallbacks gelesen und lassen eine Function nicht abstürzen, wenn sie fehlen — Auth-Weiterleitungen, Abmeldelinks und CORS sind ohne sie jedoch falsch.

VariableBeschreibung
SITE_URLÖffentliche Site-URL für Auth-Weiterleitungen (z. B. http://localhost:3000). Fällt auf http://localhost:3000 zurück.
BETTER_AUTH_SECRETSecret zum Signieren von Auth-Sessions. Mit openssl rand -base64 32 erzeugen.
UNSUBSCRIBE_SECRETHMAC-Secret für signierte Abmelde-Tokens. Mit openssl rand -base64 32 erzeugen.
EMAIL_PROVIDERE-Mail-Provider: mta, ses, resend, smtp, mandrill oder emailit. Kein impliziter Standardwert — bleibt die Variable ungesetzt, werden Sendungen abgelehnt statt an den eingebauten MTA geleitet.
CONVEX_SITE_URL nicht über `convex env set` setzen

CONVEX_SITE_URL (verwendet für Tracking-Pixel und Abmeldelinks) ist ein Convex-Built-inconvex env set lehnt es mit EnvVarNameForbidden ab. Das Backend leitet den Wert von CONVEX_SITE_ORIGIN am convex-Container ab, das docker-compose aus NUXT_PUBLIC_CONVEX_SITE_URL in Ihrer .env interpoliert. Setzen Sie die öffentliche URL dort, nicht als Umgebungsvariable einer Convex-Function.

Das einzige zwingend erforderliche Paar

MTA_API_URL und MTA_API_KEY sind die einzigen Variablen, die einen harten Fehler auslösen — und das nur, wenn tatsächlich eine E-Mail über den MTA-Provider versendet wird (Auth-Einladungen, Kampagnen, transaktionale Mail). Der Versand scheitert mit No system email transport configured, wenn eine der beiden nicht gesetzt ist (apps/api/convex/systemMail.ts; der MTA-Provider selbst liegt in apps/api/convex/lib/sendProviders/mta/index.ts). Setzen Sie beide immer dann, wenn EMAIL_PROVIDER=mta gilt.

VariableBeschreibung
MTA_API_URLURL des MTA-Service. Verwenden Sie http://mta:3100 für das Docker-Networking.
MTA_API_KEYMuss mit MTA_API_KEY in der Docker-.env übereinstimmen.
MTA_WEBHOOK_SECRETMuss mit MTA_WEBHOOK_SECRET in der Docker-.env übereinstimmen.

Absenderidentität

VariableStandardBeschreibung
DEFAULT_FROM_EMAILnoreply@example.comStandard-Absenderadresse.
DEFAULT_FROM_NAMEOwlatStandardmäßig angezeigter Absendername.
DEFAULT_FROM_DOMAINmail.owlat.appDomain für System-E-Mails (Einladungen usw.).
ALLOWED_ORIGINSKommagetrennte CORS-Origins (z. B. http://localhost:3000,http://localhost:3001).

LLM-Provider (optional)

Owlat spricht mit einem einzigen austauschbaren LLM-Provider (ADR-007). Dieselbe Konfiguration versorgt KI-Agentenantworten, Übersetzungen, Embeddings für den Knowledge Graph und den Visualisierungs-Agenten. Alles, was das Format der OpenAI Chat Completions / Embeddings spricht, funktioniert (OpenAI, OpenRouter, Ollama, lokales vLLM/LM Studio). Setzen Sie diese Variablen nur, wenn Sie ein KI-Feature-Flag aktivieren.

VariableStandardBeschreibung
LLM_PROVIDERopenaiopenai, openrouter oder ollama. Wählt den Client und eine Standard-Basis-URL.
LLM_API_KEYAPI-Key des Providers. Für ollama nicht erforderlich.
LLM_BASE_URLProvider-StandardÜberschreibt den Endpunkt (für selbst gehostete/lokale Server). OpenRouter und Ollama erhalten automatisch sinnvolle Standardwerte.
LLM_MODEL_FASTgpt-4o-miniModell für schnelle Aufgaben (Klassifizieren/Extrahieren/Absichern/Zusammenfassen).
LLM_MODEL_CAPABLEgpt-4oModell für anspruchsvolle Aufgaben (Entwurf).
LLM_EMBEDDING_MODELtext-embedding-3-smallEmbedding-Modell für den Knowledge Graph.
Abwärtskompatible Key-Aliase

OPENAI_API_KEY und OPENROUTER_API_KEY werden als Fallback-Aliase für LLM_API_KEY akzeptiert (Reihenfolge: LLM_API_KEYOPENROUTER_API_KEYOPENAI_API_KEY). Bevorzugen Sie bei neuen Installationen LLM_API_KEY (apps/api/convex/lib/llmProvider.ts).

Claude-Modelle betreiben

LLM_PROVIDER akzeptiert nur openai, openrouter und ollama. Um Claude-Modelle zu betreiben, nutzen Sie den OpenAI-kompatiblen Weg: Setzen Sie LLM_PROVIDER=openai (oder belassen Sie den Standard), richten Sie LLM_BASE_URL auf einen OpenAI-kompatiblen Endpunkt und setzen Sie LLM_MODEL_CAPABLE / LLM_MODEL_FAST auf die Claude-Modell-IDs.

Weitere Integrationen (optional)

VariableBeschreibung
GOOGLE_SAFE_BROWSING_API_KEYKey für die Google-Safe-Browsing-API v4 zur Prüfung der URL-Reputation.
MTA_INTERNAL_URLBevorzugte clusterinterne MTA-Basis-URL für alle HTTP-Aufrufe Convex→MTA (ausgehender Versand, Cache-Push, Zustell-Hooks, Anhangsprüfung); überschreibt das öffentliche MTA_API_URL. Z. B. http://mta:3100.
MAIL_SYNC_API_URLURL des Mail-Sync-Workers für externe IMAP-/SMTP-Konten. Ohne sie wird ein ausgehender externer Versand für jeden Empfänger als fehlgeschlagen markiert (errorCode EXTERNAL_NOT_CONFIGURED), statt zugestellt zu werden.
MAIL_SYNC_API_KEYGemeinsames Secret für den Mail-Sync-Worker.
POSTHOG_API_KEYPostHog-API-Key für serverseitige Analytics.
POSTHOG_HOSTURL der PostHog-Instanz (Standard: https://eu.i.posthog.com).

Die vollständige Variablenreferenz einschließlich AWS SES, Resend und Webhooks für eingehende Kanäle finden Sie unter Umgebungsvariablen.

Service-Topologie

ServicePortsHängt ab vonHealthcheck
convex3210 (API), 3211 (Site-Proxy)curl -f http://localhost:3210/version alle 15 s
convex-dashboard6791 (nur 127.0.0.1)convex (healthy)— (Profil dashboard; Zugriff über SSH-Tunnel ssh -L 6791:127.0.0.1:6791 host)
web3000convex (healthy)
mta3100 (HTTP), 25 (SMTP)redis (healthy), convex (healthy), clamav (gestartet, optional)
redis6379redis-cli ping alle 10 s
clamav3310clamdcheck alle 60 s (600 s Startverzögerung) (Profil clamav; aus, sofern die Dateiprüfung nicht aktiviert ist)
updater3200 (nur intern)docker-socket-proxy
convex-deployconvex (healthy)Einmalig (Profil deploy)
caddy80, 443web, convex, mta— (Profil tls)
code-worker— (nur intern)convex (healthy)— (Profil inbox-codetasks; außerdem dev)
imap993convex (healthy), imap-cert-init (abgeschlossen)— (Profil personal-mail)
mail-sync— (nur intern)convex (healthy)— (Profil external-mail)
ollama— (nur intern)— (Profile ai / dev)

Der updater-Sidecar hat keinen öffentlichen Port — die Web-App erreicht ihn über das Docker-Netzwerk unter http://updater:3200. Er bindet ausschließlich OWLAT_INSTALL_DIR mit Schreibrechten ein, um ein neues Compose-Template schreiben zu können, und erreicht die Docker-API über den Least-Privilege-Sidecar docker-socket-proxy (der den Socket schreibgeschützt einbindet) via DOCKER_HOST=tcp://docker-socket-proxy:2375 — den Docker-Socket bindet er nicht mehr direkt ein.

Der optionale Service caddy (--profile tls) ist ein Reverse Proxy, der TLS über Let's Encrypt terminiert und web, convex und mta auf Subdomains vorschaltet. Passen Sie die Caddyfile vor dem Start an Ihre Domains an, oder stellen Sie dem Stack stattdessen Ihren eigenen Reverse Proxy voran.

Der Sidecar code-worker (--profile inbox-codetasks, ebenfalls über --profile dev verfügbar) ist der KI-Coding-Agent, der Code-Tasks übernimmt. Er liest die Variablen LLM_* und GITHUB_* und ist standardmäßig aus.

Volumes

VolumePersistiertBackup-Priorität
convex-dataDatenbank, Dateispeicher, VektorindizesKritisch — sämtliche Anwendungsdaten
redis-dataMTA-Job-Queue (AOF)Mittel — laufende E-Mail-Jobs
clamav-dataVirensignaturenNiedrig — werden automatisch neu heruntergeladen
caddy-data / caddy-configTLS-Zertifikate und Caddy-Zustand (nur mit --profile tls)Niedrig — Zertifikate werden automatisch neu ausgestellt
code-workspaceCheckout des Code-Workers (nur mit --profile inbox-codetasks oder --profile dev)Niedrig — kurzlebiger Arbeitsbaum
mail-certsTLS-Zertifikate des IMAP-Servers (nur mit --profile personal-mail)Niedrig — Zertifikate werden automatisch neu ausgestellt
ollama-dataOllama-Modelldateien (nur mit --profile ai / --profile dev)Niedrig — Modelle werden automatisch neu heruntergeladen