n8n mit Docker Compose auf einem VPS installieren

8 Min. Lesezeit·Matthieu|

Richten Sie n8n 2.x mit Docker Compose und PostgreSQL auf einem VPS ein. Produktionsreif von Anfang an mit fixierten Versionen, Backup des Verschlüsselungsschlüssels, Health Checks und Ressourcenlimits.

Diese Anleitung installiert n8n 2.12.3 mit Docker Compose und PostgreSQL auf einem VPS. Sie haben in etwa 15 Minuten eine funktionierende n8n-Instanz. Die Konfiguration verwendet von Anfang an Produktionsstandards: fixierte Image-Versionen, verschlüsselte Zugangsdaten, Port-Binding ausschließlich auf localhost, Health Checks auf beiden Containern und Docker-Ressourcenlimits. Kein Reverse Proxy oder SSL hier. Das wird in behandelt.

Was brauche ich vor der Installation von n8n?

Sie benötigen einen VPS mit Debian 12 oder Ubuntu 24.04 und mindestens 4 GB RAM. Docker und Docker Compose (das docker compose-Plugin, nicht das alte docker-compose-Binary) müssen installiert sein. Falls Docker noch nicht eingerichtet ist, folgen Sie zuerst Docker Compose für Multi-Service-VPS-Deployments.

Prüfen Sie, ob Docker Compose verfügbar ist:

docker compose version

Erwartete Ausgabe:

Docker Compose version v2.x.x

Falls dieser Befehl mit docker: 'compose' is not a docker command fehlschlägt, haben Sie das veraltete Standalone-Binary. Installieren Sie stattdessen das Docker Compose Plugin aus dem offiziellen Docker-Repository.

Sie benötigen außerdem einen Nicht-Root-Benutzer mit sudo-Zugang. Alle Befehle in dieser Anleitung werden mit diesem Benutzer ausgeführt, nicht als root.

Warum PostgreSQL statt SQLite für n8n?

PostgreSQL verarbeitet gleichzeitige Verbindungen, unterstützt WAL für Crash-Recovery und funktioniert mit pg_dump für Hot Backups, während n8n läuft. SQLite sperrt die gesamte Datenbankdatei bei jedem Schreibvorgang. Bei gleichzeitigen Webhook-Ausführungen führt das zu Timeouts und Datenkorruption. Eine SQLite-Datenbank kann nicht sicher gesichert werden, während n8n läuft, ohne eine korrupte Kopie zu riskieren. Für alles, was über lokale Tests hinausgeht, ist PostgreSQL die richtige Wahl.

Eigenschaft SQLite PostgreSQL
Gleichzeitige Schreibvorgänge Single-Writer-Lock Volles MVCC
Hot Backups Unsicher im Betrieb pg_dump jederzeit
Crash-Recovery Manuelles Journal-Replay Automatisches WAL-Replay
Skalierung Einzelprozess Connection Pooling
n8n-Umgebungsvariable DB_TYPE=sqlite DB_TYPE=postgresdb

Wie installiere ich n8n mit Docker Compose auf einem VPS?

Erstellen Sie ein Projektverzeichnis, schreiben Sie eine .env-Datei mit Ihren Secrets, schreiben Sie die docker-compose.yml, starten Sie den Stack und überprüfen Sie, dass alles gesund ist. Jeder Schritt enthält eine Überprüfung.

Projektverzeichnis erstellen

mkdir -p ~/n8n && cd ~/n8n

Die .env-Datei erstellen

Alle Secrets gehören in eine .env-Datei. Schreiben Sie Passwörter oder Schlüssel niemals direkt in docker-compose.yml.

Generieren Sie ein starkes Datenbankpasswort und den n8n-Verschlüsselungsschlüssel:

echo "POSTGRES_PASSWORD=$(openssl rand -base64 32)" >> .env
echo "N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env

Fügen Sie nun die restlichen Variablen hinzu:

cat >> .env << 'EOF'
# PostgreSQL
POSTGRES_USER=n8n
POSTGRES_DB=n8n

# n8n
N8N_VERSION=2.12.3
N8N_HOST=localhost
N8N_PORT=5678
N8N_PROTOCOL=http
N8N_DIAGNOSTICS_ENABLED=false
GENERIC_TIMEZONE=UTC
EOF

