n8n: Das komplette technische Handbuch
n8n 2.x ist das aktuelle Major-Release – mit Fokus auf Sicherheit, Performance und Skalierung. Die stabile Version 2.8.0 (Stand Februar 2026) läuft auf dem offiziellen Docker-Image docker.n8n.io/n8nio/n8n und wird wöchentlich aktualisiert. Dieses Handbuch dokumentiert sämtliche Konfigurationsdetails, Befehle und Best Practices für den produktiven Self-hosted-Betrieb – von der Docker-Installation über Reverse-Proxy-Setup bis hin zu Skalierung und Troubleshooting.
1. Docker-Installation und grundlegende Einrichtung
Docker Run – Schnellstart
Der einfachste Weg, n8n lokal zu starten:
docker volume create n8n_data
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e GENERIC_TIMEZONE="Europe/Berlin" \
-e TZ="Europe/Berlin" \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
Das Volume /home/node/.n8n ist kritisch – es enthält die SQLite-Datenbank, den automatisch generierten Encryption Key und alle Konfigurationsdaten. Ohne persistentes Volume gehen bei Container-Neustart sämtliche Daten verloren. Für Produktionsumgebungen empfiehlt sich zwingend PostgreSQL (siehe Abschnitt 5).
Docker Run mit PostgreSQL (Produktion)
docker run -d --restart always \
--name n8n \
-p 5678:5678 \
-e DB_TYPE=postgresdb \
-e DB_POSTGRESDB_HOST=<POSTGRES_HOST> \
-e DB_POSTGRESDB_PORT=5432 \
-e DB_POSTGRESDB_DATABASE=n8n \
-e DB_POSTGRESDB_USER=n8n \
-e DB_POSTGRESDB_PASSWORD=<SICHERES_PASSWORT> \
-e N8N_ENCRYPTION_KEY=<DEIN_ENCRYPTION_KEY> \
-e N8N_HOST=n8n.example.com \
-e N8N_PROTOCOL=https \
-e WEBHOOK_URL=https://n8n.example.com/ \
-e GENERIC_TIMEZONE="Europe/Berlin" \
-e TZ="Europe/Berlin" \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n:2.8.0
Docker Compose – Produktionsreife Konfiguration mit PostgreSQL
docker-compose.yml:
version: "3.8"
volumes:
db_storage:
n8n_storage:
services:
postgres:
image: postgres:16-alpine
container_name: n8n-postgres
restart: always
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- db_storage:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 10
n8n:
image: docker.n8n.io/n8nio/n8n:2.8.0
container_name: n8n
restart: always
environment:
# Kern-Konfiguration
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${N8N_HOST}/
- N8N_EDITOR_BASE_URL=https://${N8N_HOST}/
- GENERIC_TIMEZONE=Europe/Berlin
- TZ=Europe/Berlin
# Sicherheit
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_SECURE_COOKIE=true
- N8N_BLOCK_ENV_ACCESS_IN_NODE=true
- NODE_ENV=production
# Datenbank
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# Execution Management
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=336
- EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000
- EXECUTIONS_DATA_SAVE_ON_ERROR=all
- EXECUTIONS_DATA_SAVE_ON_SUCCESS=all
# Logging
- N8N_LOG_LEVEL=warn
- N8N_METRICS=true
- N8N_PROXY_HOPS=1
ports:
- "5678:5678"
volumes:
- n8n_storage:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
.env-Datei:
N8N_HOST=n8n.example.com
POSTGRES_USER=n8n
POSTGRES_PASSWORD=EinSehrSicheresPasswort123!
POSTGRES_DB=n8n
N8N_ENCRYPTION_KEY=<mit openssl rand -hex 32 generieren>
Sichere Werte generieren:
openssl rand -hex 32 # Für N8N_ENCRYPTION_KEY
openssl rand -base64 32 # Für Passwörter
2. Vollständige Umgebungsvariablen-Referenz
Kern-Identität und Deployment
| Variable | Default | Beschreibung |
|---|---|---|
N8N_HOST |
localhost |
Hostname für URL-Generierung |
N8N_PORT |
5678 |
HTTP-Port |
N8N_LISTEN_ADDRESS |
:: |
Bind-Adresse |
N8N_PROTOCOL |
http |
http oder https – beeinflusst URL-Generierung |
N8N_PATH |
/ |
Basis-Pfad |
N8N_EDITOR_BASE_URL |
— | Öffentliche URL für Editor (SAML, OAuth-Redirects) |
N8N_ENCRYPTION_KEY |
Auto-generiert | KRITISCH – Schlüssel für Credential-Verschlüsselung |
GENERIC_TIMEZONE |
America/New_York |
Zeitzone für Schedule-Nodes |
TZ |
— | System-Zeitzone |
Webhooks
| Variable | Default | Beschreibung |
|---|---|---|
WEBHOOK_URL |
— | KRITISCH – Öffentliche URL für Webhooks, z.B. https://n8n.example.com/ |
N8N_ENDPOINT_WEBHOOK |
webhook |
Pfad für Produktions-Webhooks |
N8N_ENDPOINT_WEBHOOK_TEST |
webhook-test |
Pfad für Test-Webhooks |
N8N_PROXY_HOPS |
0 |
Anzahl Reverse-Proxies (für korrekte IP-Auflösung) |
Authentifizierung
Wichtig: N8N_BASIC_AUTH_ACTIVE, N8N_BASIC_AUTH_USER und N8N_BASIC_AUTH_PASSWORD sind in n8n 2.x deprecated. n8n nutzt jetzt ein eingebautes User-Management mit Owner-Setup beim ersten Start.
| Variable | Default | Beschreibung |
|---|---|---|
N8N_USER_MANAGEMENT_JWT_SECRET |
Auto-generiert | JWT-Secret für Sessions |
N8N_SECURE_COOKIE |
true |
HTTPS für Session-Cookies erzwingen |
N8N_SAMESITE_COOKIE |
lax |
Cross-Site-Cookie-Policy |
Datenbank
| Variable | Default | Beschreibung |
|---|---|---|
DB_TYPE |
sqlite |
sqlite oder postgresdb |
DB_POSTGRESDB_HOST |
localhost |
PostgreSQL-Host |
DB_POSTGRESDB_PORT |
5432 |
PostgreSQL-Port |
DB_POSTGRESDB_DATABASE |
n8n |
Datenbankname |
DB_POSTGRESDB_USER |
postgres |
Datenbanknutzer |
DB_POSTGRESDB_PASSWORD |
— | Datenbankpasswort |
DB_POSTGRESDB_SCHEMA |
public |
PostgreSQL-Schema |
DB_POSTGRESDB_POOL_SIZE |
2 |
Parallele Verbindungen |
DB_POSTGRESDB_SSL_ENABLED |
false |
SSL-Verbindung aktivieren |
DB_TABLE_PREFIX |
— | Prefix für Tabellennamen |
Alle sensiblen Variablen unterstützen das _FILE-Suffix für Docker-Secrets-Integration, z.B. DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/db_password.
Execution-Konfiguration
| Variable | Default | Beschreibung |
|---|---|---|
EXECUTIONS_MODE |
regular |
regular oder queue (Redis-basiert) |
EXECUTIONS_TIMEOUT |
-1 |
Timeout in Sekunden; -1 = kein Limit |
EXECUTIONS_DATA_SAVE_ON_ERROR |
all |
Fehlgeschlagene Executions speichern |
EXECUTIONS_DATA_SAVE_ON_SUCCESS |
all |
Erfolgreiche Executions speichern |
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS |
true |
Manuelle Executions speichern |
EXECUTIONS_DATA_PRUNE |
true |
Automatisches Löschen alter Daten |
EXECUTIONS_DATA_MAX_AGE |
336 |
Maximales Alter in Stunden (14 Tage) |
EXECUTIONS_DATA_PRUNE_MAX_COUNT |
10000 |
Maximale Anzahl gespeicherter Executions |
N8N_CONCURRENCY_PRODUCTION_LIMIT |
-1 |
Parallele Produktions-Executions; -1 = unbegrenzt |
Queue-Modus (Redis)
| Variable | Default | Beschreibung |
|---|---|---|
QUEUE_BULL_REDIS_HOST |
localhost |
Redis-Host |
QUEUE_BULL_REDIS_PORT |
6379 |
Redis-Port |
QUEUE_BULL_REDIS_PASSWORD |
— | Redis-Passwort |
QUEUE_HEALTH_CHECK_ACTIVE |
— | /healthz-Endpoint auf Workern aktivieren |
Logging und Metriken
| Variable | Default | Beschreibung |
|---|---|---|
N8N_LOG_LEVEL |
info |
error, warn, info, debug |
N8N_LOG_OUTPUT |
console |
console, file |
N8N_LOG_FILE_LOCATION |
— | Log-Dateipfad |
N8N_METRICS |
false |
Prometheus /metrics-Endpoint |
Sicherheit
| Variable | Default | Beschreibung |
|---|---|---|
N8N_BLOCK_ENV_ACCESS_IN_NODE |
false |
process.env-Zugriff in Code-Nodes blockieren |
N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES |
true |
Zugriff auf .n8n-Verzeichnis blockieren |
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS |
false |
0600-Berechtigungen auf Config-Datei |
N8N_COMMUNITY_PACKAGES_ENABLED |
true |
Community-Pakete erlauben |
N8N_DIAGNOSTICS_ENABLED |
true |
Anonyme Telemetrie senden |
NODES_EXCLUDE |
— | Nodes ausschließen, z.B. ["n8n-nodes-base.executeCommand"] |
Binärdaten-Speicherung
| Variable | Default | Beschreibung |
|---|---|---|
N8N_DEFAULT_BINARY_DATA_MODE |
filesystem |
filesystem oder s3 |
N8N_EXTERNAL_STORAGE_S3_HOST |
— | S3-Endpoint |
N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME |
— | S3-Bucket |
N8N_EXTERNAL_STORAGE_S3_ACCESS_KEY |
— | S3-Access-Key |
N8N_EXTERNAL_STORAGE_S3_ACCESS_SECRET |
— | S3-Secret |
3. Reverse-Proxy mit Nginx und Traefik
Nginx-Konfiguration (vollständig mit SSL und WebSocket)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name n8n.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name n8n.example.com;
ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
proxy_pass http://localhost:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket-Support (kritisch für den n8n-Editor)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Timeouts für lang laufende Workflows
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
# Buffering deaktivieren für Streaming/WebSocket
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
client_max_body_size 50M;
}
}
SSL-Zertifikat einrichten:
sudo apt install -y nginx certbot python3-certbot-nginx
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo certbot --nginx -d n8n.example.com
Der map-Block für WebSocket-Upgrade ist essenziell. Ohne ihn bricht die Editor-Verbindung ab, weil n8n über WebSockets (wss://) den Echtzeit-Status von Workflow-Ausführungen streamt. proxy_http_version 1.1 ist ebenfalls zwingend notwendig.
Traefik mit automatischem Let's Encrypt (Docker Compose)
version: "3.8"
services:
traefik:
image: traefik:v2.11
restart: always
command:
- --api.dashboard=true
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.mytlschallenge.acme.tlschallenge=true
- --certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}
- --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
ports:
- "80:80"
- "443:443"
volumes:
- traefik_letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
n8n:
image: docker.n8n.io/n8nio/n8n:2.8.0
restart: always
environment:
- N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
- GENERIC_TIMEZONE=Europe/Berlin
labels:
- traefik.enable=true
- traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
- traefik.http.routers.n8n.entrypoints=websecure
- traefik.http.routers.n8n.tls.certresolver=mytlschallenge
- traefik.http.middlewares.n8n-headers.headers.SSLRedirect=true
- traefik.http.middlewares.n8n-headers.headers.STSSeconds=315360000
- traefik.http.middlewares.n8n-headers.headers.browserXSSFilter=true
- traefik.http.middlewares.n8n-headers.headers.contentTypeNosniff=true
- traefik.http.routers.n8n.middlewares=n8n-headers
- traefik.http.services.n8n.loadbalancer.server.port=5678
volumes:
- n8n_data:/home/node/.n8n
volumes:
traefik_letsencrypt:
n8n_data:
.env für Traefik:
DOMAIN_NAME=example.com
SUBDOMAIN=n8n
SSL_EMAIL=admin@example.com
Traefik übernimmt die komplette SSL-Verwaltung automatisch – Zertifikatsausstellung, Renewal und HTTPS-Redirect. In Produktion sollte --api.insecure=true entfernt oder das Dashboard mit Auth-Middleware abgesichert werden.
4. SSL/HTTPS – vier Methoden im Überblick
Methode 1: Let's Encrypt mit Certbot + Nginx (empfohlen für Nginx-Setups):
sudo certbot --nginx -d n8n.example.com
sudo certbot renew --dry-run # Renewal testen
Methode 2: Automatisch über Traefik (siehe oben) – keinerlei manuelle Zertifikatsverwaltung nötig.
Methode 3: Selbstsignierte Zertifikate (nur für Entwicklung):
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/n8n-selfsigned.key \
-out /etc/ssl/certs/n8n-selfsigned.crt \
-subj "/CN=n8n.example.com"
Methode 4: n8n-eigenes SSL (ohne Reverse Proxy):
N8N_PROTOCOL=https
N8N_SSL_CERT=/ssl/fullchain.pem
N8N_SSL_KEY=/ssl/privkey.pem
Zertifikate werden per Volume eingebunden. Die empfohlene Methode für Produktion ist aber immer ein Reverse Proxy (Nginx oder Traefik), der SSL terminiert.
5. PostgreSQL statt SQLite
Wann PostgreSQL verwenden?
| Kriterium | SQLite | PostgreSQL |
|---|---|---|
| Einsatz | Entwicklung, Testing | Produktion, Multi-User |
| Konkurrenz | Single-Writer, Locks unter Last | Volle Parallelität |
| Queue-Modus | Nicht unterstützt | Erforderlich |
| Datenintegrität | Dateisystem-basiert | ACID, WAL-Recovery |
| n8n 2.x | Noch unterstützt | Empfohlen (PostgreSQL 13–17) |
Vollständige Docker Compose mit PostgreSQL
Siehe die docker-compose.yml in Abschnitt 1. Die PostgreSQL-Connection-Parameter unterstützen SSL für verwaltete Datenbanken:
DB_POSTGRESDB_SSL_ENABLED=true
DB_POSTGRESDB_SSL_CA=/path/to/ca-certificate.crt
DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED=true
Migration von SQLite zu PostgreSQL
Es gibt kein eingebautes Migrationstool. Die zuverlässigste Methode:
# 1. Export aus SQLite-Instanz
docker exec -u node -it n8n n8n export:workflow --all --output=/tmp/workflows/
docker exec -u node -it n8n n8n export:credentials --all --output=/tmp/credentials/
# 2. Dateien aus Container kopieren
docker cp n8n:/tmp/workflows/ ./backup/
docker cp n8n:/tmp/credentials/ ./backup/
# 3. PostgreSQL-Instanz starten (GLEICHEN N8N_ENCRYPTION_KEY verwenden!)
# 4. Import in neue Instanz
docker exec -u node -it n8n-new n8n import:workflow --input=/tmp/workflows/
docker exec -u node -it n8n-new n8n import:credentials --input=/tmp/credentials/
Ab n8n 2.x steht auch n8n export:entities / n8n import:entities für vollständigere Migrationen zur Verfügung.
6. Backup-Strategien
CLI-Export-Befehle
# Alle Workflows exportieren
docker exec -u node n8n n8n export:workflow --all --output=/tmp/workflows.json
# Alle Workflows als separate Dateien (Git-freundlich)
docker exec -u node n8n n8n export:workflow --all --separate --output=/tmp/workflows/
# Alle Credentials exportieren (verschlüsselt)
docker exec -u node n8n n8n export:credentials --all --output=/tmp/credentials.json
# Credentials entschlüsselt exportieren (für Migration)
docker exec -u node n8n n8n export:credentials --all --decrypted --output=/tmp/creds_plain.json
# Vollständiger Entity-Export (n8n 2.x)
docker exec -u node n8n n8n export:entities --outputDir=/tmp/exports
Datenbank-Backup
PostgreSQL (pg_dump):
docker exec -t n8n-postgres pg_dump -U n8n n8n | gzip > n8n_$(date +%F).sql.gz
SQLite (Datei kopieren bei gestopptem n8n):
docker compose stop n8n
cp /var/lib/docker/volumes/n8n_data/_data/database.sqlite ./backup/
docker compose start n8n
Automatisiertes Backup-Skript
#!/bin/bash
# /opt/scripts/n8n-backup.sh
BACKUP_DIR="/opt/n8n-backups"
DATE=$(date +%F)
RETENTION_DAYS=30
mkdir -p "$BACKUP_DIR/$DATE"
# PostgreSQL-Dump
docker exec -t n8n-postgres pg_dump -U n8n n8n \
| gzip > "$BACKUP_DIR/$DATE/postgres_$DATE.sql.gz"
# n8n-Volume sichern (enthält Encryption Key)
docker run --rm -v n8n_storage:/data alpine \
tar czf - -C / data > "$BACKUP_DIR/$DATE/n8n_data_$DATE.tgz"
# Workflow-Export
docker exec -u node n8n n8n export:workflow --all \
--output=/tmp/wf.json 2>/dev/null
docker cp n8n:/tmp/wf.json "$BACKUP_DIR/$DATE/"
# Alte Backups löschen
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +$RETENTION_DAYS \
-exec rm -rf {} \;
echo "Backup abgeschlossen: $BACKUP_DIR/$DATE"
Crontab (täglich um 2 Uhr):
0 2 * * * /opt/scripts/n8n-backup.sh >> /var/log/n8n-backup.log 2>&1
REST-API für Backups
curl -H "X-N8N-API-KEY: DEIN_API_KEY" \
https://n8n.example.com/api/v1/workflows > all_workflows.json
Der API-Key wird unter Settings → API im n8n-UI generiert. Die API gibt keine Credential-Secrets aus – dafür muss export:credentials --decrypted genutzt werden.
7. Update-Prozess für Docker
# 1. Aktuelle Version prüfen
docker exec n8n n8n --version
# 2. Release Notes lesen: https://docs.n8n.io/release-notes/
# 3. Backup erstellen (VOR dem Update!)
docker exec -t n8n-postgres pg_dump -U n8n n8n > n8n_pre_update.sql
docker run --rm -v n8n_storage:/data alpine tar czf - -C / data > n8n_data_pre_update.tgz
# 4. Image aktualisieren und Container neu starten
docker compose pull
docker compose down
docker compose up -d
# 5. Logs prüfen
docker compose logs -f n8n
Version Pinning ist Pflicht in Produktion – docker.n8n.io/n8nio/n8n:2.8.0 statt :latest oder :stable. Ohne gepinnte Version ist ein Rollback nahezu unmöglich, weil das alte Image nach docker compose pull überschrieben wird.
Rollback-Verfahren
docker compose down
# docker-compose.yml: Image auf alte Version zurücksetzen
# image: docker.n8n.io/n8nio/n8n:2.7.0
# Datenbank-Backup einspielen (falls nötig)
cat n8n_pre_update.sql | docker exec -i n8n-postgres psql -U n8n -d n8n
docker compose up -d
n8n 2.0 Breaking Changes: MySQL/MariaDB-Support wurde entfernt. Vor einem Upgrade von 1.x auf 2.x muss n8n migration-report ausgeführt werden. Die Docker-Tags stable und beta ersetzen die alten Tags latest und next.
8. Lizenzmodell – Fair-Code und Editionen
n8n nutzt die Sustainable Use License (SUL) – quelloffen, aber nicht Open Source nach OSI-Definition. Enterprise-Features (Dateien mit .ee. im Namen) stehen unter der n8n Enterprise License.
Erlaubt unter SUL: Interne Geschäftsautomatisierung (auch bei Großunternehmen), Self-Hosting, persönliche Nutzung, Code-Modifikation für eigenen Gebrauch, Beratungsdienstleistungen rund um n8n.
Verboten unter SUL: Weiterverkauf eines Produkts, dessen Wert wesentlich auf n8n basiert; Hosting von n8n als kostenpflichtigen Service für Dritte (konkurriert mit n8n Cloud); Einbettung in kostenpflichtige externe Dienste.
Community vs. Enterprise
| Feature | Community (kostenlos) | Enterprise (kostenpflichtig) |
|---|---|---|
| Workflows/Executions | Unbegrenzt | Unbegrenzt |
| Integrationen | 400+ | 400+ |
| User-Management | Basic (Owner + Members) | RBAC mit Custom Roles |
| SSO | ❌ | SAML, OIDC, LDAP |
| Workflow-Sharing | Nur Owner/Creator | Vollständig |
| Source Control | ❌ | Git-Integration, Environments |
| Audit Logging | ❌ | ✅ |
| Multi-Main HA | ❌ | ✅ |
| Support | Community-Forum | Dedizierter Support mit SLAs |
Seit 2025 gibt es keine aktiven Workflow-Limits mehr – alle Pläne bieten unbegrenzte Workflows. Die Preisgestaltung skaliert stattdessen nach Execution-Anzahl.
9. Sicherheitseinstellungen für Produktion
Essenzielle Konfiguration
N8N_ENCRYPTION_KEY=<openssl rand -hex 32>
N8N_PROTOCOL=https
N8N_SECURE_COOKIE=true
N8N_BLOCK_ENV_ACCESS_IN_NODE=true
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
N8N_PROXY_HOPS=1
NODE_ENV=production
N8N_DIAGNOSTICS_ENABLED=false
N8N_LOG_LEVEL=warn
Der N8N_ENCRYPTION_KEY ist der kritischste Wert der gesamten Installation. Dieser Schlüssel verschlüsselt sämtliche gespeicherten Credentials (API-Keys, Passwörter, Tokens) in der Datenbank. Geht er verloren, sind alle Credentials unwiederbringlich verloren. Der Schlüssel muss separat gesichert werden und über alle Instanzen (Main + Worker im Queue-Modus) identisch sein.
Produktions-Checkliste
- HTTPS mit gültigem SSL-Zertifikat erzwingen
- Port 5678 nie direkt exponieren – immer hinter Reverse Proxy
- 2FA für alle Admin-Accounts aktivieren
- Ungenutzte Nodes ausschließen:
NODES_EXCLUDE=["n8n-nodes-base.executeCommand"] - Webhook-Endpoints authentifizieren (Header Auth, JWT, HMAC)
- Rate Limiting auf Reverse-Proxy-Ebene implementieren
- Fail2ban auf dem Host konfigurieren
- Firewall: nur Ports 80/443 öffnen
10. Performance-Tuning und Skalierung mit Queue-Modus
Architektur im Queue-Modus
Der Queue-Modus trennt Scheduling von Execution: Die Main-Instanz verwaltet UI, API, Trigger und Webhooks, übergibt Workflow-Ausführungen aber an eine Redis-Queue. Separate Worker-Prozesse ziehen Jobs aus der Queue und führen sie aus. Dies ermöglicht horizontale Skalierung.
Docker Compose mit Queue-Modus (PostgreSQL + Redis + Worker)
version: "3.8"
services:
postgres:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: always
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
n8n:
image: docker.n8n.io/n8nio/n8n:2.8.0
restart: always
ports:
- "5678:5678"
environment:
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD}
- N8N_CONCURRENCY_PRODUCTION_LIMIT=20
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
- NODE_OPTIONS=--max-old-space-size=2048
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
n8n-worker:
image: docker.n8n.io/n8nio/n8n:2.8.0
restart: always
command: worker
environment:
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD}
- QUEUE_HEALTH_CHECK_ACTIVE=true
- NODE_OPTIONS=--max-old-space-size=2048
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
volumes:
pg_data:
redis_data:
n8n_data:
Worker skalieren:
docker compose up -d --scale n8n-worker=3
Performance-Optimierungen
# Binärdaten auf Filesystem statt RAM speichern
N8N_DEFAULT_BINARY_DATA_MODE=filesystem
# Execution-Pruning aggressiv konfigurieren
EXECUTIONS_DATA_MAX_AGE=168
EXECUTIONS_DATA_PRUNE_MAX_COUNT=5000
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none # Nur Fehler speichern
# Node.js Heap vergrößern
NODE_OPTIONS=--max-old-space-size=4096
# Docker Resource-Limits setzen
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 1G
Minimum für Produktion: 2 GB RAM. Jeder Worker verbraucht 200–500 MB RAM. Empfohlene Concurrency pro Worker: 5–10. Im Queue-Modus ist PostgreSQL zwingend erforderlich, SQLite wird nicht unterstützt. Für Binärdaten in verteilten Setups muss S3/MinIO statt Filesystem verwendet werden.
11. Webhooks und externe Erreichbarkeit
URL-Struktur
| Typ | URL-Muster |
|---|---|
| Produktion | https://n8n.example.com/webhook/<pfad> |
| Test | https://n8n.example.com/webhook-test/<pfad> |
Produktions-Webhooks funktionieren nur bei aktiviertem Workflow. Test-Webhooks laufen ~120 Sekunden nach Klick auf „Listen for Test Event".
Externe Erreichbarkeit einrichten
- DNS A-Record auf Server-IP zeigen lassen
- Firewall öffnen:
sudo ufw allow 80 && sudo ufw allow 443 - Reverse Proxy konfigurieren (Nginx/Traefik)
WEBHOOK_URL=https://n8n.example.com/setzenN8N_PROXY_HOPS=1setzen- Workflow aktivieren
Webhook testen
curl -X POST https://n8n.example.com/webhook/mein-endpoint \
-H "Content-Type: application/json" \
-d '{"name": "test", "event": "order_created"}'
Webhook-Sicherheit
Der Webhook-Node bietet eingebaute Authentifizierungsoptionen: Header Auth (geheimer Header), Basic Auth, JWT Auth und IP-Whitelisting. Für Dienste wie Stripe oder GitHub sollte die HMAC-Signatur-Verifizierung über einen Code-Node implementiert werden. Unauthentifizierte Webhook-Endpoints sollten in Produktion nie verwendet werden.
12. Community Nodes installieren
Über die UI (empfohlen)
Settings → Community Nodes → Install → npm-Paketnamen eingeben (z.B. n8n-nodes-mcp) → Risikohinweis bestätigen → Install. Nur Owner- oder Admin-Rollen können installieren.
Per CLI (für Queue-Modus oder private Pakete)
docker exec -it n8n bash
cd /home/node/.n8n
npm install n8n-nodes-<paketname>
# Dann n8n neu starten
Im Queue-Modus muss das Paket auf allen Worker-Containern installiert werden.
Relevante Umgebungsvariablen
N8N_COMMUNITY_PACKAGES_ENABLED=true
N8N_REINSTALL_MISSING_PACKAGES=true # Reinstall nach Container-Neustart
N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true # Als AI-Agent-Tools erlauben
Community Nodes werden im Verzeichnis ~/.n8n/nodes/ gespeichert – das Volume muss persistiert sein, sonst gehen die Nodes bei Container-Neustart verloren.
13. Aktuelle n8n-Version (Februar 2026)
| Kanal | Version | Datum |
|---|---|---|
| Stable | 2.8.0 | 11. Feb 2026 |
| Beta | 2.9.0 | 16. Feb 2026 |
| Legacy 1.x | 1.123.21 | 20. Feb 2026 |
14. Typische Troubleshooting-Probleme und Lösungen
Container startet nicht – Berechtigungsfehler
EACCES: permission denied, open '/home/node/.n8n/config'
n8n läuft als User node (UID 1000). Fix: sudo chown -R 1000:1000 /pfad/zu/n8n/data oder user: "1000:1000" in der docker-compose.yml setzen.
Webhooks nicht erreichbar
Häufigste Ursachen: WEBHOOK_URL nicht gesetzt oder zeigt auf localhost, Workflow nicht aktiviert (Produktions-Webhooks erfordern aktivierten Workflow), fehlende Proxy-Header in Nginx/Traefik, oder N8N_PROXY_HOPS nicht korrekt. Diagnose:
docker exec n8n env | grep WEBHOOK_URL
curl -X POST https://n8n.example.com/webhook/test -d '{"test": true}'
Memory-Probleme / OOM
docker stats n8n # Ressourcen überwachen
# Sofortmaßnahmen:
N8N_DEFAULT_BINARY_DATA_MODE=filesystem
EXECUTIONS_DATA_MAX_AGE=168
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
NODE_OPTIONS=--max-old-space-size=4096
Große Datenmengen in kleineren Batches verarbeiten (200 statt 10.000 Zeilen). Sub-Workflows nutzen, um Speicher zu isolieren.
Encryption Key verloren
Katastrophal. Wenn der N8N_ENCRYPTION_KEY verloren geht und kein Backup existiert, sind alle gespeicherten Credentials unwiederbringlich verloren. Prävention: Key aus ~/.n8n/config sichern, explizit als Umgebungsvariable setzen, und separat vom Datenbank-Backup aufbewahren.
Schnellreferenz häufiger Fehler
| Fehler | Lösung |
|---|---|
EACCES: permission denied |
chown -R 1000:1000 /data/pfad |
Received request for unknown webhook |
Workflow aktivieren |
Request failed with status code 401 |
OAuth-Tokens erneuern |
Out of memory |
Memory-Limits erhöhen, Binary-Mode auf Filesystem |
Missing encryption key |
N8N_ENCRYPTION_KEY identisch auf allen Instanzen setzen |
| Zeitzone falsch | GENERIC_TIMEZONE=Europe/Berlin und TZ=Europe/Berlin setzen |
Debug-Logging aktivieren
N8N_LOG_LEVEL=debug # Nur für aktives Debugging, danach auf warn zurücksetzen
docker logs -f n8n --tail 200
docker logs n8n | grep -i "error"
Fazit und Kernempfehlungen
Self-hosted n8n 2.x ist eine ausgereifte Plattform für Workflow-Automatisierung. Die fünf entscheidenden Konfigurationsentscheidungen für jede produktive Installation lauten: PostgreSQL statt SQLite, explizit gesetzter und gesicherter Encryption Key, Reverse Proxy mit SSL (Nginx oder Traefik), Execution-Pruning aktivieren, und Version Pinning im Docker-Image. Wer mehr als gelegentliche Workflow-Ausführungen benötigt, sollte den Queue-Modus mit Redis und separaten Workern evaluieren – er verwandelt n8n von einer Single-Process-Anwendung in eine horizontal skalierbare Architektur. Die Community Edition deckt den Großteil aller Anwendungsfälle ab; Enterprise-Features wie SSO, RBAC und Multi-Main-HA werden erst in größeren Team-Setups oder bei Compliance-Anforderungen relevant.