, 7 Min. Lesezeit, von

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.

Aktualisiert am 7. Oktober 2026: Das Beispiel-Workflow-JSON authentifiziert den HTTP-Request jetzt über ein Header-Auth-Credential. Den bisher gezeigten Zugriff per $env sperrt n8n seit Version 2.0 standardmäßig.

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 und eignet sich damit 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_PASSWORD wurde 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, $workflow und $execution sind 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",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json) }}"
      },
      "credentials": {
        "httpHeaderAuth": { "id": null, "name": "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 den API-Token hinterlegen Sie in n8n als Credentials, niemals hardcodiert im Workflow-JSON. Der HTTP-Request-Node im Skelett authentifiziert sich deshalb über ein Credential vom Typ Header Auth (authentication: "genericCredentialType", genericAuthType: "httpHeaderAuth"). Legen Sie es vor dem Import unter dem Namen API Token an, mit Name Authorization und Value Bearer <IHR_TOKEN>. Nach dem Import wählen Sie dieses Credential im HTTP-Request-Node aus, falls n8n es nicht selbst zugeordnet hat. Umgebungsvariablen per $env sind dafür keine Alternative: Seit Version 2.0 sperrt n8n diesen Zugriff in Ausdrücken und im Code-Node standardmäßig (N8N_BLOCK_ENV_ACCESS_IN_NODE steht jetzt auf true).

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.

Hinweis: Die Beiträge dieses Blogs werden unter Einsatz von KI erstellt und vor der Veröffentlichung redaktionell geprüft. Die redaktionelle Verantwortung trägt Emre Yurtbay (siehe Impressum).

Lassen Sie uns sprechen

Im kostenlosen Erstgespräch schildern Sie mir Ihre Situation. Ich gebe Ihnen eine erste Einschätzung, wie ich Sie unterstützen kann.

Kostenloses Erstgespräch anfragen