Installation
Eviworx wird mit Docker Compose installiert. Diese Anleitung führt dich durch die Installation Schritt-für-Schritt. Die Architektur basiert auf 12 Containern mit Traefik als API-Gateway für TLS-Terminierung, Routing und Security-Header.
Voraussetzungen
- Docker: Version 24.0+ (
docker --version) - Docker Compose: Version 2.20+ (
docker compose version) - Freier Speicher: Mind. 20 GB
- RAM: Mind. 8 GB (empfohlen: 16 GB)
- Betriebssystem: Linux (Ubuntu 22.04+, Debian 11+, RHEL 8+)
- Netzwerk: Ports 80 und 443 verfügbar (Traefik)
- SSL/TLS: Zertifikat (cert.pem + cert.key) für Traefik
Installation Schritt-für-Schritt
Schritt 1: Deployment-Repository klonen & Registry-Login
# Clone deployment repository (contains docker-compose.yaml + Traefik configuration)
git clone https://github.com/eviworx/eviworx-deploy.git eviworx
cd eviworx
# Registry login (for private container images)
# Registry host is provided by Eviworx
docker login <your-registry>
Hinweis: Das Repository und die Registry sind privat. Kontaktiere info@eviworx.com für Zugangsdaten.
Nach dem Klonen hast du folgende Ordnerstruktur:
eviworx/
docker-compose.yaml # Compose file (from the repo)
.env.example # Template for secrets & configuration
certs/ # Directory for TLS certificates (empty)
traefik/
traefik.yml # Traefik Static Config
dynamic.yml # Traefik Routing Config
Schritt 2: SSL-Zertifikat bereitstellen
Traefik benötigt ein TLS-Zertifikat (PEM-Format). Platziere dein Zertifikat im certs-Verzeichnis:
# Provide certificate files:
cp /path/to/your/cert.pem ./certs/cert.pem
cp /path/to/your/cert.key ./certs/cert.key
# Or self-signed certificate for development:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ./certs/cert.key \
-out ./certs/cert.pem \
-subj "/CN=localhost"
Schritt 3: Umgebungsvariablen konfigurieren
Alle Secrets und Konfigurationswerte werden über eine .env-Datei verwaltet. Erstelle diese aus der mitgelieferten Vorlage:
.env-Datei erstellen
# Create .env from template and adjust
cp .env.example .env
nano .env
Sichere Passwörter/Keys generieren
# All secrets as hex strings (no special characters, URL-safe)
openssl rand -hex 32 # for POSTGRES_PASSWORD, REDIS_PASSWORD, SHARE_SECRET, INTERNAL_API_KEY
openssl rand -hex 48 # for JWT_SECRET (slightly longer recommended)
openssl rand -hex 32 # for LICENSE_ENCRYPTION_KEY
openssl rand -hex 32 # for TWO_FACTOR_ENCRYPTION_KEY
openssl rand -hex 32 # for JOBWORKER_DB_PASSWORD
openssl rand -hex 32 # for READONLY_DB_PASSWORD
Inhalt der .env-Datei
# =============================================
# Eviworx — Environment Configuration (.env)
# =============================================
# --- Domain / Frontend URL ---
FRONTEND_URL=https://helpdesk.example.com
# --- Database ---
POSTGRES_USER=helpdesk_user
POSTGRES_PASSWORD=YOUR_STRONG_PASSWORD
POSTGRES_DB=helpdesk_db
JOBWORKER_DB_PASSWORD=YOUR_STRONG_PASSWORD
READONLY_DB_PASSWORD=YOUR_STRONG_PASSWORD
# --- Redis ---
REDIS_PASSWORD=YOUR_STRONG_PASSWORD
# --- JWT (session token) ---
JWT_SECRET=YOUR_STRONG_PASSWORD
# --- Share token (time-limited public share links) ---
# REQUIRED — backend starts with a fatal error if not set!
SHARE_SECRET=YOUR_STRONG_PASSWORD
# --- Internal API Key (service-to-service) ---
INTERNAL_API_KEY=YOUR_64_HEX_CHARS
# --- Encryption Keys ---
LICENSE_ENCRYPTION_KEY=YOUR_64_HEX_CHARS
TWO_FACTOR_ENCRYPTION_KEY=YOUR_64_HEX_CHARS
# --- Web Push (VAPID, optional) ---
# Generate once: npx web-push generate-vapid-keys
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
VAPID_SUBJECT=mailto:admin@example.com
# --- Admin (only on the very first start) ---
ADMIN_INITIAL_PASSWORD=StrongPassword123!
# --- Licensing ---
# Without an entry: trial mode (30 days, max. 3 agents)
# LICENSE_KEY=EVI-XXXX-XXXX-XXXX
# LICENSE_SECRET=your-license-secret-from-vendor
# --- Optional: Reverse Proxy / Load Balancer ---
# If Eviworx runs behind an external reverse proxy:
# TRUSTED_PROXIES=217.89.98.0/24,203.0.113.0/24
# --- Optional: Cloudflare Turnstile CAPTCHA ---
# TURNSTILE_SITE_KEY=
# TURNSTILE_SECRET_KEY=
# --- Optional: Email branding ---
# EMAIL_ACCENT_COLOR=#3b8f93
# EMAIL_APP_NAME=Eviworx
# EMAIL_APP_URL=https://helpdesk.example.com
# EMAIL_FOOTER_TEXT=Eviworx 2026
# --- Optional: Report generator ---
# COMPANY_NAME=Company Inc.
# CSV_DELIMITER=;
Sicherheit: Die .env-Datei ist in .gitignore eingetragen und wird NICHT ins Repository committed. Niemals Secrets in Git committen!
Schritt 4: Container starten
# Pull images from the registry
docker compose pull
# Start the stack
docker compose up -d
Beim ersten Start werden automatisch:
- Datenbank initialisiert (PostgreSQL)
- Restricted DB-User erstellt (helpdesk_jobworker, helpdesk_readonly)
- Datenbankschema per Migration angelegt
- System-Rollen erstellt (Admin, Agent, Approver, End User, Datenschutzbeauftragter)
- Default-Admin-User erstellt (wenn SEED_DATABASE=true)
- ClamAV Virus-Signaturen heruntergeladen (~3 Minuten)
- Traefik initialisiert (TLS, Routing, Security-Headers)
Wichtig: Der erste Start dauert 3-5 Minuten (ClamAV muss Virus-Signaturen laden). Warte bis alle Container "healthy" sind.
Schritt 5: Installation verifizieren
# Check container status
docker compose ps
# Expected output: All containers "healthy" or "running"
# NAME STATUS
# eviworx-traefik Up (healthy)
# eviworx-frontend Up (healthy)
# eviworx-backend Up (healthy)
# eviworx-job-worker Up (healthy)
# eviworx-email-worker Up (healthy)
# eviworx-notification-worker Up (healthy)
# eviworx-workflow-engine Up (healthy)
# eviworx-report-generator Up (healthy)
# eviworx-av-worker Up (healthy)
# eviworx-db Up (healthy)
# eviworx-redis Up (healthy)
# eviworx-clamav Up (healthy)
# Check backend health
curl -k https://localhost/api/health/live
# Expected: {"status":"alive"}
# Check logs (if issues)
docker compose logs -f backend
docker compose logs -f traefik
docker compose logs -f clamav # ClamAV takes longest to start
Erste Anmeldung
Nach erfolgreicher Installation (alle Container "healthy"), öffne deinen Browser:
https://your-domain.com
# Traefik automatically redirects HTTP to HTTPS
Standard-Zugangsdaten (SEED_DATABASE=true)
| Rolle | Password | Berechtigungen | |
|---|---|---|---|
| Admin | admin@company.com |
ADMIN_INITIAL_PASSWORD |
Volle Admin-Rechte |
Das Passwort wird über die Umgebungsvariable ADMIN_INITIAL_PASSWORD gesetzt (Default: ChangeMeNowXx). Dieses wird NUR beim ersten Start mit leerer Datenbank verwendet.
KRITISCH: Ändere das Admin-Passwort sofort nach der ersten Anmeldung! Erstelle weitere Benutzer über die Einladungsfunktion oder die Benutzerverwaltung.
Post-Installation: Secrets ändern
1. Admin-Passwort ändern & MFA aktivieren
Melde dich als Admin an:
- Passwort ändern: Benutzermenü → Einstellungen → Sicherheit
- MFA aktivieren: Benutzermenü → Einstellungen → Sicherheit → Zwei-Faktor-Authentifizierung
2. SEED_DATABASE deaktivieren
Nach dem ersten erfolgreichen Start, deaktiviere das Re-Seeding:
# Edit .env
nano .env
# Set:
SEED_DATABASE=false
# Restart container
docker compose up -d backend
3. Lizenz aktivieren
Eviworx startet automatisch im Trial-Modus (30 Tage, max. 3 Agents). Für den Produktiveinsatz trage deinen Lizenz-Key in die .env ein:
# In .env:
LICENSE_KEY=EVI-XXXX-XXXX-XXXX
LICENSE_SECRET=your-license-secret-from-vendor
# Restart backend
docker compose up -d backend
Alternativ direkt in der UI: Admin-Center → System → Produktlizenz → Online-Aktivierung — Vollständige Lizenz-Dokumentation →
4. Allgemeine Einstellungen konfigurieren
Firmenname und Application-URL werden in der Oberfläche konfiguriert:
- Admin-Center → System → Allgemein → Firmenname
- Admin-Center → System → Allgemein → Application URL
Diese Werte werden dynamisch für QR-Codes, PDF-Labels, E-Mail-Templates und andere Funktionen verwendet. Den Firmennamen in Report-Exporten setzt der Report-Generator über seine eigene Variable COMPANY_NAME, siehe Umgebungsvariablen – Referenz.
Traefik API-Gateway
Traefik v3 dient als zentrales API-Gateway und übernimmt:
- TLS-Termination: HTTPS mit konfigurierbaren Cipher-Suites (TLS 1.2+)
- Routing:
/api/*→ Backend,/socket.io→ Backend (WebSocket),/*→ Frontend - Security: HSTS, CSP, X-Frame-Options, Rate-Limiting (100 req/s, Burst 200)
- Interne Dienst-Endpunkte: werden extern blockiert (nur im Container-Netz erreichbar)
- HTTP → HTTPS: Automatische Weiterleitung
- Compression: Gzip-Komprimierung für API und Frontend
Externer Reverse Proxy / Load Balancer
Wenn Eviworx hinter einem externen Reverse Proxy (z.B. Nginx, HAProxy) betrieben wird, müssen zwei Stellen konfiguriert werden, damit Protokolle und IP-basierte Rate-Limits die echte Client-IP sehen und nicht die des Proxys:
1. Backend — TRUSTED_PROXIES in .env
# In .env:
TRUSTED_PROXIES=217.89.98.0/24,203.0.113.0/24
Komma-separierte CIDR-Ranges. Docker-interne und private Netzwerke (172.16.0.0/12, 10.0.0.0/8, 192.168.0.0/16) werden automatisch vertraut.
2. Traefik — forwardedHeaders.trustedIPs in traefik.yml
Ergänze die CIDR-Range deines externen Proxys in der trustedIPs-Liste beider Entrypoints (web + websecure), damit Traefik den X-Forwarded-For Header nicht überschreibt:
# traefik/traefik.yml
entryPoints:
web:
forwardedHeaders:
trustedIPs:
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
- "217.89.98.0/24" # ← CIDR deines Proxys websecure:
forwardedHeaders:
trustedIPs:
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
- "217.89.98.0/24" # ← CIDR deines Proxys
Nach Änderung Traefik neu starten: docker compose restart traefik
Traefik-Konfiguration
Die Konfiguration besteht aus zwei Dateien:
traefik/traefik.yml– Statische Konfiguration (Entrypoints, Logging)traefik/dynamic.yml– Dynamische Konfiguration (Routers, Services, Middlewares, TLS)
# Check Traefik logs
docker compose logs -f traefik
# Access log format: JSON (machine-readable)
# Fields: X-Request-ID, User-Agent (other headers dropped)
Volumes & Persistenz
Eviworx nutzt 6 Docker-Volumes für persistente Daten:
| Volume | Zweck | Wichtigkeit |
|---|---|---|
postgres_data |
Datenbank (alle Tickets, Assets, etc.) | KRITISCH - Backup erforderlich! |
redis_data |
Job-Queue & Cache | Wichtig - AOF-Persistenz |
uploads |
Hochgeladene Dateien (Attachments) | KRITISCH - Backup erforderlich! |
quarantine |
Infizierte Dateien (7 Tage Retention) | Optional - kann gelöscht werden |
clamav_data |
Virus-Signaturen (~1 GB) | Kann neu geladen werden |
sourcemaps |
JS-Sourcemaps der fünf neuesten Releases (Frontend schreibt, Backend liest read-only für Error-Tracking) | Wird beim Start neu befüllt, ca. 100-500 MB |
Volume-Backup
# Backup PostgreSQL
docker compose exec db pg_dump -U helpdesk_user helpdesk_db > backup_$(date +%Y%m%d).sql
# Backup uploads (attachments)
docker run --rm -v eviworx_uploads:/data -v $(pwd):/backup alpine tar czf /backup/uploads_$(date +%Y%m%d).tar.gz -C /data .
Umgebungsvariablen-Referenz
Alle Umgebungsvariablen mit Standardwerten und Beschreibung stehen in der Umgebungsvariablen – Referenz.
Secrets generieren
Alle Secrets werden als Hex-Strings generiert (keine Sonderzeichen, URL-sicher), in der Regel mit 64 Zeichen:
# Generate a dedicated key for EACH secret:
openssl rand -hex 48 # → JWT_SECRET
openssl rand -hex 32 # → SHARE_SECRET (REQUIRED!)
openssl rand -hex 32 # → INTERNAL_API_KEY
openssl rand -hex 32 # → LICENSE_ENCRYPTION_KEY (exactly 32 bytes!)
openssl rand -hex 32 # → TWO_FACTOR_ENCRYPTION_KEY (exactly 32 bytes!)
openssl rand -hex 32 # → POSTGRES_PASSWORD
openssl rand -hex 32 # → JOBWORKER_DB_PASSWORD
openssl rand -hex 32 # → READONLY_DB_PASSWORD
openssl rand -hex 32 # → REDIS_PASSWORD
# Enter all generated values into .env
Troubleshooting
Traefik startet nicht / SSL-Fehler
# Check Traefik logs
docker compose logs traefik
# Most common cause: certificate files missing
ls -la ./certs/cert.pem ./certs/cert.key
# Check whether ports 80/443 are already in use
sudo lsof -i :80
sudo lsof -i :443
ClamAV startet nicht / bleibt unhealthy
# Check ClamAV logs
docker compose logs clamav
# Most common cause: not enough RAM
# Solution: increase Docker RAM to at least 4 GB
# ClamAV needs 3-5 minutes on first start
# Wait until Freshclam has loaded the signatures:
docker compose logs clamav | grep -i "Database updated"
Backend startet nicht (Migration-Fehler)
# Check backend logs
docker compose logs backend
# Common errors:
# 1. Database not ready yet
# → Wait 30s and check: docker compose ps db
# 2. DATABASE_URL wrong
# → Check password in .env (must match POSTGRES_PASSWORD)
# 3. Prisma migration failed
# → Run manually:
docker compose exec backend npx prisma migrate deploy
Worker verbinden nicht zum Backend
# Check backend is reachable
docker compose exec job-worker curl http://backend:3000/api/health/live
# Check INTERNAL_API_KEY in all worker services
# MUST be identical everywhere:
docker compose config | grep INTERNAL_API_KEY
# Most common error: backend not healthy yet
docker compose ps backend
# STATUS should be "Up (healthy)"
Redis-Verbindungsfehler
# Check whether Redis is running and the password is correct
docker compose exec redis redis-cli -a YOUR_REDIS_PASSWORD --no-auth-warning ping
# Expected: PONG
# Check REDIS_URL in all services (must contain the password!)
docker compose config | grep REDIS_URL
Erweiterte Konfiguration
FIPS 140-2 Modus
Eviworx verwendet FIPS 140-2 kompatible Algorithmen (keine offizielle Zertifizierung). Im Standard-Modus werden bereits FIPS-kompatible Algorithmen verwendet (PBKDF2-SHA512, AES-256-GCM, HMAC-SHA256). Im optionalen FIPS-Modus prüft das Backend beim Start, dass Node.js im FIPS-Modus läuft (OpenSSL-FIPS-Provider), und startet sonst nicht:
# Enable FIPS mode (set in .env):
ENABLE_FIPS=true
# Restart container
docker compose up -d backend
Mehrere Worker-Instanzen (HA)
Worker-Services lassen sich auf mehrere Instanzen skalieren. Voraussetzungen und Grenzen: Skalierung & Hochverfügbarkeit →
- ☐
JWT_SECRETgeändert (mind. 32 Bytes) - ☐
SHARE_SECRETgesetzt (PFLICHT — Backend startet sonst nicht!) - ☐
INTERNAL_API_KEYgeändert (mind. 32 Bytes) - ☐
LICENSE_ENCRYPTION_KEYgeändert (genau 32 Bytes!) - ☐
TWO_FACTOR_ENCRYPTION_KEYgeändert (genau 32 Bytes!) - ☐
REDIS_PASSWORDgeändert (in allen Services!) - ☐ Alle Datenbank-Passwörter geändert
- ☐
ADMIN_INITIAL_PASSWORDgesetzt (sicheres Passwort!) - ☐
SEED_DATABASE=falsenach erstem Start - ☐
FRONTEND_URLauf echte Domain gesetzt - ☐ SSL/TLS Zertifikat konfiguriert (Traefik)
- ☐ Admin-Passwort nach Login geändert + MFA aktiviert
- ☐ Firmenname & Application-URL in Settings konfiguriert
Nützliche Befehle
Container-Verwaltung
# Start all containers
docker compose up -d
# Restart a single container
docker compose restart backend
# Pull new version (after update notification)
docker compose pull && docker compose up -d
# Stop containers
docker compose stop
# Stop AND remove containers (volumes remain!)
docker compose down
# WARNING: Delete all volumes (DATA LOSS!)
docker compose down -v # ONLY for a full reset!
# View logs (all containers log in JSON format)
docker compose logs -f backend
docker compose logs --tail=100 traefik
docker compose logs --tail=100 clamav
# Open a shell in a container
docker compose exec backend sh
docker compose exec db psql -U helpdesk_user helpdesk_db
Datenbank-Management
# PostgreSQL Shell
docker compose exec db psql -U helpdesk_user helpdesk_db
# Apply migrations (manually)
docker compose exec backend npx prisma migrate deploy
# Prisma Studio (DB admin UI)
docker compose exec backend npx prisma studio
# Database Backup
docker compose exec db pg_dump -U helpdesk_user helpdesk_db > backup.sql
# Database Restore
cat backup.sql | docker compose exec -T db psql -U helpdesk_user helpdesk_db
Redis-Management
# Redis CLI (with password!)
docker compose exec redis redis-cli -a YOUR_REDIS_PASSWORD --no-auth-warning
# Check queue sizes (BullMQ)
docker compose exec redis redis-cli -a YOUR_REDIS_PASSWORD --no-auth-warning keys "bull:*"
# Check Locks
docker compose exec redis redis-cli -a YOUR_REDIS_PASSWORD --no-auth-warning keys "lock:*"
Erste Schritte nach der Installation
Vollständige Referenz aller Variablen