n8n selbst hosten mit Docker Compose: Anleitung 2026

Schritt für Schritt: n8n mit Docker Compose und Traefik für HTTPS betreiben, N8N_ENCRYPTION_KEY und Webhook-URL setzen, richtig sichern und sicher updaten.

Um n8n selbst zu hosten, brauchst du einen Linux-Server mit Docker, eine Subdomain, die auf ihn zeigt, und die offizielle Docker-Compose-Datei von n8n, die n8n hinter Traefik mit automatischem HTTPS betreibt. Die Fehler passieren meistens später: beim Schlüssel für die Verschlüsselung, bei der Webhook-URL und beim Backup des richtigen Ordners.

Diese Anleitung folgt der offiziellen Docker-Compose-Anleitung von n8n (geprüft im Oktober 2026, als die aktuelle stabile Version 2.43.5 war) und ergänzt die Schritte drumherum, die in der Doku auf anderen Seiten stehen.

Bevor du anfängst

Die n8n-Doku ist da ehrlich: Self-Hosting "requires technical knowledge", und empfohlen wird es für erfahrene Nutzer, weil Fehler "can lead to data loss, security issues, and downtime". Du musst kein Profi sein, um dieser Anleitung zu folgen. Aber wenn etwas kaputtgeht, reparierst du es.

Du brauchst:

  • Einen Linux-Server mit öffentlicher IP-Adresse. Für private Nutzung reicht ein kleiner VPS.
  • Eine Domain, bei der du DNS-Einträge anlegen kannst.
  • Docker Engine und das Docker-Compose-Plugin.
  • SSH-Zugang und Grundkenntnisse im Terminal.

Ein Wort zur Lizenz: Die Sustainable Use License von n8n erlaubt Self-Hosting für interne Geschäftszwecke sowie private und nicht kommerzielle Nutzung. Sie ist keine von der OSI anerkannte Open-Source-Lizenz, und n8n als bezahlten Dienst für andere anzubieten ist nicht erlaubt. Die Details und komplett offene Alternativen findest du in unserem Vergleich der Zapier-Alternativen.

Schritt 1: Docker installieren

Installier Docker Engine und Docker Compose nach der offiziellen Anleitung für deine Distribution auf docs.docker.com. Prüf danach, ob beides läuft:

docker --version
docker compose version

Wenn du willst, darf dein Nutzer Docker auch ohne sudo verwenden:

sudo usermod -aG docker ${USER}
exec sg docker newgrp

Schritt 2: Subdomain auf den Server zeigen lassen

Leg einen A-Eintrag für die gewünschte Subdomain an, zum Beispiel n8n, der auf die IP-Adresse deines Servers zeigt. Mit der Domain example.com ist n8n dann unter https://n8n.example.com erreichbar.

Warte, bis der Eintrag aufgelöst wird, bevor du den Stack startest. Traefik fordert das HTTPS-Zertifikat beim ersten Start an.

Schritt 3: Projektordner und .env-Datei anlegen

mkdir n8n-compose
cd n8n-compose

Leg in diesem Ordner eine Datei .env an:

DOMAIN_NAME=example.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=Europe/Berlin
SSL_EMAIL=user@example.com

GENERIC_TIMEZONE nutzen die Schedule- und Cron-Nodes. Lässt du die Variable weg, rechnet n8n mit der Zeit von New York. An SSL_EMAIL schickt Let's Encrypt Hinweise zu deinen Zertifikaten.

Dann legst du einen Ordner für Dateien an, die sich n8n und der Server teilen:

mkdir local-files

In n8n erreichst du ihn als /files, zum Beispiel mit dem Node "Read/Write Files from Disk".

Schritt 4: Die Docker-Compose-Datei

Leg eine compose.yaml mit dem Inhalt aus der n8n-Doku an:

services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - traefik_data:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - N8N_WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - TZ=${GENERIC_TIMEZONE}
      - N8N_RESTRICT_FILE_ACCESS_TO=/files
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  n8n_data:
  traefik_data:

Was hier passiert:

  • Traefik lauscht auf Port 80 und 443, leitet HTTP auf HTTPS um und holt über die TLS-Challenge ein Zertifikat von Let's Encrypt. Seine Routen liest es aus den Labels am n8n-Container. Veröffentlicht sind nur Port 80 und 443, die eigene API von Traefik auf Port 8080 bleibt also innerhalb von Docker.
  • n8n lauscht auf Port 5678, aber nur auf 127.0.0.1. Von außen erreichst du es also nur über Traefik.
  • Das Volume n8n_data enthält /home/node/.n8n. Dort liegen die SQLite-Datenbank und der Schlüssel für die Verschlüsselung. Genau dieses Volume musst du sichern.
  • Im Volume traefik_data liegen die Zertifikate.

