Skip to content

feat: Add support for custom runner images (n8n v2 support)#289

Open
joshuabaird wants to merge 1 commit into8gears:mainfrom
joshuabaird:chore/v2/separate-worker-image
Open

feat: Add support for custom runner images (n8n v2 support)#289
joshuabaird wants to merge 1 commit into8gears:mainfrom
joshuabaird:chore/v2/separate-worker-image

Conversation

@joshuabaird
Copy link
Copy Markdown
Contributor

@joshuabaird joshuabaird commented Jan 20, 2026

What this PR does / why we need it

This PR adds support for configuring a separate Docker image for n8n workers/task runners, enabling compatibility with n8n v2.0+ while maintaining full backwards compatibility with v1.x deployments.

Background

Starting with n8n v2.0, the task runner functionality has been removed from the main n8nio/n8n Docker image and moved to a separate n8nio/runners image. This is a breaking change that requires users to configure workers to use the new image.
See: https://docs.n8n.io/2-0-breaking-changes/#remove-task-runner-from-n8nion8n-docker-image

Which issue this PR fixes

Fixes #281.

Checklist

Please place an 'x' in all applicable fields and remove unrelated items.

Version and Documentation

Testing and Validation

  • Ran ah lint locally without errors
  • Ran Chart-Testing: ct lint --chart-dirs charts/n8n --charts charts/n8n --validate-maintainers=false
  • Tested chart installation locally
  • Tested with example configurations in /examples directory

Summary by CodeRabbit

  • New Features

    • Configure a separate worker/task-runner image with repository, tag and pull policy, defaulting to main image when unset; chart omits command/args for the dedicated runners image to preserve its entrypoint.
  • Chores

    • Helm chart version bumped to 2.1.0.
  • Documentation

    • Added migration guide, README notes and examples for v2.0+ runners image usage, defaults, and compatibility.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0d5e59 and e035d6c.

📒 Files selected for processing (5)
  • README.md
  • charts/n8n/Chart.yaml
  • charts/n8n/templates/deployment.worker.yaml
  • charts/n8n/values.yaml
  • examples/values_full.yaml
🚧 Files skipped from review as they are similar to previous changes (5)
  • README.md
  • examples/values_full.yaml
  • charts/n8n/values.yaml
  • charts/n8n/templates/deployment.worker.yaml
  • charts/n8n/Chart.yaml

Walkthrough

Adds explicit per-worker image configuration and docs to support n8n v2.0+ separate task-runner image, updates worker command/args resolution to avoid overriding runners image entrypoint, and bumps the Helm chart to 2.1.0.

Changes

Cohort / File(s) Summary
Documentation & Examples
README.md, examples/values_full.yaml
Add guidance and migration notes for n8n v2.0+ using a separate task-runner image; document that worker.command/worker.commandArgs must not be set for runners image.
Chart Metadata
charts/n8n/Chart.yaml
Bump chart version to 2.1.0 and add Artifact Hub change noting support for custom worker/task-runner image.
Values
charts/n8n/values.yaml
Introduce worker.image block (repository, tag, pullPolicy) with fallbacks to global image settings and explicit notes about v2 runners behavior.
Worker Deployment Template
charts/n8n/templates/deployment.worker.yaml
Resolve worker image and pullPolicy from worker.image.* with fallbacks; conditionally omit command/args when a custom worker image is used and only set defaults for the main image.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • Vad1mo
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main change: adding support for custom runner images to enable n8n v2 compatibility.
Linked Issues check ✅ Passed The PR successfully addresses the primary objective of issue #281 by implementing configuration support for separate runner images and maintaining backwards compatibility with v1.x.
Out of Scope Changes check ✅ Passed All changes are scoped to enabling custom runner image configuration (values, templates, documentation) without attempting to address operational concerns like task broker networking or database requirements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@joshuabaird joshuabaird force-pushed the chore/v2/separate-worker-image branch from f992c86 to 78e33b5 Compare January 20, 2026 15:06
@joshuabaird joshuabaird mentioned this pull request Jan 20, 2026
1 task
@joshuabaird joshuabaird marked this pull request as ready for review January 20, 2026 15:08
@elabbarw
Copy link
Copy Markdown

Howdy, would this support sidecars acting as task runners for workers?

@joshuabaird
Copy link
Copy Markdown
Contributor Author

Howdy, would this support sidecars acting as task runners for workers?

As is, no. That would need to be a separate effort.

@elabbarw
Copy link
Copy Markdown

Thanks :) this new task runner setup has become a **** show on k8s

@NigelVanHattum
Copy link
Copy Markdown

@Vad1mo Could you review this? This is needed before a 2.x upgrade.

@RoseSecurity
Copy link
Copy Markdown
Contributor

