Workflow-Automatisierung mit n8n: Self-Hosting, Architektur und erste Workflows
n8n als selbst gehostete Workflow-Engine: Einordnung gegenüber Make, Zapier, Temporal und Airflow, Docker-Setup und ein praxisnaher Beispiel-Workflow.
Automatisierungswerkzeuge sind aus modernen IT-Architekturen nicht wegzudenken. Ob Daten zwischen SaaS-Systemen synchronisiert, Webhooks verarbeitet oder wiederkehrende Batch-Jobs orchestriert werden müssen – ohne eine dedizierte Automatisierungsschicht landet die Logik schnell als Spaghetti-Code in Microservices oder als fragile Shell-Skripte in Cron-Jobs. Dieser Artikel beleuchtet die Klasse der Workflow-Engines am Beispiel von n8n, ordnet sie gegenüber verwandten Werkzeugen ein und zeigt, wie Sie n8n in wenigen Minuten selbst betreiben.
Was ist eine Workflow-Engine?
Eine Workflow-Engine modelliert Automatisierungslogik als gerichteten Graphen aus Nodes. Jeder Node kapselt eine Aktion oder Transformation; Verbindungen (Edges) definieren den Datenfluss. Das Kernprinzip lautet:
Trigger --> Verarbeitung --> Aktion(en)
n8n folgt diesem Modell visuell: Sie ziehen Nodes auf eine Canvas, verbinden sie und konfigurieren sie per Formular. Unter der Haube ist n8n eine Node.js-Anwendung (TypeScript), die Workflows in einer SQLite- oder PostgreSQL-Datenbank persistiert und per Webhooks, Cron oder manuell auslöst.
Typische Anwendungsfälle:
- Eingehende Webhooks verarbeiten und an interne APIs weiterleiten
- Daten zwischen CRM, ERP und Kommunikationsplattformen synchronisieren
- Alerts aus Monitoring-Systemen anreichern und eskalieren
- Datei-Uploads transformieren und in Objektspeicher schreiben
Einordnung: n8n, Make/Zapier, Temporal, Airflow
Bevor Sie ein Werkzeug wählen, lohnt sich eine ehrliche Abgrenzung. Die folgende Tabelle zeigt die wesentlichen Unterschiede:
+------------------+------------+------------+------------+------------+
| Kriterium | n8n | Make/Zapier| Temporal | Airflow |
+------------------+------------+------------+------------+------------+
| Hosting | Self/SaaS | SaaS only | Self/Cloud | Self/Cloud |
| Code-Freiheit | hoch | niedrig | vollstaend.| hoch |
| Visuelle Canvas | ja | ja | nein | DAG-View |
| Durability/Retry | einfach | einfach | nativ/tief | mittel |
| Zielgruppe | Dev/Ops | No-Code | Backend-Dev| Data-Eng. |
| Lizenz | fair-code | proprietaer| MIT | Apache 2.0 |
| DSGVO Self-Host | ja | nein | ja | ja |
+------------------+------------+------------+------------+------------+
Make und Zapier eignen sich für schnelle, no-code Integrationen zwischen Cloud-Diensten. Sobald Sie eigene Transformationslogik, Self-Hosting aus Datenschutzgründen oder komplexere Verzweigungen brauchen, stoßen Sie an Grenzen.
Temporal und Apache Airflow sind echte Code-Orchestratoren. Temporal bietet nativ dauerhafte Workflows mit automatischen Retries, Saga-Pattern und deterministischen Replays – geeignet für verteilte Transaktionen, die Minuten bis Stunden (oder länger) dauern. Airflow ist speziell auf datengetriebene DAG-Pipelines (ETL, ML-Pipelines) ausgerichtet. Beide erfordern deutlich mehr Entwicklungsaufwand und Infrastruktur.
n8n positioniert sich dazwischen: ausreichend mächtig für produktive Integrationsstrecken, entwicklerfreundlich dank Code-Nodes, aber ohne die Garantien eines durable-execution Frameworks. Für operative Webhooks, Benachrichtigungspipelines und mittlere Komplexität ist n8n die pragmatische Wahl.
n8n selbst hosten mit Docker
n8n stellt ein offizielles Docker-Image unter docker.n8n.io/n8nio/n8n bereit. Das folgende docker-compose.yml ist produktionsnah und deckt Persistenz, Zeitzone und Webhook-URL ab:
# docker-compose.yml
services:
n8n:
image: docker.n8n.io/n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_HOST=n8n.beispiel.de
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.beispiel.de/
- GENERIC_TIMEZONE=Europe/Berlin
- TZ=Europe/Berlin
# Verschluesselungs-Key fuer Credentials fest setzen (sonst pro Volume generiert)
- N8N_ENCRYPTION_KEY=bitte-ersetzen-langer-zufallswert
# Externe PostgreSQL-Datenbank statt SQLite
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=db-passwort
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=db-passwort
volumes:
- pg_data:/var/lib/postgresql/data
volumes:
n8n_data:
pg_data:
Starten Sie den Stack mit:
docker compose up -d
# Logs beobachten
docker compose logs -f n8n
n8n ist danach unter http://localhost:5678 erreichbar.
Hinweis zur Authentifizierung: Die früher übliche Basic-Auth über
N8N_BASIC_AUTH_ACTIVE/N8N_BASIC_AUTH_USER/N8N_BASIC_AUTH_PASSWORDwurde mit n8n 1.0 entfernt und ist in aktuellen Versionen wirkungslos. Stattdessen greift das integrierte User-Management: Beim ersten Aufruf legen Sie ein Owner-Konto (E-Mail + Passwort) an; weitere Benutzer laden Sie anschließend ein. Eine echte Schutzschicht für die exponierte Instanz gehört in den vorgelagerten Reverse-Proxy.
In Produktion schalten Sie einen Reverse-Proxy (nginx, Caddy, Traefik) davor, der TLS terminiert und optional IP-Allowlisting umsetzt. Die Variable WEBHOOK_URL muss auf die extern erreichbare HTTPS-URL zeigen, damit Webhook-Nodes korrekte Callback-URLs generieren.
Beispiel-Workflow: Webhook bis HTTP-Request
Der folgende Ablauf illustriert einen typischen Integrationsfall: Ein eingehender Webhook liefert Rohdaten, ein Code-Node transformiert sie, ein HTTP-Request-Node schickt das Ergebnis an eine externe API, und ein Respond-Node antwortet dem Aufrufer.
+-----------------+ +-----------------+ +-----------------+ +-----------------+
| Webhook Trigger |--->| Code / Transform|--->| HTTP Request |--->| Respond to |
| POST /hook/xyz | | (JS, $input) | | POST /api/ingest| | Webhook |
+-----------------+ +-----------------+ +-----------------+ +-----------------+
Code-Node: Items transformieren
n8n reicht Daten als Array von Items weiter. Im Code-Node greifen Sie über $input.all() darauf zu und geben ein neues Array zurück:
// Code-Node (JavaScript) - Modus "Run Once for All Items"
const items = $input.all();
return items
.filter(item => item.json.status === "active")
.map(item => {
const { id, name, email, createdAt } = item.json;
return {
json: {
externalId: `EXT-${id}`,
displayName: name.trim(),
contactEmail: email.toLowerCase(),
// ISO-8601-Timestamp sicherstellen
registeredAt: new Date(createdAt).toISOString(),
source: "n8n-webhook",
},
};
});
Wichtige Konventionen:
- Jedes zurückgegebene Objekt muss eine
json-Property haben. - Binärdaten landen in einer optionalen
binary-Property. $input,$workflowund$executionsind globale Hilfsobjekte der n8n-Laufzeit; auf Daten anderer Nodes greifen Sie idiomatisch über$('Node-Name')zu.
Workflow-Skelett als JSON
n8n-Workflows lassen sich als JSON exportieren und versionieren. Ein minimales Skelett sieht so aus:
{
"name": "Webhook-Transform-Request",
"nodes": [
{
"id": "1",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [240, 300],
"parameters": {
"httpMethod": "POST",
"path": "ingest",
"responseMode": "responseNode"
}
},
{
"id": "2",
"name": "Transform",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [460, 300],
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "return $input.all().map(i => ({ json: { ...i.json, processed: true } }));"
}
},
{
"id": "3",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [680, 300],
"parameters": {
"method": "POST",
"url": "https://api.beispiel.de/ingest",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json) }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "Authorization", "value": "Bearer {{ $env.API_TOKEN }}" }
]
}
}
},
{
"id": "4",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [900, 300],
"parameters": {
"respondWith": "json",
"responseBody": "={{ { \"ok\": true } }}"
}
}
],
"connections": {
"Webhook": { "main": [[{ "node": "Transform", "type": "main", "index": 0 }]] },
"Transform": { "main": [[{ "node": "HTTP Request", "type": "main", "index": 0 }]] },
"HTTP Request": { "main": [[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]] }
}
}
Da der Webhook mit responseMode: "responseNode" konfiguriert ist, beendet der Node Respond to Webhook (n8n-nodes-base.respondToWebhook) die HTTP-Antwort an den Aufrufer. Secrets wie API_TOKEN hinterlegen Sie in n8n als Credentials oder als Umgebungsvariable, niemals hardcodiert im Workflow-JSON.
Lizenz und DSGVO
n8n steht unter der Sustainable Use License (fair-code). Das bedeutet: Sie dürfen die Software kostenlos nutzen, modifizieren und weitergeben – allerdings nur für Ihre eigenen internen Geschäftszwecke oder für nicht-kommerzielle bzw. persönliche Nutzung. Eingeschränkt ist insbesondere, n8n als gehosteten Dienst für Dritte anzubieten oder ein Produkt zu verkaufen, dessen Wert wesentlich auf n8n beruht; dafür ist eine separate kommerzielle Lizenz nötig. Das bloße Anbieten von Beratungs- oder Implementierungsleistungen rund um n8n ist hingegen erlaubt. Die Details finden Sie in der Sustainable Use License sowie im n8n-Repository.
Für europäische Unternehmen ist der DSGVO-Aspekt des Self-Hostings relevant: Alle verarbeiteten Nutzdaten verbleiben in Ihrer eigenen Infrastruktur. Bei SaaS-Anbietern wie Make oder Zapier werden Payload-Daten auf deren Servern – häufig außerhalb der EU – verarbeitet, was Auftragsverarbeitungsverträge und ggf. Drittland-Transfer-Prüfungen erfordert.
Praxis-Empfehlung
Beginnen Sie mit SQLite für lokale Entwicklung und Prototypen; für Produktion empfiehlt sich PostgreSQL mit einem dedizierten Volume und regelmäßigen Backups (pg_dump). Setzen Sie zudem einen festen N8N_ENCRYPTION_KEY, damit hinterlegte Credentials bei einem Neuaufbau weiter entschlüsselt werden können. Versionieren Sie Ihre Workflow-JSONs in Git, begrenzen Sie ausführliche Execution-Logs auf Debug-Phasen (Datensparsamkeit), und schützen Sie die Instanz durch einen Reverse-Proxy mit TLS. Für Workflows mit harten Zuverlässigkeitsanforderungen – etwa verteilte Transaktionen über mehrere externe Systeme hinweg – prüfen Sie, ob Temporal die bessere Grundlage wäre.
Haben Sie Fragen zur Integration in Ihre konkrete Systemlandschaft, zur Skalierung über mehrere Worker oder zur Absicherung der n8n-Instanz? Schreiben Sie an info@yurtbay.dev.