Task Runners: Code-Nodes sicherer ausführen

n8n Task Runners führen Code-Nodes isoliert aus statt im Hauptprozess. So funktionieren interner und externer Modus.

Task Runners führen den JavaScript- und Python-Code aus dem Code-Node nicht mehr im Hauptprozess von n8n aus, sondern in einem getrennten Prozess oder Container. Damit kommt fehlerhafter oder fremder Code nicht mehr an Zugangsdaten, Verschlüsselungsschlüssel oder Umgebungsvariablen der Instanz.

Ab n8n 1.111.0 lässt sich der externe Modus produktiv betreiben. Dieser Artikel zeigt den Unterschied zu internen Runnern, eine lauffähige Compose-Datei, die Allowlist für Module und die Härtungsmaßnahmen aus der n8n-Dokumentation.

Was sind Task Runners in n8n?

Task Runners sind ein Mechanismus, der Aufgaben getrennt vom Hauptprozess ausführt. n8n nutzt sie ausschließlich für den nutzergesteuerten Code aus dem Code-Node.

Drei Bestandteile arbeiten zusammen:

Bestandteil | Rolle | Wo er läuft

Bestandteil: Task Runner · Rolle: führt den Code tatsächlich aus · Wo er läuft: Kindprozess oder eigener Container

Bestandteil: Task Broker · Rolle: verteilt Aufgaben und koordiniert die Antworten · Wo er läuft: in der n8n-Hauptinstanz oder im Worker

Bestandteil: Task Requester · Rolle: fordert eine Ausführung an · Wo er läuft: der Code-Node im Workflow

Der Runner verbindet sich per WebSocket mit dem Broker. Der Broker gibt eine wartende Aufgabe heraus, der Runner liefert das Ergebnis zurück an den Requester.

Ohne Task Runner läuft der Code direkt in n8n. Wer dann einen Workflow bearbeiten darf, kann laut Dokumentation potenziell die Datenbank, den Verschlüsselungsschlüssel und alle gespeicherten Zugangsdaten auslesen.

Interner oder externer Modus: was ist der Unterschied?

Der interne Modus startet den Runner als Kindprozess mit derselben Benutzer- und Gruppen-ID wie n8n, der externe Modus startet ihn in einem eigenen Container. Nur der externe Modus gilt laut n8n als produktionstauglich.

Kriterium | Intern (`internal`) | Extern (`external`)

Kriterium: Standardeinstellung · Intern (internal): ja · Extern (external): nein

Kriterium: Prozessmodell · Intern (internal): Kindprozess von n8n · Extern (external): Sidecar-Container mit Launcher

Kriterium: Rechte des Codes · Intern (internal): gleiche uid und gid wie n8n · Extern (external): eigener Container, eigener Nutzer

Kriterium: Zugriff bei Sandbox-Ausbruch · Intern (internal): wie n8n, inklusive Zugangsdaten · Extern (external): auf den Runner-Container begrenzt

Kriterium: Zusätzliche Container · Intern (internal): keine · Extern (external): einer je Hauptinstanz und je Worker

Kriterium: Mindestversion · Intern (internal): seit Langem verfügbar · Extern (external): n8n 1.111.0

Kriterium: Empfehlung von n8n · Intern (internal): nur für isolierte Instanzen ohne sensible Daten · Extern (external): Produktion

Der interne Modus ist kein Sicherheitsgewinn, sondern ein Kompromiss. n8n nennt ihn ausdrücklich unsicher, weil der Runner auf demselben Host mit denselben Rechten läuft.

Wie richten Sie den externen Modus mit Docker Compose ein?

Sie ergänzen einen zweiten Container mit dem Image n8nio/runners und verbinden beide über ein gemeinsames Geheimnis. Die Version des Runner-Image muss exakt zur n8n-Version passen.

