The Task Runner system provides isolated, sandboxed execution environments for user-provided JavaScript and Python code in n8n workflows. This architecture separates code execution from the main n8n process, enhancing security and stability by preventing untrusted code from directly accessing n8n internals or the host system.
The system consists of three main components:
Task runners are deployed as separate containers (sidecar pattern) or processes that communicate with the main n8n application over HTTP.
Key Benefits:
Sources: docker/images/runners/Dockerfile docker/images/runners/Dockerfile.distroless
Communication Flow:
Sources: docker/images/runners/n8n-task-runners.json docker/images/runners/Dockerfile142-148
The Task Runner Launcher is an external Go binary that manages the lifecycle of task runner processes and acts as an HTTP gateway between n8n and the individual runners.
| Responsibility | Description |
|---|---|
| Process Management | Starts, monitors, and stops JavaScript and Python runner processes |
| Request Routing | Routes incoming task requests to the appropriate runner based on task type |
| Health Monitoring | Monitors runner health via HTTP health check endpoints |
| Configuration | Loads runner configuration from /etc/n8n-task-runners.json |
| Auto-shutdown | Terminates idle runners after configured timeout |
The launcher binary is downloaded during Docker image build from the n8n-io/task-runner-launcher GitHub repository:
The launcher is installed to /usr/local/bin/ and serves as the container entrypoint.
Sources: docker/images/runners/Dockerfile82-101 docker/images/runners/Dockerfile.distroless98-120
The launcher reads configuration from /etc/n8n-task-runners.json:
Configuration Fields:
runner-type: Identifies the runner (must match task type in requests)workdir: Working directory for the runner processcommand: Path to the runtime executable (node or python)args: Command-line arguments passed to the runnerhealth-check-server-port: Port for HTTP health checksallowed-env: Whitelist of environment variables passed to runnerenv-overrides: Environment variables set/overridden by launcherSources: docker/images/runners/n8n-task-runners.json1-55
The JavaScript task runner executes JavaScript code from Code nodes using a sandboxed Node.js environment.
Security Flags:
--disallow-code-generation-from-strings: Prevents eval(), Function(), etc.--disable-proto=delete: Removes __proto__ to prevent prototype pollutionSources: docker/images/runners/n8n-task-runners.json7-10
The JavaScript runner is built from the @n8n/task-runner package and installed to /opt/runners/task-runner-javascript/:
The build process removes monorepo-specific dependency references (catalog:, workspace:) to allow users to extend the image with pnpm add.
Sources: docker/images/runners/Dockerfile7-32
Default allowed libraries are configured via environment variables:
| Environment Variable | Default Value | Purpose |
|---|---|---|
NODE_FUNCTION_ALLOW_BUILTIN | crypto | Whitelisted Node.js built-in modules |
NODE_FUNCTION_ALLOW_EXTERNAL | moment | Whitelisted external npm packages |
These can be overridden by setting environment variables when starting the container. The moment library is pre-installed for backwards compatibility with existing workflows.
Sources: docker/images/runners/n8n-task-runners.json27-28
The Python task runner executes Python code from Code nodes using a sandboxed Python environment.
Python Flags:
-I: Isolated mode (ignores user environment, site-packages)-B: Don't write .pyc files (security)-X disable_remote_debug: Disables remote debugging capabilitiesSources: docker/images/runners/n8n-task-runners.json36
The Python runner uses uv (fast Python package installer) to create a reproducible virtual environment:
This creates a relocatable virtual environment at /opt/runners/task-runner-python/.venv/ that includes all dependencies.
Sources: docker/images/runners/Dockerfile37-79
Library access is controlled via environment variables:
| Environment Variable | Default Value | Purpose |
|---|---|---|
N8N_RUNNERS_STDLIB_ALLOW | "" (empty) | Whitelisted Python standard library modules |
N8N_RUNNERS_EXTERNAL_ALLOW | "" (empty) | Whitelisted external packages |
By default, both are empty strings, meaning strict sandboxing. Users can extend the image with additional packages:
Then restart with updated environment variables to allow their use.
Sources: docker/images/runners/n8n-task-runners.json50-51
n8n provides two Docker images for task runners:
Image: n8nio/runners:latest
Base: python:3.13-alpine + node:24.13.1-alpine
Characteristics:
pnpm, uv)Sources: docker/images/runners/Dockerfile110-155
Image: n8nio/runners:latest-distroless
Base: gcr.io/distroless/cc-debian12
Characteristics:
Sources: docker/images/runners/Dockerfile.distroless128-199
Both images are built for AMD64 and ARM64 architectures using multi-stage builds in GitHub Actions:
The workflow builds platform-specific images (-amd64, -arm64 suffixes) then combines them into multi-arch manifest tags.
Sources: .github/workflows/docker-build-push.yml136-167 .github/workflows/docker-build-push.yml197-230
Task runners are typically deployed as sidecar containers alongside the main n8n container:
Key Environment Variables:
| Variable (n8n) | Purpose |
|---|---|
N8N_RUNNERS_ENABLED | Enable task runner integration |
N8N_RUNNERS_MODE | external for sidecar, internal for in-process |
N8N_RUNNERS_TASK_BROKER_URI | HTTP endpoint for task runner launcher |
| Variable (runners) | Purpose |
|---|---|
N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT | Seconds of inactivity before runner shutdown |
N8N_RUNNERS_TASK_TIMEOUT | Maximum execution time per task (seconds) |
N8N_RUNNERS_MAX_CONCURRENCY | Maximum concurrent task executions |
Each runner exposes an HTTP health check endpoint:
http://localhost:5681/healthzhttp://localhost:5682/healthzThe launcher monitors these endpoints and restarts failed runners automatically.
Sources: docker/images/runners/n8n-task-runners.json12 docker/images/runners/n8n-task-runners.json37
Sources: docker/images/runners/Dockerfile134-135 docker/images/runners/Dockerfile.distroless187
JavaScript:
eval, Function)--disable-proto=delete)Python:
-I) prevents importing from user site-packagesSources: docker/images/runners/n8n-task-runners.json8-10 docker/images/runners/n8n-task-runners.json36
The launcher enforces strict environment variable filtering:
Only explicitly allowed environment variables are passed from the host to runner processes. This prevents sensitive information leakage (credentials, tokens, etc.).
Sources: docker/images/runners/n8n-task-runners.json13-25 docker/images/runners/n8n-task-runners.json38-48
The task runner images are built and published alongside the main n8n image:
Build Steps:
@n8n/task-runner and @n8n/task-runner-python packagesSources: .github/workflows/docker-build-push.yml70-167 .github/workflows/docker-build-push.yml279-331
Both runner images undergo security scanning with Trivy:
Vulnerability reports are generated for each release and tracked via VEX attestations.
Sources: .github/workflows/docker-build-push.yml398-410
To extend the JavaScript runner with additional npm packages:
The Alpine-based image includes pnpm by default, allowing package installation.
To extend the Python runner with additional Python packages:
The Alpine-based image includes uv by default for fast package installation.
The distroless image cannot be extended at runtime because it lacks shell and package managers. To add packages, rebuild from source:
Sources: docker/images/runners/Dockerfile129-133 docker/images/runners/Dockerfile119
The Task Runner system provides a secure, isolated architecture for executing user code in n8n:
| Component | Purpose | Key Technologies |
|---|---|---|
| Task Runner Launcher | Process manager and HTTP gateway | Go binary, external repository |
| JavaScript Runner | Execute JavaScript code | Node.js, vm2/isolated-vm |
| Python Runner | Execute Python code | Python, RestrictedPython, uv |
| Alpine Image | Development/self-hosted | Alpine Linux, includes shell/package managers |
| Distroless Image | Production/cloud | Google Distroless, hardened, no shell |
Key Features:
The system balances security, performance, and flexibility, allowing users to execute custom code safely while maintaining the stability of the main n8n application.
Sources: docker/images/runners/Dockerfile docker/images/runners/Dockerfile.distroless docker/images/runners/n8n-task-runners.json
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.