Schritt 5: Die wichtigen Umgebungsvariablen

Die offizielle Datei setzt das meiste, was du brauchst. Drei Variablen solltest du dir genauer ansehen.

N8N_ENCRYPTION_KEY

n8n verschlüsselt jeden gespeicherten Zugang (API-Keys, Passwörter, OAuth-Tokens), bevor er in die Datenbank kommt. Beim ersten Start erzeugt n8n einen zufälligen Schlüssel und legt ihn in der Datei config im Ordner .n8n ab, hier also im Volume n8n_data.

Verlierst du diesen Schlüssel, sind deine Zugangsdaten weg. Eine wiederhergestellte Datenbank lässt sich ohne ihn nicht entschlüsseln. Du kannst den erzeugten Schlüssel behalten und dafür sorgen, dass er in deinen Backups steckt. Oder du setzt einen eigenen, der dann auch in deinem Passwortmanager liegt:

# in die .env
N8N_ENCRYPTION_KEY=hier-ein-langer-zufaelliger-string
# in compose.yaml unter environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}

Einen zufälligen String erzeugst du mit openssl rand -hex 32. Mach das bei einer frischen Installation. n8n nutzt die Variable nur, wenn noch kein Schlüssel in der Einstellungsdatei steht. Bei einer bestehenden Instanz bleibt der gespeicherte Schlüssel maßgeblich.

N8N_WEBHOOK_URL

Hinter einem Reverse Proxy kann n8n seine öffentliche Adresse nicht selbst herausfinden: Intern läuft es auf Port 5678, die Welt erreicht es über 443. N8N_WEBHOOK_URL sagt n8n die öffentliche Adresse. Dann zeigt der Editor die richtigen URLs, und n8n registriert die richtigen Webhooks bei anderen Diensten.

Ab n8n 2.30.0 heißt die Variable N8N_WEBHOOK_URL. Ältere Versionen und ältere Tutorials nutzen WEBHOOK_URL. Der alte Name gilt ab 2.35.0 als veraltet und erzeugt eine Warnung im Log. Die offizielle Compose-Datei oben nutzt schon den neuen Namen.

N8N_PROXY_HOPS

Die n8n-Doku zum Reverse Proxy empfiehlt außerdem N8N_PROXY_HOPS=1, wenn n8n hinter einem Proxy läuft, und der Proxy sollte die Header X-Forwarded-For, X-Forwarded-Host und X-Forwarded-Proto weitergeben. Traefik schickt diese Header von sich aus mit. Ergänz die Variable unter environment::

      - N8N_PROXY_HOPS=1

Schritt 6: n8n starten

sudo docker compose up -d

Öffne https://n8n.example.com und leg das Owner-Konto an. n8n ist nur über HTTPS erreichbar. Lädt die Seite nicht, prüf deine Firewall (Port 80 und 443 müssen offen sein) und ob der DNS-Eintrag auf die richtige IP zeigt.

Zum Stoppen:

sudo docker compose stop

Schritt 7: Backups

Laut der Backup-Doku von n8n ist ein vollständiges Backup dieses Setups der Ordner .n8n. Mit der Standard-Datenbank SQLite steckt dort alles drin: die Datenbank mit Nutzern, Workflows, Zugangsdaten und Ausführungen, dazu der Schlüssel. Wechselst du später zu PostgreSQL, sicherst du die Datenbank mit deren eigenen Werkzeugen und sicherst .n8n weiter wegen des Schlüssels.

Stopp n8n, bevor du den Ordner kopierst. Wenn du die SQLite-Datei kopierst, während n8n hineinschreibt, kann das Backup kaputt sein. Docker Compose setzt den Projektordner vor den Volume-Namen, hier heißt das Volume also n8n-compose_n8n_data:

cd n8n-compose
sudo docker compose stop n8n
sudo docker run --rm -v n8n-compose_n8n_data:/data -v "$(pwd)":/backup alpine \
  tar czf /backup/n8n-data-$(date +%F).tar.gz -C /data .
sudo docker compose start n8n

Kopier das Archiv auf einen anderen Rechner oder in einen Objektspeicher. Ein Backup auf demselben Server hilft dir nicht, wenn der Server weg ist.