Schränken Sie die Dateiberechtigungen ein. Nur Ihr Benutzer sollte diese Datei lesen können:

chmod 600 .env

Überprüfung:

ls -la .env

Sie sollten -rw------- sehen. Kein anderer Benutzer auf dem Server kann Ihr Datenbankpasswort oder Ihren Verschlüsselungsschlüssel lesen.

Wie generiere und sichere ich den n8n-Verschlüsselungsschlüssel?

Der N8N_ENCRYPTION_KEY wurde oben mit openssl rand -hex 32 generiert. Das erzeugt einen zufälligen 32-Byte-Schlüssel (64 Hexadezimalzeichen). n8n verwendet diesen Schlüssel zur Verschlüsselung aller gespeicherten Zugangsdaten: API-Schlüssel, OAuth-Tokens, Datenbankpasswörter in Workflows. Wenn Sie diesen Schlüssel verlieren, werden alle gespeicherten Zugangsdaten dauerhaft unlesbar. Es gibt keinen Wiederherstellungsmechanismus.

Sichern Sie den Verschlüsselungsschlüssel jetzt. Kopieren Sie ihn in einen Passwortmanager oder einen Offline-Tresor:

grep N8N_ENCRYPTION_KEY .env

Speichern Sie die Ausgabe an einem sicheren Ort außerhalb dieses Servers. Tun Sie das, bevor Sie Ihre ersten Zugangsdaten in n8n hinzufügen.

Referenz der Umgebungsvariablen

Variable Zweck Beispielwert
POSTGRES_USER PostgreSQL-Superuser-Name n8n
POSTGRES_PASSWORD PostgreSQL-Superuser-Passwort (generiert, 32+ Zeichen)
POSTGRES_DB Datenbankname n8n
N8N_VERSION Fixierter n8n-Image-Tag 2.12.3
N8N_ENCRYPTION_KEY Verschlüsselt gespeicherte Zugangsdaten (generiert, 64 Hex-Zeichen)
N8N_HOST Host für die n8n-Oberfläche localhost
N8N_PORT Port für die n8n-Oberfläche 5678
N8N_PROTOCOL HTTP oder HTTPS http
N8N_DIAGNOSTICS_ENABLED Telemetrie an n8n senden false
GENERIC_TIMEZONE Zeitzone für Cron-Trigger UTC

Die docker-compose.yml schreiben

cat > docker-compose.yml << 'COMPOSE'
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"
    security_opt:
      - no-new-privileges:true
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  n8n:
    image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
    restart: unless-stopped
    environment:
      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}
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      N8N_HOST: ${N8N_HOST}
      N8N_PORT: ${N8N_PORT}
      N8N_PROTOCOL: ${N8N_PROTOCOL}
      N8N_DIAGNOSTICS_ENABLED: ${N8N_DIAGNOSTICS_ENABLED}
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
    ports:
      - "127.0.0.1:5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:5678/healthz || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: "2.0"
    security_opt:
      - no-new-privileges:true
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  postgres_data:
  n8n_data:
COMPOSE

Einige Punkte zu dieser Datei:

Kein version:-Schlüssel. Docker Compose V2 ignoriert ihn. Alle Konkurrenz-Tutorials enthalten noch version: '3.7' oder version: '3.8'. Die Compose-Spezifikation hat dieses Feld als veraltet markiert. Es einzufügen erzeugt eine Warnung bei aktuellen Docker-Versionen.

Port an 127.0.0.1 gebunden. Die Zeile "127.0.0.1:5678:5678" beschränkt n8n auf localhost. Das ist eine Sicherheitsanforderung, keine Präferenz. Docker-Port-Mappings umgehen iptables und UFW-Regeln vollständig. Wenn Sie 5678:5678 ohne den Präfix 127.0.0.1 schreiben, ist n8n aus dem Internet erreichbar, selbst wenn Ihre Firewall Port 5678 blockiert. Ein Reverse Proxy auf derselben Maschine leitet den Datenverkehr an localhost:5678 weiter, sobald Sie einen einrichten.