1services:
2 n8n:
3 image: n8nio/n8n:1.111.0
4 container_name: n8n-main
5 environment:
6 - N8N_RUNNERS_ENABLED=true
7 - N8N_RUNNERS_MODE=external
8 - N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
9 - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
10 - N8N_NATIVE_PYTHON_RUNNER=true
11 ports:
12 - "127.0.0.1:5678:5678"
13 volumes:
14 - n8n_data:/home/node/.n8n
15
16 task-runners:
17 image: n8nio/runners:1.111.0
18 container_name: n8n-runners
19 environment:
20 - N8N_RUNNERS_TASK_BROKER_URI=http://n8n-main:5679
21 - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
22 depends_on:
23 - n8n
24
25volumes:
26 n8n_data:

N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0 ist Pflicht, sobald zwei Container im Spiel sind. Ohne diesen Wert lauscht der Broker nur auf 127.0.0.1 und der Sidecar erreicht ihn nie.

Das Token gehört in die .env-Datei neben der Compose-Datei, nicht in die Compose-Datei selbst. In n8n 1.x setzen Sie zusätzlich N8N_RUNNERS_ENABLED=true. Ab n8n 2.0 ist die Variable veraltet und überflüssig.

Welche Module darf der Code-Node importieren?

Standardmäßig keine. n8n blockiert im Code-Node sowohl Node.js-Bordmittel als auch Python-Standardbibliothek und Drittanbieter-Pakete, bis Sie sie ausdrücklich freigeben.

Im externen Modus setzen Sie diese Allowlists nicht als Container-Variablen, sondern in der Launcher-Konfiguration /etc/n8n-task-runners.json. Der Launcher reicht sie als env-overrides an den jeweiligen Runner weiter.

1{
2 "task-runners": [
3 {
4 "runner-type": "javascript",
5 "env-overrides": {
6 "NODE_FUNCTION_ALLOW_BUILTIN": "crypto",
7 "NODE_FUNCTION_ALLOW_EXTERNAL": "moment,uuid"
8 }
9 },
10 {
11 "runner-type": "python",
12 "env-overrides": {
13 "PYTHONPATH": "/opt/runners/task-runner-python",
14 "N8N_RUNNERS_STDLIB_ALLOW": "json",
15 "N8N_RUNNERS_EXTERNAL_ALLOW": "numpy,pandas"
16 }
17 }
18 ]
19}

Die Datei binden Sie als Volume ein, etwa mit ./n8n-task-runners.json:/etc/n8n-task-runners.json. Drittanbieter-Pakete müssen zusätzlich im Image liegen. Dafür erweitern Sie n8nio/runners per eigenem Dockerfile.

Verzichten Sie auf den Platzhalter *. Er erlaubt sämtliche Module und hebt einen wesentlichen Teil der Absicherung wieder auf.

Welche Umgebungsvariablen steuern Task Runners?

Die folgenden Variablen decken den Regelbetrieb ab. Alle Standardwerte stammen aus der Referenz zu den Task-Runner-Umgebungsvariablen.

Variable | Standard | Wirkung

Variable: N8N_RUNNERS_MODE · Standard: internal · Wirkung: Betriebsart, internal oder external

Variable: N8N_RUNNERS_AUTH_TOKEN · Standard: Zufallswert · Wirkung: gemeinsames Geheimnis zwischen Runner und Broker

Variable: N8N_RUNNERS_BROKER_PORT · Standard: 5679 · Wirkung: Port, auf dem der Broker Verbindungen annimmt

Variable: N8N_RUNNERS_BROKER_LISTEN_ADDRESS · Standard: 127.0.0.1 · Wirkung: Lauschadresse, im Mehrcontainer-Betrieb 0.0.0.0

Variable: N8N_RUNNERS_TASK_BROKER_URI · Standard: http://127.0.0.1:5679 · Wirkung: Adresse des Brokers aus Sicht des Runners

Variable: N8N_RUNNERS_MAX_CONCURRENCY · Standard: 5 · Wirkung: gleichzeitige Aufgaben je Runner