Zusätzlich kannst du Workflows und Zugangsdaten mit der CLI von n8n als JSON exportieren. Schreib sie ins Volume, weil andere Ordner im Container verloren gehen, wenn er neu erstellt wird:

sudo docker compose exec -u node n8n n8n export:workflow --backup --output=/home/node/.n8n/backups/workflows/
sudo docker compose exec -u node n8n n8n export:credentials --backup --output=/home/node/.n8n/backups/credentials/

Diese Exporte enthalten nur Workflows und Zugangsdaten, keine Nutzer, Ausführungshistorie, Variablen oder Einstellungen. Zum Umziehen von Workflows sind sie praktisch, das Backup des Ordners ersetzen sie aber nicht. Die Zugangsdaten darin sind weiterhin mit deinem Schlüssel verschlüsselt.

Schritt 8: Updates

n8n veröffentlicht fast jede Woche eine neue Minor-Version. Die Doku empfiehlt, oft zu aktualisieren, mindestens einmal im Monat, damit du nie viele Versionen auf einmal überspringen musst. Lies vorher die Release Notes auf Breaking Changes und mach vor jedem Update ein Backup.

cd n8n-compose
sudo docker compose pull
sudo docker compose down
sudo docker compose up -d

Die Compose-Datei nutzt n8nio/n8n ohne Tag, also immer die neueste stabile Version. Wenn du selbst entscheiden willst, wann du aktualisierst, leg in compose.yaml eine Version fest, zum Beispiel image: n8nio/n8n:2.43.5, und änder sie, wenn du so weit bist.

Checkliste Sicherheit

  • Halte das Betriebssystem des Servers aktuell und lass in der Firewall nur Port 22, 80 und 443 zu.
  • Nimm ein starkes Passwort für den Owner und schalte für dein Konto die Zwei-Faktor-Authentifizierung ein.
  • Gib die .env und deine Backups nicht weiter: Zusammen enthalten sie die Schlüssel zu all deinen verbundenen Diensten.
  • Installier Community-Nodes nur aus Quellen, denen du vertraust. Sie führen Code auf deinem Server aus.

Der Managed-Weg

Wenn du dich nicht um einen Server kümmern willst, hast du zwei Möglichkeiten. n8n bietet die kostenpflichtige n8n Cloud an. Oder du nimmst einen Managed-Hoster, der die Community Edition für dich betreibt: Auf blitz.cloud lässt sich n8n mit einem Klick installieren, HTTPS inklusive, gehostet in der EU. Es gibt einen kostenlosen Plan ohne Kreditkarte, in dem Apps nach 30 Minuten ohne Besucher schlafen. Zum Bauen und Testen von Workflows reicht das. Workflows, die nach Zeitplan laufen, brauchen eine App, die wach bleibt.

Egal welchen Weg du gehst: Exportier deine Workflows ab und zu. Sie sind einfaches JSON und lassen sich leicht zwischen Instanzen umziehen.

FAQ

Ist selbst gehostetes n8n kostenlos?

Die Community Edition ist kostenlos und hat laut n8n "almost the complete feature set". Funktionen wie SSO, Projekte, Environments und Versionskontrolle über Git brauchen eine bezahlte Lizenz. Den Server bezahlst du trotzdem.

Was passiert, wenn ich den N8N_ENCRYPTION_KEY verliere?

Deine gespeicherten Zugangsdaten lassen sich nicht mehr entschlüsseln. Die Workflows bleiben, aber du musst jeden API-Key neu eintragen und jedes Konto neu verbinden. Bewahr den Schlüssel in deinen Backups und in einem Passwortmanager auf.

WEBHOOK_URL oder N8N_WEBHOOK_URL?

N8N_WEBHOOK_URL ab n8n 2.30.0. WEBHOOK_URL funktioniert in aktuellen Versionen noch, gilt aber ab 2.35.0 als veraltet.

Brauche ich PostgreSQL?

Für den Anfang nicht. Das offizielle Compose-Setup nutzt SQLite und speichert es im Volume n8n_data. Für größere Setups unterstützt n8n PostgreSQL, wie du wechselst, steht in der Doku.

Kann ich n8n ohne Domain betreiben?

Zum lokalen Testen ja, unter http://localhost:5678. Damit andere Dienste Webhooks schicken können, brauchst du eine öffentliche HTTPS-Adresse, in der Praxis also eine Domain oder einen Managed-Hoster, der dir eine stellt.