Self-Hosted Installationsanleitung

Deploye MailDesk auf deiner eigenen Infrastruktur. Alle Daten bleiben auf deinen Servern.

Voraussetzungen

VoraussetzungMinimum
Docker Engine 24+
Docker Compose v2.20+
4 GB RAM
20 GB Speicher (+ Anhang-Speicher)
Beliebiges Linux mit Docker-Unterstützung
Lizenzschlüssel von maildesk.cloud
Die App lauscht standardmäßig auf Port 3000. Stelle einen Reverse Proxy (Caddy, Nginx, Traefik) davor für TLS.

1. Entpacken und laden

Paket entpacken:

shell
tar xzf maildesk-selfhosted.tar.gz
cd maildesk

Docker-Images laden:

shell
docker load < maildesk-images.tar.gz

2. Umgebung konfigurieren

shell
./setup.sh

Führe ./setup.sh aus, um alle Secrets automatisch zu generieren. Dann editiere .env und setze deine APP_URL und den Lizenzschlüssel.

Öffne .env und setze folgende Werte:

Erforderliche Variablen

VariableBeschreibung
APP_URLÖffentliche URL deiner Instanz (ohne abschließenden Slash)
MAILDESK_LICENSE_KEYDein Ed25519-signierter JWT-Lizenzschlüssel

Auto-generiert durch setup.sh

Diese werden automatisch beim Ausführen von setup.sh generiert. Nicht ändern, außer bei Datenmigration.

VariableBeschreibung
BETTER_AUTH_SECRETSession-Signierungsschlüssel, min. 32 Zeichen (auto-generiert)
CREDENTIAL_ENCRYPTION_KEYAES-256-GCM-Schlüssel für IMAP/SMTP-Passwörter (auto-generiert)
POSTGRES_PASSWORDPostgreSQL-Datenbankpasswort (auto-generiert)
REDIS_PASSWORDRedis-Cache-Passwort (auto-generiert)
MAILDESK_MODEAuf selfhosted gesetzt (automatisch durch setup.sh)

Optionale Variablen

VariableBeschreibung
MAILDESK_LICENSE_SERVER_URLLizenzserver-URL für Online-Verifizierung (Standard: nur offline)
REGISTRATION_ENABLEDtrue (Standard) oder false um Selbstregistrierung zu deaktivieren
ALLOWED_REGISTER_IPSKomma-getrennte IPs mit Zugriff auf /register
ENABLE_HSTStrue um HSTS-Header zu senden (aktivieren hinter TLS)
LOG_LEVELtrace, debug, info (Standard), warn, error, fatal
METRICS_AUTH_TOKENBearer-Token für /api/metrics Endpoint (versteckt wenn nicht gesetzt)
OPENAI_EMBEDDING_KEYOpenAI API-Key für KB semantische Suche (optional)
MAX_ATTACHMENT_SIZE_MBMax. Anhangsgröße in MB (Standard: 25)

Beispiel .env für Self-Hosted

env
# Only these 2 lines need manual editing after running ./setup.sh:
APP_URL=https://tickets.example.com
MAILDESK_LICENSE_KEY=eyJhbGciOiJFZERTQSIs...your-key-here

# Everything else is auto-generated by ./setup.sh

3. Starten

shell
docker compose up -d

Dies startet 6 Services:

ServiceZweck
migrateFührt Datenbankmigrationen aus, dann beendet
appNext.js Webanwendung (Port 3000)
workerHintergrund-Worker (IMAP/SMTP, E-Mail-Verarbeitung, Jobs)
postgresPostgreSQL 17 mit pgvector-Erweiterung
redisRedis 7 für Job-Queues und Pub/Sub
clamavClamAV Antivirus für Anhang-Scanning

Der migrate-Service läuft automatisch bevor App und Worker starten. Er erstellt alle Tabellen idempotent — sicher für neue und bestehende Datenbanken.

4. Deployment verifizieren

shell
# Check all services are healthy
docker compose ps

# Check app logs
docker compose logs app

# Check worker logs
docker compose logs worker

# Health check endpoint
curl http://localhost:3000/api/health

Sobald alles healthy ist, öffne deine APP_URL im Browser. Du solltest die Login-/Registrierungsseite sehen.

5. Ersteinrichtung

  1. 1Registriere das erste Admin-Konto unter deine-domain.de/register
  2. 2Erstelle eine Organisation — das ist dein Workspace
  3. 3Füge eine Mailbox unter Einstellungen > Mailboxen hinzu (IMAP/SMTP-Zugangsdaten)
  4. 4Eingehende E-Mails erstellen automatisch Tickets
Tip: Nutze ALLOWED_REGISTER_IPS um einzuschränken, wer Konten erstellen kann, oder setze REGISTRATION_ENABLED=false nach dem Erstellen des Admin-Kontos.

E-Mail-Verifizierung (Optional)

Konfiguriere SMTP, um E-Mail-Verifizierung für neue Benutzer zu aktivieren. Ohne SMTP werden neue Benutzer automatisch verifiziert und können sich sofort anmelden.

.env
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=you@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM=MailDesk <noreply@yourdomain.com>
Ohne SMTP: Die E-Mail-Verifizierung wird automatisch übersprungen. Neue Benutzer können sich registrieren und anmelden, ohne ihre E-Mail zu bestätigen. Du kannst SMTP jederzeit nachträglich hinzufügen.