Variable: N8N_RUNNERS_TASK_TIMEOUT · Standard: 300 · Wirkung: Laufzeitgrenze je Aufgabe in Sekunden

Variable: N8N_RUNNERS_TASK_REQUEST_TIMEOUT · Standard: 60 · Wirkung: Wartezeit auf einen freien Runner in Sekunden

Variable: N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT · Standard: 15 · Wirkung: Leerlaufsekunden bis zum Herunterfahren des Runners

Variable: N8N_BLOCK_RUNNER_ENV_ACCESS · Standard: true · Wirkung: blockiert os.environ im Python-Code

Variable: GENERIC_TIMEZONE · Standard: America/New_York · Wirkung: Zeitzone im Runner, in Deutschland auf Europe/Berlin setzen

Eine Besonderheit betrifft Geheimnisse: Das Runner-Image unterstützt keine dateibasierte Konfiguration. Variablen mit dem Suffix _FILE werden dort nicht ausgewertet.

Wie härten Sie die Runner-Container zusätzlich ab?

n8n nennt vier Maßnahmen über den externen Modus hinaus. Sie greifen unabhängig voneinander und lassen sich einzeln einführen.

Maßnahme | Umsetzung | Nutzen

Maßnahme: Distroless-Image · Umsetzung: Tag-Suffix -distroless, etwa 2.4.6-distroless · Nutzen: keine Shell, kein Paketmanager im Container

Maßnahme: Unprivilegierter Nutzer · Umsetzung: Runner als nobody mit UID und GID 65532 · Nutzen: kein Prozess mit Root-Rechten

Maßnahme: Schreibgeschütztes Dateisystem · Umsetzung: Root read-only, kleines emptyDir auf /tmp · Nutzen: Code kann keine Systemdateien ändern

Maßnahme: AppArmor-Profil · Umsetzung: Regel gegen /proc-Zugriffe (siehe unten) · Nutzen: verhindert das Auslesen von Umgebungsvariablen

Die AppArmor-Regel aus der Dokumentation lautet:

1audit deny @{PROC}/[0-9]*/{environ,mounts} rwl,

Sie verweigert Lesen, Schreiben und Verlinken auf die Dateien environ und mounts je Prozess und protokolliert jeden Versuch. Ohne diese Regel kann Code im Container Umgebungsvariablen anderer Prozesse auslesen.

Für wen lohnt sich der Umstieg?

Der Umstieg lohnt sich für jede selbst gehostete Instanz, die echte Zugangsdaten speichert oder Workflows mehrerer Teams betreibt. Auf isolierten Testinstanzen mit reinen Beispieldaten ist der interne Modus ein vertretbarer Kompromiss.

Ehrlich gesagt kostet der externe Modus Betriebsaufwand. Sie betreiben einen zusätzlichen Container je Worker, pflegen zwei Image-Versionen im Gleichschritt und verwalten eigene Allowlists.

Diesen Aufwand sollten Sie trotzdem einplanen. n8n stuft N8N_RUNNERS_ENABLED ab Version 2.0 als veraltet ein, und der interne Modus bleibt dauerhaft als unsicher gekennzeichnet.

NordFlux richtet n8n-Instanzen inklusive Task-Runner-Absicherung ein und dokumentiert die Konfiguration nachvollziehbar. Mehr dazu auf der Seite zur n8n-Beratung.

Typische Fehler und Ursachen

Fünf Fehlerbilder treten beim Einrichten externer Task Runner besonders häufig auf.

Der Sidecar verbindet sich nicht, das Log meldet einen Verbindungsfehler zum Broker.

Ursache: N8N_RUNNERS_BROKER_LISTEN_ADDRESS steht auf dem Standard 127.0.0.1, der Broker nimmt nur lokale Verbindungen an. Lösung: Den Wert im n8n-Container auf 0.0.0.0 setzen. Quelle: Set up task runners.

Der Runner meldet einen Authentifizierungsfehler.

