n8n auf Hetzner installieren: DSGVO-konformer Automatisierungsserver
n8n auf Hetzner installieren: Servertyp, Docker Compose mit Caddy und warum der deutsche Serverstandort für DSGVO-konforme Automatisierung zählt.
So installieren Sie n8n mit Docker Compose: Postgres statt SQLite, .env, Volumes und Updates Schritt für Schritt.
n8n lässt sich mit Docker Compose in wenigen Schritten auf einem eigenen Server installieren. Sie legen eine compose.yaml und eine .env-Datei an, definieren Volumes für die dauerhaften Daten und starten den Stack mit einem einzigen Befehl.
Für den produktiven Betrieb wechseln viele Betreiber von der mitgelieferten SQLite-Datenbank zu PostgreSQL. Dieser Artikel zeigt die Compose-Datei, die nötigen Umgebungsvariablen, die Volumes und den Ablauf für Updates.
Die Installation besteht aus vier Schritten: Docker prüfen, Projektverzeichnis anlegen, compose.yaml und .env schreiben, Stack starten. Danach ist n8n unter Ihrer Domain erreichbar.
docker --version und docker compose versionlocal-files für den Dateiaustauschcompose.yaml und .env in dieses Verzeichnis legendocker compose up -dDie folgende compose.yaml folgt dem offiziellen Setup aus der n8n-Dokumentation zu Docker Compose. Traefik übernimmt darin den Reverse Proxy und die TLS-Zertifikate.
1services:2 traefik:3 image: traefik:v3.14 restart: always5 command:6 - "--providers.docker=true"7 - "--providers.docker.exposedbydefault=false"8 - "--entrypoints.web.address=:80"9 - "--entrypoints.web.http.redirections.entryPoint.to=websecure"10 - "--entrypoints.web.http.redirections.entrypoint.scheme=https"11 - "--entrypoints.websecure.address=:443"12 - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"13 - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"14 - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"15 ports:16 - "80:80"17 - "443:443"18 volumes:19 - traefik_data:/letsencrypt20 - /var/run/docker.sock:/var/run/docker.sock:ro21
22 n8n:23 image: n8nio/n8n:1.81.024 restart: always25 ports:26 - "127.0.0.1:5678:5678"27 labels:28 - traefik.enable=true29 - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)30 - traefik.http.routers.n8n.tls=true31 - traefik.http.routers.n8n.entrypoints=web,websecure32 - traefik.http.routers.n8n.tls.certresolver=mytlschallenge33 - traefik.http.middlewares.n8n.headers.SSLRedirect=true34 - traefik.http.middlewares.n8n.headers.STSSeconds=31536000035 - traefik.http.middlewares.n8n.headers.browserXSSFilter=true36 - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true37 - traefik.http.middlewares.n8n.headers.forceSTSHeader=true38 - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}39 - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true40 - traefik.http.middlewares.n8n.headers.STSPreload=true41 - traefik.http.routers.n8n.middlewares=n8n@docker42 environment:43 - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}44 - N8N_PORT=567845 - N8N_PROTOCOL=https46 - NODE_ENV=production47 - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/48 - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}49 - TZ=${GENERIC_TIMEZONE}50 - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true51 - N8N_RUNNERS_ENABLED=true52 - N8N_RESTRICT_FILE_ACCESS_TO=/files53 volumes:54 - n8n_data:/home/node/.n8n55 - ./local-files:/files56
57volumes:58 n8n_data:59 traefik_data:Der Versions-Tag 1.81.0 ist bewusst gesetzt. Ohne Tag zieht docker compose pull jede neue Hauptversion mit, auch wenn sich Umgebungsvariablen geändert haben.
Die .env-Datei enthält alle Werte, die sich von Server zu Server unterscheiden. Dadurch bleibt die compose.yaml auf jedem Server identisch.
1DOMAIN_NAME=beispiel.de2SUBDOMAIN=n8n3GENERIC_TIMEZONE=Europe/Berlin4SSL_EMAIL=technik@beispiel.deVariable | Zweck | Beispielwert
Variable: DOMAIN_NAME · Zweck: Basisdomain für Traefik-Regel und TLS · Beispielwert: beispiel.de
Variable: SUBDOMAIN · Zweck: Subdomain, unter der n8n läuft · Beispielwert: n8n
Variable: GENERIC_TIMEZONE · Zweck: Zeitzone für Zeitplan-Nodes und TZ · Beispielwert: Europe/Berlin
Variable: SSL_EMAIL · Zweck: Kontaktadresse für die Zertifikatsausstellung · Beispielwert: technik@beispiel.de
Die Datei enthält serverspezifische Werte und später oft auch Passwörter. Sie gehört deshalb in die .gitignore und nie in ein öffentliches Repository.
SQLite reicht für Einzelinstanzen mit wenigen parallelen Ausführungen, PostgreSQL ist die richtige Wahl für produktive Server mit vielen Workflows. n8n nutzt ohne weitere Konfiguration SQLite und legt die Datei database.sqlite im Verzeichnis .n8n ab.
Kriterium | SQLite | PostgreSQL
Kriterium: Konfiguration · SQLite: keine, Standard · PostgreSQL: DB_TYPE und fünf weitere Variablen
Kriterium: Parallele Ausführungen · SQLite: begrenzt, Schreibsperren auf Dateiebene · PostgreSQL: für parallele Zugriffe ausgelegt
Kriterium: Backup im laufenden Betrieb · SQLite: Datei kopieren ist heikel · PostgreSQL: pg_dump ohne Stopp möglich
Kriterium: Queue-Modus mit mehreren Workern · SQLite: nicht geeignet · PostgreSQL: Voraussetzung
Kriterium: Zusätzlicher Container · SQLite: nein · PostgreSQL: ja
Die Variablennamen stehen in der Dokumentation zur Datenbankauswahl. Der folgende Ausschnitt ergänzt dieselbe compose.yaml. Die Zeilen unter n8n gehören in den bereits vorhandenen Block, nicht in einen zweiten.
1services:2 postgres:3 image: postgres:16.44 restart: always5 environment:6 - POSTGRES_DB=${POSTGRES_DB}7 - POSTGRES_USER=${POSTGRES_USER}8 - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}9 volumes:10 - postgres_data:/var/lib/postgresql/data11 healthcheck:12 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]13 interval: 10s14 timeout: 5s15 retries: 516
17 n8n:18 depends_on:19 postgres:20 condition: service_healthy21 environment:22 - DB_TYPE=postgresdb23 - DB_POSTGRESDB_HOST=postgres24 - DB_POSTGRESDB_PORT=543225 - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}26 - DB_POSTGRESDB_USER=${POSTGRES_USER}27 - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}28 - DB_POSTGRESDB_SCHEMA=public29
30volumes:31 postgres_data:Die drei neuen Werte kommen ebenfalls in die .env-Datei:
1POSTGRES_DB=n8n2POSTGRES_USER=n8n3POSTGRES_PASSWORD=hier-ein-langes-zufaelliges-passwortAuch mit PostgreSQL bleibt das Volume auf /home/node/.n8n notwendig. Dort liegt der Schlüssel, mit dem n8n die gespeicherten Zugangsdaten verschlüsselt.
Vier Speicherorte müssen einen Neuaufbau des Containers überleben. Fehlt einer davon, gehen Workflows, Zugangsdaten, Zertifikate oder ausgetauschte Dateien verloren.
Volume oder Pfad | Ziel im Container | Inhalt
Volume oder Pfad: n8n_data · Ziel im Container: /home/node/.n8n · Inhalt: Verschlüsselungsschlüssel, SQLite-Datei, Instanzdaten
Volume oder Pfad: traefik_data · Ziel im Container: /letsencrypt · Inhalt: TLS-Zertifikate von Let's Encrypt
Volume oder Pfad: postgres_data · Ziel im Container: /var/lib/postgresql/data · Inhalt: Datenbank, sofern PostgreSQL genutzt wird
Volume oder Pfad: ./local-files · Ziel im Container: /files · Inhalt: Dateiaustausch zwischen Host und Workflows
Im Workflow sprechen Sie den Austauschordner über den Pfad /files an, nicht über den Host-Pfad. Die Variable N8N_RESTRICT_FILE_ACCESS_TO begrenzt den Zugriff auf genau dieses Verzeichnis.
Ein Update läuft über die drei Befehle docker compose pull, docker compose down und docker compose up -d. Die Volumes bleiben dabei unberührt, Workflows und Zugangsdaten also erhalten.
1cd /opt/n8n2docker compose pull3docker compose down4docker compose up -d5docker compose logs -f n8nVor dem Update ändern Sie den Versions-Tag in der compose.yaml auf die gewünschte Version. Prüfen Sie vorher die Release-Hinweise, weil sich Umgebungsvariablen zwischen Hauptversionen ändern können.
Der Tag next liefert die instabile Beta-Version und gehört nicht auf einen produktiven Server. Die Tag-Übersicht steht in der Anleitung zur Docker-Installation.
Wer eine saubere Konfiguration von Anfang an will, plant lieber einmal gründlich. Genau das übernimmt NordFlux im Rahmen der n8n-Einrichtung zum Festpreis, inklusive Entscheidung zwischen SQLite und PostgreSQL.
Fünf Fehlerbilder treten bei Docker-Compose-Installationen besonders häufig auf. Alle lassen sich über Umgebungsvariablen oder Volumes lösen.
Zugangsdaten lassen sich nach einem Neuaufbau nicht mehr entschlüsseln.
Ursache: Das Volume auf /home/node/.n8n fehlte oder wurde neu angelegt, also erzeugte n8n einen neuen Verschlüsselungsschlüssel. Lösung: Volume dauerhaft mounten oder N8N_ENCRYPTION_KEY fest vorgeben. Quelle: Umgebungsvariablen für das Deployment.
Webhook-URLs im Editor zeigen auf localhost statt auf die Domain.
Ursache: WEBHOOK_URL und N8N_HOST sind nicht gesetzt, n8n kennt seine öffentliche Adresse nicht. Lösung: beide Variablen wie im Beispiel oben setzen und den Container neu starten. Quelle: Setup mit Docker Compose.
Zeitplan-Nodes feuern zur falschen Uhrzeit.
Ursache: Nur TZ oder nur GENERIC_TIMEZONE ist gesetzt, der Container läuft sonst auf UTC. Lösung: beide Variablen auf denselben Wert setzen, etwa Europe/Berlin. Quelle: Installation mit Docker.
n8n meldet beim Start eine Deprecation-Warnung zu Task Runnern.
Ursache: N8N_RUNNERS_ENABLED fehlt in der Konfiguration. Lösung: Variable in Version 1.x auf true setzen. Ab n8n 2.0 ist sie überflüssig. Quelle: Installation mit Docker.
Ein Workflow findet eine Datei auf dem Server nicht.
Ursache: N8N_RESTRICT_FILE_ACCESS_TO steht auf /files, der Workflow nutzt aber den Host-Pfad. Lösung: im Workflow den Containerpfad /files/... verwenden und den Mount ./local-files:/files prüfen. Quelle: Setup mit Docker Compose.
Nein. Für eine einfache Einzelcontainer-Installation genügen ein Volume und der Port 5678, n8n ist dann unter http://localhost:5678 erreichbar. Eine Domain brauchen Sie erst für den Aufbau mit Traefik und automatischem TLS-Zertifikat.
Im Volume, das auf /home/node/.n8n zeigt. Dort liegt bei SQLite-Nutzung die Datenbankdatei und unabhängig von der Datenbankwahl der Verschlüsselungsschlüssel. Ohne dieses Volume sind die Daten nach dem nächsten Neuaufbau verloren.
Die Reihenfolge docker compose pull, docker compose down und docker compose up -d tauscht nur das Image aus. Workflows, Zugangsdaten und Datenbank liegen in den Volumes und bleiben erhalten. Vor größeren Versionssprüngen lohnt ein Blick in die Release-Hinweise.
Ja, über den Image-Tag. Ein Tag wie 1.81.0 fixiert eine stabile Version, der Tag next liefert die instabile Beta-Version. Für produktive Server ist ein fixierter Versions-Tag die verlässlichere Wahl.
Gründer von NordFlux. Sieben Jahre Erfahrung von Web und SEO bis zur Automatisierung im Konzern-Maßstab, heute pragmatisch für den Mittelstand und mit deutscher Datenhoheit.
Zertifizierungen
n8n auf Hetzner installieren: Servertyp, Docker Compose mit Caddy und warum der deutsche Serverstandort für DSGVO-konforme Automatisierung zählt.
Das Self-hosted AI Starter Kit von n8n startet n8n, Ollama, Qdrant und PostgreSQL per Docker Compose fuer lokale KI-Workflows ohne Cloud-APIs.
npm, Docker oder Desktop-App: Wie Sie n8n lokal testen, was sich bei Persistenz und Aufwand unterscheidet und warum die Desktop-App nicht mehr existiert.
Postgres statt SQLite, eine saubere .env-Datei und richtig gesetzte Volumes sind die Grundlage, doch erst der laufende Betrieb mit Updates und Backups entscheidet über die Ausfallsicherheit. NordFlux übernimmt den betreuten n8n-Betrieb auf Ihrer Docker-Infrastruktur, mit Monitoring, Updates und getesteten Backups statt Ad-hoc-Wartung. Im ersten Gespräch prüfen wir Ihr aktuelles Setup und zeigen die größten Betriebsrisiken.