Reverse Proxy einrichten

MailDesk benötigt einen Reverse Proxy für TLS-Terminierung. Hier sind Beispiele für gängige Setups:

Caddyfile
tickets.example.com {
    handle /ws* {
        reverse_proxy localhost:3002
    }
    handle {
        reverse_proxy localhost:3000
    }
}
WebSocket: MailDesk nutzt WebSocket für Echtzeit-Updates (Chat, Benachrichtigungen, Ticket-Events). Die /ws Route muss auf Port 3002 (Worker) zeigen.

Lizenzschlüssel

Dein Lizenzschlüssel ist ein Ed25519-signiertes JWT, das deinen Plan, Limits und Feature-Flags enthält.

Was der Schlüssel steuert:

  • Plan-Stufe (Free, Pro, Business)
  • Limits: max. Agenten, Mailboxen, Tickets/Monat, Speicher
  • Features: KI-Antworten, Wissensdatenbank, Auto-Übersetzung

Validierung:

  • Der Schlüssel wird standardmäßig offline mit dem eingebetteten Ed25519 Public Key validiert — keine externen Aufrufe nötig
  • Wenn MAILDESK_LICENSE_SERVER_URL gesetzt ist, verifiziert MailDesk den Schlüssel regelmäßig online (optional)
  • Validierte Lizenzdaten werden 24 Stunden in Redis gecacht
  • Bei Redis-Ausfall wird das JWT direkt verifiziert (Ed25519 braucht keinen Server)

Abgelaufener oder ungültiger Schlüssel:

  • Die App wechselt in den Nur-Lesen-Modus — bestehende Daten bleiben zugänglich
  • Ticket-Erstellung, Antworten senden und KI-Features sind deaktiviert
  • Ein Banner zeigt "Lizenz abgelaufen" mit einem Verlängerungslink

Aktualisierung

shell
# Load new images
docker load < maildesk-images.tar.gz

# Restart (migrations run automatically)
docker compose up -d

Migrationen laufen automatisch bei jedem Start — kein manueller Migrationsschritt nötig.

Backup & Wiederherstellung

Backup

Datenbank

shell
docker compose exec postgres pg_dump -U maildesk maildesk > backup_$(date +%Y%m%d).sql

Anhänge

shell
docker compose cp worker:/data/attachments ./attachments-backup

Redis (optional — nur Caches, kann neu aufgebaut werden)

shell
docker compose exec redis redis-cli BGSAVE

Wiederherstellung

Datenbank

shell
docker compose exec -T postgres psql -U maildesk maildesk < backup_20260317.sql

Anhänge

shell
docker compose cp ./attachments-backup/. worker:/data/attachments

Fehlerbehebung

App startet nicht

shell
docker compose logs app
docker compose logs migrate

Häufige Ursachen:

  • Datenbank nicht bereit — Der migrate-Service wartet auf den Postgres-Healthcheck. Prüfe docker compose ps auf unhealthy Services.
  • Ungültige DATABASE_URL — Stelle sicher, dass der Connection-String zu den Postgres-Zugangsdaten passt.
  • Port-Konflikt — Wenn Port 3000 belegt ist, ändere das Port-Mapping in docker-compose.yml.

Lizenz-Fehler

shell
docker compose logs app | grep -i license
  • "License invalid" — Überprüfe ob MAILDESK_LICENSE_KEY korrekt in .env gesetzt ist (keine Zeilenumbrüche, keine Anführungszeichen um das JWT).
  • "License expired" — Erneuere deine Lizenz auf maildesk.cloud.

ClamAV startet langsam

ClamAV lädt beim ersten Start Virendefinitionen herunter, was 3–5 Minuten dauern kann.

shell
docker compose logs clamav

Worker verarbeitet keine E-Mails

shell
docker compose logs worker
  • Überprüfe ob die IMAP-Zugangsdaten in den Mailbox-Einstellungen korrekt sind
  • Prüfe ob der Worker-Service healthy ist
  • Stelle sicher, dass Redis erreichbar ist

Architekturübersicht

        ┌─────────────┐
        │  Reverse    │
        │  Proxy      │
        │  (TLS)      │
        └──────┬──────┘
               │ :3000
        ┌──────▼──────┐
        │    App      │
        │  (Next.js)  │
        └──┬──────┬───┘
           │      │
  ┌────────▼─┐  ┌─▼────────┐
  │ Postgres │  │  Redis   │
  │ (pgvec)  │  │ (queue)  │
  └────────▲─┘  └─▲────────┘
           │      │
        ┌──┴──────┴───┐
        │   Worker    │
        │ (IMAP/SMTP) │
        └──────┬──────┘
               │
        ┌──────▼──────┐
        │   ClamAV    │
        │ (antivirus) │
        └─────────────┘
  • App App stellt die Web-UI und API-Routen bereit
  • Worker Worker verbindet sich per IMAP mit Mailboxen, sendet Antworten per SMTP, verarbeitet Hintergrund-Jobs
  • Postgres Postgres speichert alle Anwendungsdaten (mit pgvector für KI-Embeddings)
  • Redis Redis verwaltet Job-Queues (BullMQ) und Echtzeit-Pub/Sub (WebSocket)
  • ClamAV ClamAV scannt E-Mail-Anhänge auf Malware