Ursache: Die beiden Container tragen unterschiedliche Werte in N8N_RUNNERS_AUTH_TOKEN, oder das Token fehlt im Sidecar. Lösung: Beide Container aus derselben Variable in der .env-Datei speisen. Quelle: Task-Runner-Umgebungsvariablen.

Ein `require` oder `import` im Code-Node schlägt trotz gesetzter Variable fehl.

Ursache: NODE_FUNCTION_ALLOW_EXTERNAL oder N8N_RUNNERS_EXTERNAL_ALLOW wurde als Container-Variable gesetzt. Im externen Modus wertet der Launcher diese Variablen nur aus der Konfigurationsdatei aus. Lösung: Die Allowlist als env-override in /etc/n8n-task-runners.json eintragen und die Datei mounten. Quelle: Set up task runners.

Nach einem Update startet der Runner nicht mehr oder verhält sich unerwartet.

Ursache: Die Versionen von n8nio/n8n und n8nio/runners stimmen nicht überein. Lösung: Beide Tags auf dieselbe Version setzen und gemeinsam aktualisieren. Quelle: Set up task runners.

Im Queue-Modus laufen Code-Nodes auf einem Worker in einen Timeout.

Ursache: Nur die Hauptinstanz hat einen Sidecar, die Worker haben keinen. Jeder Worker benötigt einen eigenen Runner-Container. Lösung: Je Worker einen Sidecar ergänzen. Quelle: Queue-Modus aktivieren.

Häufige Fragen zu Task Runners in n8n

Was ist der Unterschied zwischen internem und externem Task-Runner-Modus?

Im internen Modus läuft der Runner als Kindprozess von n8n mit denselben Rechten. Im externen Modus läuft er in einem eigenen Container und ist vom Hauptprozess isoliert. Nur der externe Modus gilt als produktionstauglich.

Ab welcher n8n-Version funktionieren externe Task Runners?

Ab n8n 1.111.0. Zusätzlich muss die Version des Image n8nio/runners exakt zur eingesetzten n8n-Version passen.

Muss ich für jeden Worker einen eigenen Task-Runner-Container betreiben?

Ja. Im Queue-Modus braucht jeder Worker einen eigenen Sidecar. Hauptinstanzen brauchen ebenfalls einen, sofern OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS nicht aktiv ist und sie manuelle Ausführungen selbst verarbeiten.

Blockieren Task Runners automatisch den Zugriff auf Umgebungsvariablen?

Für Python ist der Zugriff über os.environ per N8N_BLOCK_RUNNER_ENV_ACCESS standardmäßig blockiert. Für Isolation auf Betriebssystemebene empfiehlt n8n zusätzlich ein AppArmor-Profil gegen /proc-Zugriffe.

Quellen: Set up task runners, Harden task runners und Task-Runner-Umgebungsvariablen.

Simon Glowik, Gründer von NordFlux
Über den Autor

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

  • Microsoft zertifiziert — PL-900 und AZ-900
  • UiPath zertifiziert — Automation Developer Associate
Alle Beiträge
Weiterlesen

Verwandte Anleitungen

Kostenlose Erstanalyse

Code-Nodes isoliert, aber wer härtet den Rest der Instanz?

Task Runners sind ein Baustein, ein sicher betriebenes n8n braucht daneben Hardening, Rechtekonzept und saubere Updates. NordFlux betreibt n8n-Instanzen mit externem Task-Runner-Modus, Monitoring und dokumentierter Konfiguration. So laufen auch Code-lastige Workflows produktiv, ohne dass eine einzelne Node die ganze Instanz gefährdet.

n8n Kosten und Lizenzenn8n Hosting in Deutschland

  • Externer Task-Runner-Modus sauber konfiguriert statt Standardwerte
  • Hardening der gesamten Instanz, nicht nur der Code-Nodes
  • Updates und Konfigurationsänderungen ohne Produktionsausfall