security_opt: no-new-privileges:true verhindert, dass Prozesse im Container über setuid- oder setgid-Binaries zusätzliche Privilegien erlangen. Das ist eine Defense-in-Depth-Maßnahme gegen Container-Escape-Angriffe.

Log-Rotation. Der logging-Block begrenzt das JSON-Log jedes Containers auf 3 Dateien mit je 10 MB (maximal 30 MB pro Service). Ohne diese Einstellung wachsen Docker-Logs, bis Ihre Festplatte voll ist. Auf einem VPS mit begrenztem Speicher ist das relevant.

Health Checks auf beiden Services. PostgreSQL verwendet pg_isready. n8n nutzt seinen /healthz-Endpoint. Die depends_on-Bedingung stellt sicher, dass n8n erst startet, nachdem PostgreSQL seinen Health Check bestanden hat.

Ressourcenlimits. PostgreSQL erhält 512 MB RAM und 1 CPU. n8n erhält 2 GB RAM und 2 CPUs. Diese Werte funktionieren gut auf einem VPS mit 4-8 GB. Passen Sie sie an Ihre Servergröße und Workflow-Komplexität an.

Benannte Volumes. Sowohl postgres_data als auch n8n_data sind von Docker verwaltete benannte Volumes. Docker regelt Eigentümerschaft und Berechtigungen innerhalb des Volumes automatisch. Es ist nicht nötig, Host-Verzeichnisse zu erstellen oder Berechtigungen manuell zu korrigieren.

restart: unless-stopped statt restart: always. Beide starten nach Abstürzen neu, aber unless-stopped respektiert manuelle docker compose stop-Befehle. Mit restart: always startet ein manuell gestoppter Container neu, wenn der Docker-Daemon neu startet (z. B. nach einem Systemupdate).

Den Stack starten

cd ~/n8n
docker compose up -d

Beobachten Sie die Logs beim ersten Start:

docker compose logs -f

Warten Sie, bis n8n eine Zeile mit n8n ready on ausgibt. Drücken Sie Ctrl+C, um den Log-Viewer zu beenden.

Die Installation überprüfen

Überprüfen Sie, dass beide Container laufen und gesund sind:

docker compose ps

Erwartete Ausgabe:

NAME       IMAGE                                  ...  STATUS                    PORTS
n8n-n8n-1       docker.n8n.io/n8nio/n8n:2.12.3   ...  Up X minutes (healthy)    127.0.0.1:5678->5678/tcp
n8n-postgres-1  postgres:16-alpine                ...  Up X minutes (healthy)

Achten Sie darauf: Beide Container zeigen (healthy) in der Spalte STATUS. Das bestätigt, dass die Health Checks bestanden werden. Falls Sie (health: starting) sehen, warten Sie 30 Sekunden und prüfen Sie erneut.

Testen Sie die n8n-API vom Server aus:

curl -s http://localhost:5678/healthz

Erwartete Ausgabe:

{"status":"ok"}

Überprüfen Sie, dass der Port nur auf localhost lauscht, nicht auf allen Interfaces:

ss -tlnp | grep 5678

Sie sollten 127.0.0.1:5678 in der Ausgabe sehen. Falls Sie 0.0.0.0:5678 sehen, ist Ihr Port-Binding falsch. Stoppen Sie den Stack, korrigieren Sie die ports-Zeile in docker-compose.yml und starten Sie neu.

Wie erstelle ich das n8n-Owner-Konto?

Öffnen Sie einen SSH-Tunnel von Ihrem lokalen Rechner, um n8n über Ihren Browser zu erreichen:

ssh -L 5678:127.0.0.1:5678 your-user@your-server-ip

Öffnen Sie nun http://localhost:5678 in Ihrem Browser. n8n zeigt beim ersten Zugriff einen Einrichtungsbildschirm. Erstellen Sie Ihr Owner-Konto mit einem starken Passwort. Dieses Konto hat vollen Administratorzugang zu n8n.

Schließen Sie nach der Kontoerstellung den SSH-Tunnel. Lassen Sie Port 5678 nicht länger als nötig getunnelt. Richten Sie einen Reverse Proxy mit SSL für den regulären Zugang ein. Siehe .

Wie überprüfe ich, dass n8n korrekt läuft?

