Self-Hosting-Übersicht¶
Diese Seite ist die Referenz für Operations-Aufgaben rund um Vesana. Wenn du Vesana für andere hostest oder bei einem Kunden eine Instanz pflegst: hier sind die Hebel.
Verzeichnisstruktur¶
Auf dem Host selbst liegen in /opt/vesana/ nur Konfigurationsdateien:
/opt/vesana/
├── docker-compose.prod.yml # Compose-Stack-Definition (gehört Vesana, wird bei Updates ersetzt)
├── docker-compose.override.yml # optional: deine eigenen Ergänzungen (bleibt bei Updates erhalten)
├── .env # Secrets + Konfiguration (Klartext-Umgebungsvariablen, nur für root lesbar)
├── .env.example # Vorlage mit allen Variablen
└── secrets/ # Kopie der generierten Geheimnisse (nur root; wirksam ist allein die .env)
Dazu kommen kleine Hilfsdateien des Installers (z. B. .vesana-ac-autoinstall.sh für die Active-Checker-Einrichtung) und ggf. admin-nginx/, das der Split-Container-Assistent beschreibt.
Eigene Netze, Labels, Ressourcen-Grenzen oder Bind-Mounts gehören nie in docker-compose.prod.yml, sondern in docker-compose.override.yml — siehe Eigene Anpassungen am Stack.
Alles andere — SSL-Zertifikate, Backups, Agent-/Collector-Binaries, Uploads, Icon-Assets, Avatare — liegt in benannten Docker-Volumes, nicht als Verzeichnis unter /opt/vesana. Das hat den Vorteil, dass ein docker compose down (ohne -v) niemals versehentlich Daten aus einem Host-Verzeichnis mitreißt.
Willst du in ein Volume hineinschauen oder etwas herauskopieren, geht das über einen Wegwerf-Container:
# Beispiel: Inhalt eines Volumes auflisten
docker run --rm -v vesana_backup-data:/data alpine ls -la /data
# Beispiel: Datei aus einem Volume herauskopieren
docker run --rm -v vesana_backup-data:/src -v $(pwd):/dst alpine \
sh -c 'cp /src/irgendeine-datei /dst/'
(Volume-Namen tragen üblicherweise den Compose-Projekt-Präfix, z. B. vesana_backup-data — mit docker volume ls prüfen, falls der Präfix bei dir abweicht.)
Optionale Compose-Profile¶
Optionale Profile schalten zusätzliche Services an:
| Profil | Service | Wann |
|---|---|---|
| Default (kein Profil) | postgres, redis, init, init-binaries, api, receiver, worker, worker-scheduler, nginx, updater | Immer |
ai |
ollama | AI-Features mit lokalem Ollama |
agent-gateway |
agent-gateway | Separater Port nur für Agent-/Collector-Endpunkte (Weboberfläche kann dann per Firewall abgeschottet werden) — siehe Distribution & Erreichbarkeit |
admin-split, admin-split-port |
api-admin, nginx-admin | Eigener Admin-Container — setzt der Split-Container-Assistent, nie von Hand |
Backups sind kein Profil mehr — das eingebaute DR-Backup-System (siehe Backup & Disaster-Recovery) läuft immer mit, ohne separaten Sidecar.
Aktivieren:
Oder dauerhaft über die .env:
Wichtige Umgebungsvariablen¶
Die .env wird vom Setup-Script generiert. Wichtige Variablen:
Pflicht¶
| Variable | Bedeutung |
|---|---|
BASE_URL |
Öffentliche URL inkl. https:// |
POSTGRES_PASSWORD |
Generiert |
REDIS_PASSWORD |
Generiert |
SECRET_KEY |
Signaturschlüssel für Login-Tokens, generiert |
FIELD_ENCRYPTION_KEY |
AES-256-GCM-Key für Feldverschlüsselung, generiert |
UPDATER_SHARED_SECRET |
Geheimer Header zwischen API und Updater, generiert. Leer = ältere Installationen ohne diesen Schutz; nachrüsten durch Setzen eines zufälligen Werts (z. B. openssl rand -hex 32) und Neustart des Stacks |
VESANA_SETUP_TOKEN |
Einmal-Code für den Setup-Wizard, generiert; nach dem Abschluss bedeutungslos |
Optional / Tuning¶
| Variable | Default | Bedeutung |
|---|---|---|
WORKER_REPLICAS |
1 |
Anzahl Consumer-Worker-Container |
WORKER_CONCURRENCY |
4 |
Parallelität pro Worker |
WORKER_BATCH_SIZE |
100 |
Batch-Größe pro DB-Insert-Durchlauf |
DB_POOL_SIZE |
10 |
Größe des DB-Connection-Pools |
DB_MAX_OVERFLOW |
20 |
Zusätzliche Connections über den Pool hinaus, bei Bedarf |
PG_SHARED_BUFFERS |
nach RAM, siehe unten | Postgres-Puffer |
PG_WORK_MEM |
16MB |
Sort-/Hash-Buffer pro Operation |
PG_EFFECTIVE_CACHE |
nach RAM, siehe unten | Postgres-Planner-Annahme (belegt keinen Speicher) |
PG_MAX_CONNECTIONS |
200 |
Connection-Limit |
PG_SHM_SIZE |
nach RAM, siehe unten | Obergrenze für /dev/shm des Postgres-Containers (parallele Abfragen) |
PG_MAINTENANCE_WORK_MEM |
nach RAM, siehe unten | Speicher-Deckel für Vacuum/Index-Wartung — ohne diesen Wert leitet die automatische Postgres-Tuning-Logik den Wert aus dem gesamten Host-RAM ab, was auf kleinen Maschinen zu OOM führen kann |
REDIS_MAXMEMORY |
512mb |
Redis-Speicherlimit (noeviction-Policy — Redis lehnt neue Daten ab statt alte zu verwerfen) |
HTTP_PORT / HTTPS_PORT |
80 / 443 |
Wenn andere Dienste die Ports belegen |
AGENT_GATEWAY_PORT |
8443 |
Nur relevant mit aktivem agent-gateway-Profil |
AI_ENABLED |
false |
Vorgabe für die KI-Funktionen, solange unter Admin → System → KI nichts gespeichert ist |
LICENSE_KEY |
leer | Lizenzschlüssel (wirkt ohne erneute Eingabe in der Oberfläche) |
VESANA_VERSION |
latest |
Image-Tag; der Updater schreibt hier die installierte Version hinein |
COMPOSE_PROJECT_DIR |
/opt/vesana |
Installationsverzeichnis, das der Updater aktualisiert (setzt der Installer bei VESANA_DIR) |
VESANA_PULSE |
on |
off schaltet den täglichen Instanz-Puls ab |
VESANA_NGINX_KEEPALIVE |
leer (an) | off = nginx baut je Anfrage eine neue Verbindung zu API und Receiver auf (Notschalter) |
Postgres-Speicher nach Arbeitsspeicher¶
Bei einer Neuinstallation leitet setup.sh die Postgres-Werte der Tabelle aus dem Arbeitsspeicher des Servers ab und schreibt sie in die .env. Die Werte sind bewusst zurückhaltend, weil sich Postgres den Server mit API, Worker, Receiver, Redis und gegebenenfalls Ollama teilt:
| Arbeitsspeicher | PG_SHARED_BUFFERS |
PG_EFFECTIVE_CACHE |
PG_MAINTENANCE_WORK_MEM |
PG_SHM_SIZE |
|---|---|---|---|---|
| bis 2 GB | 256MB | 512MB | 256MB | 512m |
| 4 GB | 512MB | 2GB | 256MB | 512m |
| 8 GB | 1GB | 4GB | 256MB | 512m |
| 16 GB | 2GB | 8GB | 512MB | 512m |
| 32 GB | 4GB | 16GB | 512MB | 1g |
| 64 GB und mehr | 8GB | 32GB | 1GB | 1g |
Die Grenzen liegen zwischen den üblichen Größen (unter 3, 6, 12, 24 und 48 GB), weil ein Server etwas weniger meldet als seinen Nennwert. PG_WORK_MEM und PG_MAX_CONNECTIONS bleiben unabhängig vom Arbeitsspeicher bei 16MB bzw. 200 — beide vervielfachen sich je Abfrage bzw. Verbindung.
PG_SHM_SIZE ist die Obergrenze für /dev/shm im Postgres-Container (keine Reservierung). Dort legen parallele Abfragen ihren gemeinsamen Speicher an; Dockers Standard von 64 MB reicht schon für einen parallelen Hash-Join über einige Millionen Zeilen nicht — die Abfrage bricht dann mit could not resize shared memory segment … No space left on device ab. Der Wert wirkt mit der Compose-Datei ab Oktober 2026 (shm_size am Dienst postgres); ohne Eintrag in der .env gilt dort 512m.
- Bestehende Installationen ändern sich nicht. Der Installer fasst eine vorhandene
.envnie an; ein Update ändert die Werte ebenfalls nicht. - Die Größen-Auswahl im Einrichtungs-Assistenten senkt die Werte nicht, sie kann sie nur anheben. Unter Ressourcen → Leistung wendet ein Profil seine Werte dagegen genau so an, wie es sie anzeigt.
- Ohne Ableitung installieren:
VESANA_PG_SIZING=defaultbeim Aufruf vonsetup.shsetzen — dann gelten die Werte der.env.example(256MB / 512MB / 256MB / 512m). - Wann von Hand zurückstellen: wenn der Server weitere speicherhungrige Dienste trägt (z. B. ein großes Ollama-Modell) und der Arbeitsspeicher knapp wird. Die Zeilen in der
.envanpassen unddocker compose up -dausführen — Postgres startet dabei kurz neu.
Die vier Sizing-Profile (Klein/Mittel/Groß/XL) unter Ressourcen → Leistung setzen WORKER_REPLICAS, WORKER_CONCURRENCY, PG_SHARED_BUFFERS, PG_EFFECTIVE_CACHE, PG_WORK_MEM, PG_MAINTENANCE_WORK_MEM, PG_MAX_CONNECTIONS, DB_POOL_SIZE/DB_MAX_OVERFLOW und REDIS_MAXMEMORY in einem Rutsch — für die meisten Setups einfacher als einzelne Variablen von Hand zu justieren.
Vollständige Liste der verfügbaren Variablen in der mitgelieferten .env.example. Nach Änderungen: docker compose up -d zum Übernehmen.
SSL / TLS¶
Standard: automatisches selbstsigniertes Zertifikat¶
Beim ersten Start generiert Vesana automatisch ein selbstsigniertes Zertifikat — dadurch läuft der Setup-Wizard immer über HTTPS, auch ganz ohne eigene Domain oder eigenes Zertifikat. Dein Browser zeigt dafür eine Zertifikatswarnung, bis du ein echtes Zertifikat einspielst.
Zertifikat direkt aus Vesana (empfohlen)¶
Admin → System → Zertifikat stellt ein öffentliches Zertifikat selbst aus und erneuert es: Let's Encrypt oder eine eigene ACME-CA, geprüft über einen DNS-Anbieter (über 200 Anbieter, z. B. OVH, Cloudflare, IONOS, Hetzner, RFC2136 für Windows-DNS) oder über Port 80. Ein eigenes, gekauftes Zertifikat lädt man auf derselben Seite hoch. Kein certbot, kein Cron-Job, keine Änderung an der Compose-Datei — Details: TLS / Zertifikat.
Eigenes Zertifikat von Hand einspielen¶
Wer certbot auf dem Host behalten will: Zertifikat und Key liegen im Container unter /etc/nginx/ssl/fullchain.pem und /etc/nginx/ssl/privkey.pem — das ist ein benanntes Docker-Volume, kein Host-Verzeichnis. Eigenes Zertifikat reinkopieren:
docker run --rm \
-v vesana_ssl:/etc/nginx/ssl \
-v /pfad/zu/deinem/cert:/src:ro \
alpine sh -c 'cp /src/fullchain.pem /src/privkey.pem /etc/nginx/ssl/'
docker compose -f /opt/vesana/docker-compose.prod.yml restart nginx
Solange gültige Dateien unter diesen beiden Namen im Volume liegen, überschreibt Vesana sie beim Neustart nicht mit einem neuen selbstsignierten Zertifikat — Erneuerung musst du dann selbst per Cron-Job wiederholen. Vesana erkennt so ein Zertifikat, überschreibt es nie still und warnt über den Check „TLS Certificate", bevor es abläuft.
Hinter eigenem Reverse-Proxy¶
Wenn der Server bereits hinter einem eigenen nginx / Traefik / HAProxy / Nginx Proxy Manager steht, terminiere TLS dort und proxiere intern auf den Vesana-Webserver-Container. Details zu Reverse-Proxy-Besonderheiten (SSE-Buffering, WebSocket-Upgrade): Distribution & Erreichbarkeit. Wie du den Webserver in das Docker-Netz deines Proxys hängst (auch über mehrere Hosts per Overlay-Netz), ohne dass ein Update es rückgängig macht, und was dabei für echte Client-Adressen und das Agent-Gateway gilt: Eigene Anpassungen am Stack.
Updates & Backups¶
- Updates — GUI-Updater, Online + Offline + Notfall-CLI, kein Auto-Rollback
- Backup & Restore — eingebautes DR-System, mehrere Zeitpläne, Disaster-Drill
Anschluss¶
- Ressourcen — Speicher, RAM, Leistung — Sizing-Profile im Detail
- Distribution & Erreichbarkeit
- Sicherheit — Härtungs-Checkliste