fix(onboard): skip OLLAMA_HOST=0.0.0.0 on WSL2 to fix Docker routing#1104
fix(onboard): skip OLLAMA_HOST=0.0.0.0 on WSL2 to fix Docker routing#1104ericksoa merged 1 commit intoNVIDIA:mainfrom
Conversation
📝 WalkthroughWalkthroughDetect WSL in Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
d1330dc to
a7bf527
Compare
Ollama's Go runtime creates a dual-stack (AF_INET6) socket when given OLLAMA_HOST=0.0.0.0, but WSL2's port relay only forwards IPv4 sockets to the Windows host. Docker's host-gateway cannot reach the dual-stack socket, causing inference requests to fail with connection refused. On WSL2, let Ollama bind to the default 127.0.0.1 instead, which creates an IPv4-only socket that the WSL2 relay forwards correctly.
a7bf527 to
7c44475
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
bin/lib/onboard.js (1)
1911-2324:setupNimis still too complex; consider extracting provider handlers.This change adds more branching in an already very large function. Splitting remote/local provider flows into helpers would improve readability and testability while keeping policy limits in check.
As per coding guidelines, "Maintain cyclomatic complexity limit of 20 (target: ratchet down to 15) for all functions."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@bin/lib/onboard.js` around lines 1911 - 2324, The setupNim function is too large and has high cyclomatic complexity; refactor by extracting each provider branch into small helper handlers and have setupNim orchestrate them. Create functions like handleRemoteProviderSelection(selected, requestedModel) to encapsulate the REMOTE_PROVIDER_CONFIG path (including custom/anthropicCompatible handling, model prompting/validation, ensureApiKey/ensureNamedCredential and return {model, provider, endpointUrl, credentialEnv, preferredInferenceApi}), handleNimLocalSelection(gpu, requestedModel) to encapsulate nim.listModels/pullNimImage/startNimContainer/health check and return the same object plus nimContainer or signal fallback, handleOllamaSelection(selectedKey, gpu, requestedModel) to start/ensure Ollama, prompt/validate models and return the same object, and handleVllmSelection(requestedModel) to query vLLM and validate model; then simplify setupNim to call these handlers based on selected.key, handle errors/continue selectionLoop when handlers indicate retry, and keep return shape { model, provider, endpointUrl, credentialEnv, preferredInferenceApi, nimContainer } unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bin/lib/onboard.js`:
- Around line 2196-2200: The validateLocalProvider("ollama-local") guidance
needs to reflect the WSL exception used in onboard.js (isWsl() causes ollama to
bind to 127.0.0.1 instead of 0.0.0.0); update the user-facing message in
bin/lib/local-inference.js so it conditionally recommends 127.0.0.1:11434 when
isWsl() is true and 0.0.0.0:11434 otherwise (or add a short note that WSL should
use 127.0.0.1), keeping the check consistent with the isWsl() logic used around
run(`${ollamaEnv}ollama serve ...`) and ensuring
validateLocalProvider("ollama-local") outputs the correct host suggestion.
- Around line 2199-2200: The WSL branch currently sets ollamaEnv = "" which
leaves any parent OLLAMA_HOST exported and can leak into the child; change the
assignment so the WSL branch explicitly clears the variable for the child
process (e.g., set ollamaEnv to "OLLAMA_HOST= " or use "unset OLLAMA_HOST &&"
before the command) so the run call (run(`${ollamaEnv}ollama serve ...`, {
ignoreError: true })) executes with OLLAMA_HOST cleared; update the code that
defines ollamaEnv (the isWsl() ternary) accordingly.
---
Nitpick comments:
In `@bin/lib/onboard.js`:
- Around line 1911-2324: The setupNim function is too large and has high
cyclomatic complexity; refactor by extracting each provider branch into small
helper handlers and have setupNim orchestrate them. Create functions like
handleRemoteProviderSelection(selected, requestedModel) to encapsulate the
REMOTE_PROVIDER_CONFIG path (including custom/anthropicCompatible handling,
model prompting/validation, ensureApiKey/ensureNamedCredential and return
{model, provider, endpointUrl, credentialEnv, preferredInferenceApi}),
handleNimLocalSelection(gpu, requestedModel) to encapsulate
nim.listModels/pullNimImage/startNimContainer/health check and return the same
object plus nimContainer or signal fallback, handleOllamaSelection(selectedKey,
gpu, requestedModel) to start/ensure Ollama, prompt/validate models and return
the same object, and handleVllmSelection(requestedModel) to query vLLM and
validate model; then simplify setupNim to call these handlers based on
selected.key, handle errors/continue selectionLoop when handlers indicate retry,
and keep return shape { model, provider, endpointUrl, credentialEnv,
preferredInferenceApi, nimContainer } unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: bebd8d60-0401-4688-8063-18dc8febe542
📒 Files selected for processing (1)
bin/lib/onboard.js
| // On WSL2, binding to 0.0.0.0 creates a dual-stack socket that Docker | ||
| // cannot reach via host-gateway. The default 127.0.0.1 binding works | ||
| // because WSL2 relays IPv4-only sockets to the Windows host. | ||
| const ollamaEnv = isWsl() ? "" : "OLLAMA_HOST=0.0.0.0:11434 "; | ||
| run(`${ollamaEnv}ollama serve > /dev/null 2>&1 &`, { ignoreError: true }); |
There was a problem hiding this comment.
Update local-validation guidance to include the WSL exception.
With Line 2199 intentionally avoiding 0.0.0.0 on WSL, the current validateLocalProvider("ollama-local") message in bin/lib/local-inference.js still tells users to bind 0.0.0.0:11434, which is now the known-bad path on WSL.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@bin/lib/onboard.js` around lines 2196 - 2200, The
validateLocalProvider("ollama-local") guidance needs to reflect the WSL
exception used in onboard.js (isWsl() causes ollama to bind to 127.0.0.1 instead
of 0.0.0.0); update the user-facing message in bin/lib/local-inference.js so it
conditionally recommends 127.0.0.1:11434 when isWsl() is true and 0.0.0.0:11434
otherwise (or add a short note that WSL should use 127.0.0.1), keeping the check
consistent with the isWsl() logic used around run(`${ollamaEnv}ollama serve
...`) and ensuring validateLocalProvider("ollama-local") outputs the correct
host suggestion.
| const ollamaEnv = isWsl() ? "" : "OLLAMA_HOST=0.0.0.0:11434 "; | ||
| run(`${ollamaEnv}ollama serve > /dev/null 2>&1 &`, { ignoreError: true }); |
There was a problem hiding this comment.
Clear inherited OLLAMA_HOST in the WSL path.
At Line 2199, omitting inline assignment does not remove an already-exported OLLAMA_HOST from the parent environment. That can silently bypass this fix on WSL.
💡 Proposed fix
- const ollamaEnv = isWsl() ? "" : "OLLAMA_HOST=0.0.0.0:11434 ";
- run(`${ollamaEnv}ollama serve > /dev/null 2>&1 &`, { ignoreError: true });
+ const ollamaEnvPrefix = isWsl() ? "env -u OLLAMA_HOST " : "OLLAMA_HOST=0.0.0.0:11434 ";
+ run(`${ollamaEnvPrefix}ollama serve > /dev/null 2>&1 &`, { ignoreError: true });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const ollamaEnv = isWsl() ? "" : "OLLAMA_HOST=0.0.0.0:11434 "; | |
| run(`${ollamaEnv}ollama serve > /dev/null 2>&1 &`, { ignoreError: true }); | |
| const ollamaEnvPrefix = isWsl() ? "env -u OLLAMA_HOST " : "OLLAMA_HOST=0.0.0.0:11434 "; | |
| run(`${ollamaEnvPrefix}ollama serve > /dev/null 2>&1 &`, { ignoreError: true }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@bin/lib/onboard.js` around lines 2199 - 2200, The WSL branch currently sets
ollamaEnv = "" which leaves any parent OLLAMA_HOST exported and can leak into
the child; change the assignment so the WSL branch explicitly clears the
variable for the child process (e.g., set ollamaEnv to "OLLAMA_HOST= " or use
"unset OLLAMA_HOST &&" before the command) so the run call
(run(`${ollamaEnv}ollama serve ...`, { ignoreError: true })) executes with
OLLAMA_HOST cleared; update the code that defines ollamaEnv (the isWsl()
ternary) accordingly.
There was a problem hiding this comment.
The fix intentionally avoids overriding OLLAMA_HOST on WSL2 to let Ollama use its default binding. If a user has explicitly exported OLLAMA_HOST=0.0.0.0 in their environment, that's an intentional configuration choice - overriding it silently would be surprising. This is an unlikely edge case since neither the Ollama installer nor NemoClaw sets this variable in shell profiles.
There was a problem hiding this comment.
@jieunl24, that's a fair point — respecting an explicitly exported OLLAMA_HOST is consistent with the principle of least surprise for users who intentionally configure their own binding. The edge case is unlikely enough that silently clearing it would probably cause more confusion than it prevents. I'll defer to your judgment here.
✏️ Learnings added
Learnt from: jieunl24
Repo: NVIDIA/NemoClaw PR: 1104
File: bin/lib/onboard.js:2199-2200
Timestamp: 2026-03-30T17:32:13.519Z
Learning: In `bin/lib/onboard.js` (NemoClaw project), the WSL2 Ollama startup path intentionally does NOT clear an inherited `OLLAMA_HOST` environment variable (e.g., via `env -u OLLAMA_HOST`). The design decision is to respect any explicitly exported `OLLAMA_HOST` as an intentional user configuration choice. The fix only avoids *setting* `OLLAMA_HOST=0.0.0.0:11434` inline on WSL2; it does not override pre-existing env values. This is considered acceptable because neither the Ollama installer nor NemoClaw sets `OLLAMA_HOST` in shell profiles.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
…1104) Ollama's Go runtime creates a dual-stack (AF_INET6) socket when given OLLAMA_HOST=0.0.0.0, but WSL2's port relay only forwards IPv4 sockets to the Windows host. Docker's host-gateway cannot reach the dual-stack socket, causing inference requests to fail with connection refused. On WSL2, let Ollama bind to the default 127.0.0.1 instead, which creates an IPv4-only socket that the WSL2 relay forwards correctly.
…VIDIA#1104) Ollama's Go runtime creates a dual-stack (AF_INET6) socket when given OLLAMA_HOST=0.0.0.0, but WSL2's port relay only forwards IPv4 sockets to the Windows host. Docker's host-gateway cannot reach the dual-stack socket, causing inference requests to fail with connection refused. On WSL2, let Ollama bind to the default 127.0.0.1 instead, which creates an IPv4-only socket that the WSL2 relay forwards correctly.
…VIDIA#1104) Ollama's Go runtime creates a dual-stack (AF_INET6) socket when given OLLAMA_HOST=0.0.0.0, but WSL2's port relay only forwards IPv4 sockets to the Windows host. Docker's host-gateway cannot reach the dual-stack socket, causing inference requests to fail with connection refused. On WSL2, let Ollama bind to the default 127.0.0.1 instead, which creates an IPv4-only socket that the WSL2 relay forwards correctly.
Ollama has no built-in auth and binding to 0.0.0.0 exposes it to the network (CWE-668, #1140). This adds an authenticated reverse proxy so Ollama stays on localhost while containers can still reach it. - Add scripts/ollama-auth-proxy.js — Node.js proxy on 0.0.0.0:11435 that validates a per-instance Bearer token before forwarding to Ollama on 127.0.0.1:11434. Health check (GET /api/tags) is exempt. Uses crypto.timingSafeEqual for timing-safe token comparison. - Bind Ollama to 127.0.0.1 instead of 0.0.0.0 during onboard - Start the auth proxy after Ollama, with stale proxy cleanup and startup verification - Route sandbox inference through proxy port (11435) with the generated token as the OpenAI API key credential - Gate macOS hint on process.platform === "darwin" - Add OLLAMA_PROXY_PORT (11435) to ports.ts - Add 7 e2e tests and CI job for the proxy - Update unit tests for new port and error messages Reimplements the approach from #679 (closed in favor of #1104) against the current TypeScript codebase, addressing CodeRabbit findings from the original PR (timing-safe comparison, stale proxy cleanup, startup verification). Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Persist proxy token to ~/.nemoclaw/ollama-proxy-token (mode 0600) so it survives process restarts and onboard --resume - Add ensureOllamaAuthProxy() called on sandbox connect to auto-restart the proxy after host reboots - Restore WSL2 compatibility: skip proxy on WSL2 where Docker reaches the host directly (#1104), use OLLAMA_CONTAINER_PORT that adapts per platform - Fix e2e test: replace invalid 0.0.0.0 reachability test with localhost liveness check (0.0.0.0 as destination routes to loopback on both Linux and macOS) Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Ollama's Go runtime creates a dual-stack (AF_INET6) socket when given OLLAMA_HOST=0.0.0.0, but WSL2's port relay only forwards IPv4 sockets to the Windows host. Docker's host-gateway cannot reach the dual-stack socket, causing inference requests to fail with connection refused.
On WSL2, let Ollama bind to the default 127.0.0.1 instead, which creates an IPv4-only socket that the WSL2 relay forwards correctly.
Current support matrix on Windows / WSL Ollama inference path
Related Issue
#336 #417
Changes
On WSL2, skip setting
OLLAMA_HOST=0.0.0.0:11434when starting Ollama during onboard, letting it bind to the default127.0.0.1instead. Uses the existingisWsl()helper fromplatform.jsto detect WSL2.Type of Change
Testing
npx prek run --all-filespasses (or equivalentlymake check).npm testpasses.make docsbuilds without warnings. (for doc-only changes)Checklist
General
Code Changes
npx prek run --all-filesauto-fixes formatting (ormake formatfor targeted runs).Doc Changes
update-docsagent skill to draft changes while complying with the style guide. For example, prompt your agent with "/update-docscatch up the docs for the new changes I made in this PR."Summary by CodeRabbit
Bug Fixes
Documentation