Führen Sie nach der Kontoerstellung und dem Schließen des SSH-Tunnels eine letzte Reihe von Prüfungen vom Server aus durch.

Container-Gesundheit prüfen:

docker compose ps --format "table {{.Name}}\t{{.Status}}"

Beide Services sollten (healthy) anzeigen.

n8n-Logs auf Fehler prüfen:

docker compose logs n8n --tail 20

Suchen Sie nach ERROR-Zeilen. Ein sauberer Start zeigt Datenbankmigrationsmeldungen gefolgt von n8n ready on.

PostgreSQL-Logs prüfen:

docker compose logs postgres --tail 10

Sie sollten database system is ready to accept connections sehen.

Speicherverbrauch Ihrer Docker-Volumes prüfen:

docker system df -v | grep -E "n8n|postgres"

Das zeigt Ihnen, wie viel Speicher n8n und PostgreSQL verbrauchen. Prüfen Sie das regelmäßig auf VPS-Instanzen mit begrenztem Speicher.

Etwas ist schiefgelaufen?

Container beendet sich sofort. Prüfen Sie die Logs mit docker compose logs n8n. Häufige Ursachen: fehlende .env-Datei, falsches PostgreSQL-Passwort oder der Verschlüsselungsschlüssel enthält Sonderzeichen, die die Shell-Expansion stören. Generieren Sie Ihre .env bei Bedarf neu.

Berechtigungsfehler. Der n8n-Container läuft als UID 1000. Wenn Sie von benannten Volumes auf Bind Mounts umsteigen, stellen Sie sicher, dass das Host-Verzeichnis UID 1000 gehört: sudo chown -R 1000:1000 ./n8n_data.

Health Check schlägt fehl. n8n braucht beim ersten Start 20-30 Sekunden, während die Datenbankmigrationen ausgeführt werden. Falls Health Checks fehlschlagen, prüfen Sie docker compose logs n8n auf Migrationsfehler. Die Einstellung start_period: 30s gibt n8n Zeit, bevor die Health Checks beginnen.

Verbindung zu n8n nicht möglich. Der Port ist an localhost gebunden. Sie können ohne SSH-Tunnel oder Reverse Proxy nicht von einem anderen Rechner darauf zugreifen. Das ist beabsichtigt.

Verschlüsselungsschlüssel vergessen. Wenn Sie N8N_ENCRYPTION_KEY verloren haben und n8n Zugangsdaten gespeichert hat, sind diese Zugangsdaten verloren. Eine Wiederherstellung ist nicht möglich. Deshalb gibt es den Backup-Schritt.

Was sollte ich nach der Installation von n8n tun?

Diese Installation gibt Ihnen eine funktionierende n8n-Instanz, die nur vom Server selbst erreichbar ist. Für den Produktionseinsatz benötigen Sie drei weitere Dinge:

  1. Reverse Proxy mit SSL. Richten Sie Nginx oder Caddy vor n8n mit einem TLS-Zertifikat ein. Das ermöglicht HTTPS-Zugang mit einem Domainnamen. Siehe .

  2. Backups. Planen Sie automatisierte Backups der PostgreSQL-Datenbank und des n8n-Verschlüsselungsschlüssels. Siehe .

  3. Updates. Um n8n zu aktualisieren, ändern Sie N8N_VERSION in .env auf die neue Version und führen Sie dann docker compose up -d aus. Docker zieht das neue Image und erstellt den Container neu. Lesen Sie immer die n8n Release Notes vor dem Update.

Für die übergeordnete Anleitung zu Workflow-Automatisierungsoptionen auf einem VPS siehe .

Für Docker-Compose-Grundlagen und die Verwaltung mehrerer Services siehe Docker Compose für Multi-Service-VPS-Deployments.


Copyright 2026 Virtua.Cloud. Alle Rechte vorbehalten. Dieser Inhalt ist ein Originalwerk des Virtua.Cloud-Teams. Vervielfältigung, Wiederveröffentlichung oder Weiterverbreitung ohne schriftliche Genehmigung ist untersagt.

Bereit, es selbst auszuprobieren?

Stellen Sie Ihren eigenen Server in Sekunden bereit. Linux, Windows oder FreeBSD.

VPS-Angebote ansehen