I am actively testing this today and Monday on our dev clusters and I can report back

@NotANormalNerd
Copy link
Copy Markdown

NotANormalNerd commented Feb 15, 2026

This isn't working as it is:

  1. The main n8n instance is exposing a task broker on port 5679 which the worker/runner needs access too, right now there are no services setup for that, so it is impossible to get to that port from the runner, a additional service is needed.
  2. I didn't understand if valkey is needed or not in this distrubuted setup and if SQLite works or doesn't, especially when having more workers.
  3. The env: N8N_RUNNERS_TASK_BROKER_URI has to be set, since defaults don't work. Same for N8N_RUNNERS_BROKER_LISTEN_ADDRESS.
  4. probably some more stuff, but that is a lot for a nearly 1am session of trying to upgrade to n8n v2

command:
{{- toYaml .Values.worker.command | nindent 12 }}
{{- else }}
command: ["n8n"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command won't work with the runner image. So either set it in the values or change it here.

args:
{{- toYaml .Values.worker.commandArgs | nindent 12 }}
{{- else }}
args:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for args.

@joshuabaird
Copy link
Copy Markdown
Contributor Author

This isn't working as it is:

  1. The main n8n instance is exposing a task broker on port 5679 which the worker/runner needs access too, right now there are no services setup for that, so it is impossible to get to that port from the runner, a additional service is needed.
  2. I didn't understand if valkey is needed or not in this distrubuted setup and if SQLite works or doesn't, especially when having more workers.
  3. The env: N8N_RUNNERS_TASK_BROKER_URI has to be set, since defaults don't work. Same for N8N_RUNNERS_BROKER_LISTEN_ADDRESS.
  4. probably some more stuff, but that is a lot for a nearly 1am session of trying to upgrade to n8n v2

This PR wasn't meant to solve all things needed for v2 compatibility -- it was only meant to provide the ability to configure custom runner images.

I'll take a closer look at the command-related comments, thanks.

@joshuabaird
Copy link
Copy Markdown
Contributor Author

@RoseSecurity Just pushed a possible fix for the CMD/ARGS on v2 runners. Can you test and let me know the results, please?

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@README.md`:
- Around line 817-851: The migration docs for "n8n v2.0+ Support and Task Runner
Image" are incomplete: update the README section (the "n8n v2.0+ Support and
Task Runner Image" header and the worker image guidance mentioning worker.image
and worker.command/commandArgs) to include a clear "Known limitations" or
"Additional configuration may be required" note that instructs users to (1)
create a Service exposing port 5679 so the runners can reach the task broker,
and (2) configure the environment variables N8N_RUNNERS_TASK_BROKER_URI and
N8N_RUNNERS_BROKER_LISTEN_ADDRESS for Kubernetes deployments (explain that
defaults won’t work), plus a short pointer that these settings are required in
addition to swapping worker.image to n8nio/runners.

Comment on lines +817 to +851
## n8n v2.0+ Support and Task Runner Image

Starting with n8n v2.0, the task runner (worker) functionality has been moved to a separate Docker image (`n8nio/runners`). This chart now supports configuring a custom image for workers while maintaining full backwards compatibility with n8n v1.x.

### For n8n v1.x Users (Current Default)

No changes needed! Workers will continue using the main n8n image (`n8nio/n8n`).

### For n8n v2.0+ Users

When upgrading to n8n v2.0 or later, you **must** configure the worker to use the separate task runner image:

```yaml
image:
repository: n8nio/n8n
tag: "2.0.0"

worker:
enabled: true
image:
repository: n8nio/runners
tag: "2.0.0"
# IMPORTANT: Do NOT set command or commandArgs when using n8nio/runners
# The runners image has its own launcher and doesn't use "n8n worker" commands
```

**Key points:**
- The main n8n application continues to use `n8nio/n8n`
- Workers/task runners must use `n8nio/runners` for n8n v2.0+
- **Do not set `worker.command` or `worker.commandArgs`** when using the runners image - it has its own entrypoint/launcher
- The chart automatically omits command/args when a custom worker image is specified
- If `worker.image.*` is not specified, it defaults to the global `image.*` configuration (backwards compatible)
- You can specify different tags for main and worker if needed

For more details, see the [n8n v2.0 breaking changes documentation](https://docs.n8n.io/2-0-breaking-changes/#remove-task-runner-from-n8nion8n-docker-image).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Migration guide may be incomplete for a successful v2.0+ deployment.

Based on PR discussion, users upgrading to v2.0+ also need:

  1. A Service exposing port 5679 for the task broker (runners need to reach it).
  2. Environment variables N8N_RUNNERS_TASK_BROKER_URI and N8N_RUNNERS_BROKER_LISTEN_ADDRESS configured, since defaults don't work in Kubernetes.

While the PR author has noted that these concerns are outside the current PR scope, the migration guide as written may mislead users into thinking the image swap alone is sufficient. Consider adding a "Known limitations" or "Additional configuration may be required" note to set expectations and prevent failed deployments.

🤖 Prompt for AI Agents
In `@README.md` around lines 817 - 851, The migration docs for "n8n v2.0+ Support
and Task Runner Image" are incomplete: update the README section (the "n8n v2.0+
Support and Task Runner Image" header and the worker image guidance mentioning
worker.image and worker.command/commandArgs) to include a clear "Known
limitations" or "Additional configuration may be required" note that instructs
users to (1) create a Service exposing port 5679 so the runners can reach the
task broker, and (2) configure the environment variables
N8N_RUNNERS_TASK_BROKER_URI and N8N_RUNNERS_BROKER_LISTEN_ADDRESS for Kubernetes
deployments (explain that defaults won’t work), plus a short pointer that these
settings are required in addition to swapping worker.image to n8nio/runners.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="charts/n8n/templates/deployment.worker.yaml">

<violation number="1" location="charts/n8n/templates/deployment.worker.yaml:88">
P2: Using the presence of `worker.image.repository` as a proxy for "this is a runner image that doesn't need command/args" is fragile. If a user explicitly sets `worker.image.repository` to the same value as the global image (e.g., `n8nio/n8n` for clarity or pinning), the worker will silently start without `command: ["n8n"]` and `args: ["worker"]`, breaking the deployment.

Consider comparing `worker.image.repository` against `image.repository` instead, or introducing an explicit boolean flag (e.g., `worker.useRunnerImage: false`) to control this behavior.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

{{- /* User has specified a custom command, use it */ -}}
command:
{{- toYaml .Values.worker.command | nindent 12 }}
{{- else if .Values.worker.image.repository }}
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Using the presence of worker.image.repository as a proxy for "this is a runner image that doesn't need command/args" is fragile. If a user explicitly sets worker.image.repository to the same value as the global image (e.g., n8nio/n8n for clarity or pinning), the worker will silently start without command: ["n8n"] and args: ["worker"], breaking the deployment.

Consider comparing worker.image.repository against image.repository instead, or introducing an explicit boolean flag (e.g., worker.useRunnerImage: false) to control this behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At charts/n8n/templates/deployment.worker.yaml, line 88:

<comment>Using the presence of `worker.image.repository` as a proxy for "this is a runner image that doesn't need command/args" is fragile. If a user explicitly sets `worker.image.repository` to the same value as the global image (e.g., `n8nio/n8n` for clarity or pinning), the worker will silently start without `command: ["n8n"]` and `args: ["worker"]`, breaking the deployment.

Consider comparing `worker.image.repository` against `image.repository` instead, or introducing an explicit boolean flag (e.g., `worker.useRunnerImage: false`) to control this behavior.</comment>

<file context>
@@ -82,15 +82,21 @@ spec:
+          {{- /* User has specified a custom command, use it */ -}}
           command:
             {{- toYaml .Values.worker.command | nindent 12 }}
+          {{- else if .Values.worker.image.repository }}
+          {{- /* Worker is using a custom image (likely n8nio/runners for v2) - don't set command, let image entrypoint run */ -}}
           {{- else }}
</file context>
Fix with Cubic

Add worker.image configuration to allow specifying a separate Docker image
for workers/task runners, enabling compatibility with n8n v2.0+ which moved
task runner functionality to the separate n8nio/runners image.

Changes:
- Add worker.image.{repository,tag,pullPolicy} configuration in values.yaml
- Update deployment.worker.yaml to use worker-specific image with fallback
- Bump chart version to 2.1.0 (backwards-compatible feature)
- Add migration documentation and examples for n8n v2.0+

Maintains full backwards compatibility - existing deployments continue using
the main n8n image for workers when worker.image is not specified.

Ref: https://docs.n8n.io/2-0-breaking-changes/#remove-task-runner-from-n8nion8n-docker-image

Do not supply CMD or ARGS for v2 runners.

Signed-off-by: Josh Baird <jbaird@galileo.io>
@joshuabaird joshuabaird force-pushed the chore/v2/separate-worker-image branch from e0d5e59 to e035d6c Compare February 25, 2026 15:24
@mubarak-j
Copy link
Copy Markdown

For supporting sidecars acting as task runners for workers, take a look at this workaround #252 (review)

@Vad1mo
Copy link
Copy Markdown
Member

Vad1mo commented Mar 14, 2026

I will work on this since we are now using workers and n8n 2.11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feature: Support for n8n 2

7 participants