Wartung & Updates
Ihre selbst gehostete Owlat-Instanz aktuell halten, Backups verwalten, Performance skalieren und häufige Probleme beheben.
Diese Anleitung behandelt die tägliche Wartung Ihrer selbst gehosteten Owlat-Instanz. Für die Ersteinrichtung siehe Self-Hosting.
Aktualisieren
Owlat unterstützt drei Wege zum Aktualisieren: in der App, per CLI oder manuell. Alle drei tun unter der Haube dasselbe — das gepinnte Compose-Template eines getaggten Release ziehen, es anwenden und die Convex-Functions erneut deployen.
Option A: Update in der App (empfohlen)
Plattform-Admins sehen unter Einstellungen → System & Updates eine Benachrichtigung „Update verfügbar“, sobald eine neue Version veröffentlicht wurde. Klicken Sie auf Jetzt aktualisieren, bestätigen Sie, und die Web-App wird:
- Die gepinnte
docker-compose-<version>.ymlvon den GitHub Releases herunterladen - Sie an den Updater-Sidecar übergeben
- Neue Images ziehen, Container neu erstellen, Convex-Functions erneut deployen
- Überprüfen, dass die neue Version aktiv ist
Die Seite fragt die Container-Gesundheit ab und lädt sich nach Abschluss des Updates automatisch neu. Gesamtdauer: typischerweise 2–5 Minuten.
Option B: CLI owlat upgrade
Wird vom Installer nach /usr/local/bin/owlat installiert:
owlat upgrade # to latest
owlat upgrade --version 1.2.3 # to a specific version (useful for rollback)
Das CLI steuert denselben Updater-Sidecar, den auch der Ablauf in der App nutzt.
Option C: Manuell
Für Air-Gapped-Umgebungen oder wenn Sie Updates lieber selbst steuern:
# 1. Pull the pinned compose template for the target version
curl -fsSL https://github.com/wolvesdotink/owlat/releases/download/v1.2.3/docker-compose-1.2.3.yml \
-o docker-compose.yml
# 2. Pull the new images
docker compose pull
# 3. Recreate containers
docker compose up -d
# 4. Re-deploy Convex tenant functions
docker compose --profile deploy run --rm convex-deploy
Das Ziehen neuer Docker-Images aktualisiert die Container, die Convex-Serverless-Functions werden jedoch separat deployt. Der Weg in der App und über das CLI erledigen das für Sie; der manuelle Weg erfordert Schritt 4 oben.
Wiederherstellung nach einem fehlgeschlagenen Update
Schlägt ein Update mittendrin fehl, kann Ihr Stack in einem gemischten Zustand sein — einige Container auf der neuen Version, andere auf der alten. Der Updater fasst die Daten-Volumes nie an, und seit dem Stage-then-Promote-Ablauf ersetzt er docker-compose.yml erst, nachdem Images gezogen und Convex-Functions erfolgreich deployt wurden. Dennoch gilt: Erstellen Sie vor dem Update ein Backup (owlat backup) — ein Release mit einer brechenden Schemaänderung kann Daten zurücksetzen oder migrieren, und maßgeblich dafür sind die Release Notes.
Zuerst diagnostizieren
# What's running?
owlat status # or: docker compose ps
# What did each container log?
owlat logs web # follows the stream (Ctrl-C to exit); for a one-shot snapshot use: docker compose logs --tail=200 web
owlat logs mta
owlat logs convex
owlat logs updater
# Environment health check
owlat doctor # checks .env, required env vars, compose override, running services
Rollback auf die vorherige Version
Jedes getaggte Release hängt seine docker-compose-<version>.yml an die GitHub-Release-Seite an. So machen Sie ein Rollback:
Per CLI:
# Replace with the last-known-good version
owlat upgrade --version 1.2.2
Manuell:
# Download the previous release's compose file
curl -fsSL https://github.com/wolvesdotink/owlat/releases/download/v1.2.2/docker-compose-1.2.2.yml \
-o docker-compose.yml
# Pull the pinned images and recreate
docker compose pull
docker compose up -d
# Re-deploy functions at the old version
docker compose --profile deploy run --rm convex-deploy
Docker zieht die Images zu den gepinnten Tags (z. B. ghcr.io/wolvesdotink/web:1.2.2) und tauscht die Container an Ort und Stelle aus.
Wenn der Web-Container nicht startet
# See why
docker compose logs web
# Rule out a stale image
docker compose pull web
docker compose up -d --force-recreate web
Wenn Convex nicht startet
Convex hält die primäre Datenbank; Redis und ClamAV persistieren ebenfalls Daten, dazu kommen optionale Services (code-worker, ollama, IMAP-/ACME-Zertifikate), sofern deren Feature-Profile aktiviert sind. Wenn der Start scheitert, prüfen Sie zuerst den Speicherplatz auf dem Volume convex-data:
docker system df -v | grep convex-data
Ist die Festplatte voll, schaffen Sie Platz oder vergrößern Sie das zugrunde liegende Volume. Löschen Sie das Volume convex-data niemals — das ist Ihre Datenbank.
Letztes Mittel: aus dem Backup wiederherstellen
Ist der Stack in einem nicht mehr reparablen Zustand, stellen Sie das jüngste Backup-Archiv wieder her. Das owlat-CLI kapselt scripts/restore.sh:
owlat restore backups/owlat-YYYYMMDD-HHMMSS.tar.gz
# equivalently: bash scripts/restore.sh backups/owlat-YYYYMMDD-HHMMSS.tar.gz
Das stoppt den Stack, löscht die Volumes, befüllt sie aus dem Archiv neu (Convex, Redis und optional ClamAV) und fährt alles wieder hoch. Die aktuelle .env wird zuvor unter .env.before-restore-<timestamp> gesichert. Wie Sie solche Archive erzeugen und automatische Backups einrichten, steht unter Backups. Um wiederkehrende Backups einzurichten, ohne selbst Cron-Einträge zu basteln, führen Sie owlat backup-schedule enable aus — das installiert einen täglichen systemd-Timer (mit Cron als Fallback), der scripts/backup.sh ausführt; owlat backup-schedule disable entfernt ihn wieder.
Einen Update-Fehler melden
Schlägt ein Update auf eine Weise fehl, die Sie für einen Bug in Owlat selbst halten (und nicht für ein Problem Ihrer Umgebung), erfassen Sie Folgendes und hängen es an ein GitHub-Issue an:
owlat doctor > /tmp/owlat-doctor.txt 2>&1
docker compose ps > /tmp/owlat-ps.txt
docker compose logs --tail=500 > /tmp/owlat-logs.txt 2>&1
cat /opt/owlat/docker-compose.yml > /tmp/owlat-compose.yml
Einreichen unter: https://github.com/wolvesdotink/owlat/issues/new
Updates automatisieren
Es gibt bewusst keinen Cron-Job für unbeaufsichtigte Updates ab Werk. Zwei Gründe:
- Die Reihenfolge zählt: Functions müssen deployt werden, bevor die App-Container
neu starten (der Updater in der App und
owlat upgradeerledigen das für Sie). Ein naiverpull && up && deploy-Cron — wie ihn frühere Fassungen dieser Seite vorschlugen — startet die Container zuerst gegen ein altes Schema neu. - Vor 1.0 kann ein Release eine brechende Schemaänderung enthalten. Lesen Sie die Release Notes, bevor Sie ein Update anwenden; lassen Sie sie nicht blind per Cron einspielen.
Wenn Sie diese Kompromisse akzeptieren, automatisieren Sie owlat upgrade (das die
sichere Reihenfolge kapselt) und kombinieren es mit einem Backup vor dem Update:
# /etc/cron.d/owlat-update — automated upgrades, at your own risk
0 4 * * 0 root cd /opt/owlat && bash scripts/backup.sh && owlat upgrade
Halten Sie vor einem Update stets ein frisches Backup bereit. Owlat ist vor 1.0: Ein Release kann brechende Schemaänderungen enthalten, die bestimmte Tabellen zurücksetzen — die Release Notes weisen darauf hin, wenn das der Fall ist.
ClamAV-Signaturen
Der ClamAV-Container führt automatisch freshclamd aus, was täglich aktualisierte Virendefinitionen herunterlädt. Ein manueller Eingriff ist nicht nötig.
Um eine sofortige Signaturaktualisierung zu erzwingen:
docker compose exec clamav freshclam
Um die installierte Version der Signaturdatenbank direkt zu prüfen:
docker compose exec clamav sigtool --info /var/lib/clamav/daily.cld
(clamscan --version meldet die Version der ClamAV-Engine, nicht die der Signaturdatenbank.)
Redis-Wartung
Redis ist standardmäßig mit AOF-Persistenz (Append Only File) konfiguriert. Das stellt sicher, dass die MTA-Job-Queue Container-Neustarts übersteht.
- Kompaktierung — Redis schreibt die AOF-Datei automatisch neu, um sie kompakt zu halten.
- Arbeitsspeicher — überwachen Sie den Speicherverbrauch von Redis mit
docker compose exec redis redis-cli info memory. - Leeren — wenn Sie die Queue leeren müssen (z. B. nach einer Fehlkonfiguration):
docker compose exec redis redis-cli FLUSHALL. Das verwirft alle laufenden E-Mail-Jobs.
Wenn Sie Redis mit einem REDIS_PASSWORD abgesichert haben (siehe Redis-Authentifizierung), stellen Sie jedem redis-cli-Befehl -a "$REDIS_PASSWORD" --no-auth-warning voran, z. B. docker compose exec redis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning info memory.
Skalierung
MTA-Durchsatz
Erhöhen Sie WORKER_CONCURRENCY in Ihrer .env, um mehr E-Mail-Gruppen parallel zu verarbeiten:
# Default: 50 workers
WORKER_CONCURRENCY=100
Zum Anwenden den MTA neu starten: docker compose restart mta
Server-Dimensionierung
| Last | vCPU | RAM | Festplatte |
|---|---|---|---|
| Bis zu 10.000 Kontakte | 2 | 4 GB | 40 GB |
| Bis zu 100.000 Kontakte | 4 | 8 GB | 80 GB |
| 100.000+ Kontakte | 8 | 16 GB | 160 GB |
Convex-Backend
Convex ist ein Single-Node-Service, der vertikal skaliert. Überwachen Sie die Festplattennutzung des Volumes convex-data — dort werden alle Datenbankeinträge, hochgeladenen Dateien und Vektorindizes gespeichert.
# Check volume disk usage
docker system df -v | grep convex-data
Fehlerbehebung
Convex startet nicht
docker compose logs convex
Häufige Ursachen:
INSTANCE_SECRETist nicht gesetzt — prüfen Sie, ob Ihre.env-Datei eine gültige Hex-Zeichenkette enthält- Festplatte voll — das Volume
convex-databenötigt freien Speicher für die Datenbank - Port-Konflikt — ein anderer Service belegt Port 3210 oder 3211
Der MTA kann keine E-Mails versenden
docker compose logs mta
Häufige Ursachen:
MTA_API_URList in der Convex-Laufzeit nicht gesetzt — die häufigste Ursache nach einer manuellen Installation.MTA_API_URL(undMTA_API_KEY) müssen in das Convex-Deployment übertragen werden, nicht nur in die Compose-.env; ohne sie löst der Versand einen harten FehlerNo system email transport configuredaus (apps/api/convex/systemMail.ts), bevor der MTA überhaupt erreicht wird. Prüfen Sie das mitnpx convex env list(oder über das Dashboard) und setzen Sie den Wert aufhttp://mta:3100. Der Assistentowlat quickstarterledigt das für Sie.- Der EHLO-Hostname passt nicht zum PTR-Record — empfangende Server weisen die Verbindung ab. Prüfen Sie mit
dig -x YOUR_IP +short - Das JSON in DKIM_KEYS ist ungültig — validieren Sie das JSON:
echo $DKIM_KEYS | jq . - Port 25 blockiert — viele Cloud-Anbieter (AWS, GCP, Azure) blockieren ausgehendes SMTP standardmäßig. Beantragen Sie die Freigabe von Port 25 oder nutzen Sie ein E-Mail-Relay
- MTA_API_KEY stimmt nicht überein — der Key in der Docker-
.envmuss dem in den Convex-Umgebungsvariablen gesetzten entsprechen
ClamAV startet langsam
Das ist normal. ClamAV lädt beim Start die Virendefinitionen in den Arbeitsspeicher und beim allerersten Start zusätzlich die vollständige Signaturdatenbank (~300 MB) herunter — auf einem kleinen VPS kann das mehrere Minuten dauern. Der Docker-Healthcheck hat dafür ein start_period: 600s.
Der MTA wartet, bis ClamAV healthy ist, bevor er startet (konfiguriert über depends_on in Docker Compose).
Die Web-Oberfläche zeigt einen Verbindungsfehler
Der Browser muss das Convex-Backend direkt erreichen. Wenn NUXT_PUBLIC_CONVEX_URL einen Docker-internen Hostnamen verwendet (etwa http://convex:3210), kann der Browser keine Verbindung aufbauen.
Abhilfe: Setzen Sie NUXT_PUBLIC_CONVEX_URL auf eine aus dem Browser erreichbare URL:
- Lokale Entwicklung:
http://localhost:3210 - Produktion:
https://api.example.com(über den Reverse Proxy)
Das Deployment der Functions schlägt fehl
docker compose --profile deploy run --rm convex-deploy 2>&1
Häufige Ursachen:
- CONVEX_ADMIN_KEY ist falsch oder fehlt — neu erzeugen:
docker compose exec convex ./generate_admin_key.sh - Der Convex-Container ist nicht healthy — mit
docker compose psprüfen - Schemakonflikt — wenn Sie Convex-Schemadateien geändert haben, suchen Sie in der Deploy-Ausgabe nach Validierungsfehlern
Umzug in die Produktion
So wechseln Sie von einem lokalen Entwicklungs-Setup zu einem Produktions-Deployment:
- URLs aktualisieren in
.env:NUXT_PUBLIC_CONVEX_URL=https://api.example.com NUXT_PUBLIC_CONVEX_SITE_URL=https://rest.api.example.com NUXT_PUBLIC_SITE_URL=https://owlat.example.com - DNS einrichten — A-Records, PTR, SPF, DKIM und DMARC konfigurieren. Siehe DNS- & E-Mail-Setup.
- Reverse Proxy ergänzen — Caddy oder Nginx mit TLS. Siehe Produktions-Deployment.
- Redis absichern —
REDIS_PASSWORDergänzen, wie unter Produktions-Deployment beschrieben. - Convex-Umgebungsvariablen aktualisieren, damit sie zu den neuen URLs passen:
npx convex env set SITE_URL "https://owlat.example.com" --url http://localhost:3210 --admin-key <key> # CONVEX_SITE_URL is a Convex BUILT-IN — do not set it via `convex env set` # (the CLI rejects it). It derives from CONVEX_SITE_ORIGIN on the convex # container, which docker-compose interpolates from NUXT_PUBLIC_CONVEX_SITE_URL. npx convex env set ALLOWED_ORIGINS "https://owlat.example.com" --url http://localhost:3210 --admin-key <key> - Stack neu starten:
docker compose up -d - Überprüfen — senden Sie eine Test-E-Mail und prüfen Sie die Zustellung mit mail-tester.com.