fix(onboard): propagate NEMOCLAW_PROXY_HOST/PORT to sandbox env (#2424)#2581
Conversation
`patchStagedDockerfile()` already substitutes NEMOCLAW_PROXY_HOST and
NEMOCLAW_PROXY_PORT into the staged Dockerfile's ARG defaults at build
time, so the resulting image's `Config.Env` carries the user-supplied
values. But the runtime container does not see them: the create
command emitted by `createSandbox()` is
openshell sandbox create … -- env <whitelist> nemoclaw-start
and only the env vars listed before `nemoclaw-start` reach the
container — image-baked ENV is not forwarded by this path. The
existing whitelist already covers CHAT_UI_URL, NEMOCLAW_DASHBOARD_PORT
(conditional), Brave/Slack tokens, but omits the proxy pair.
Effect of the omission:
- Build time: Dockerfile ENV / RUN python step sees the override
and would bake e.g. discord/telegram channel proxies with the
new host:port if those channels are configured.
- Runtime: nemoclaw-start.sh:898 reads `${NEMOCLAW_PROXY_HOST:-…}`,
sees the var unset, falls back to the default 10.200.0.1:3128,
writes that into /tmp/nemoclaw-proxy-env.sh, and `HTTPS_PROXY`
inside the sandbox ignores the host override entirely.
Reporter on #2424 verified on v0.0.24 that `HTTPS_PROXY` inside the
sandbox is `http://10.200.0.1:3128` even after exporting custom values
on the host before `nemoclaw onboard`. End-to-end isolated tracing of
patchStagedDockerfile() + docker inspect of the built image + cat of
/tmp/nemoclaw-proxy-env.sh + .bashrc source chain confirmed the only
break point is between image ENV and pod runtime ENV.
Add the two assignments to the whitelist with the same input
validation regex used in `patchStagedDockerfile()` so build-time
and runtime accept identical inputs:
PROXY_HOST_RE = /^[A-Za-z0-9._:-]+$/
PROXY_PORT_RE = /^[0-9]{1,5}$/
Conditional push (only when the host env is present) keeps the
default behaviour byte-identical when no override is exported.
…nv-to-sandbox-2424 # Conflicts: # src/lib/onboard.ts
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds centralized validation for Changes
Sequence Diagram(s)sequenceDiagram
participant UserEnv as User env vars
participant Onboard as onboard script
participant Dockerfile as staged Dockerfile
participant Openshell as openshell sandbox create
participant Sandbox as runtime container
UserEnv->>Onboard: NEMOCLAW_PROXY_HOST/PORT set
Onboard->>Onboard: validate via isValidProxyHost/Port
alt valid
Onboard->>Dockerfile: optionally substitute ARGs
Onboard->>Openshell: pass env args (--env NEMOCLAW_PROXY_HOST/PORT)
Openshell->>Sandbox: start container with provided env
Sandbox->>Sandbox: HTTP_PROXY/HTTPS_PROXY set from env
else invalid
Onboard->>Openshell: create sandbox without proxy env
Sandbox->>Sandbox: uses baked/default proxy values
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/onboard.ts`:
- Around line 3601-3609: The current validation allows IPv6 (colons) and
out-of-range ports; update PROXY_HOST_RE to disallow colons (remove ":" from
/^[A-Za-z0-9._:-]+$/) so only hostnames/IPv4-like labels are accepted (e.g.
/^[A-Za-z0-9._-]+$/), and replace the loose PROXY_PORT_RE check with a numeric
range check: after reading sandboxProxyPort parse it to an integer and only
accept (0 <= port <= 65535) before calling formatEnvAssignment; apply the
identical tightened host and port validation logic in patchStagedDockerfile()
(use the same PROXY_HOST_RE/port numeric check and formatEnvAssignment calls) so
build-time and runtime proxy values are validated the same way.
🪄 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: Enterprise
Run ID: fd6ab830-9ef1-4df7-b396-d7b7c3aa96bd
📒 Files selected for processing (1)
src/lib/onboard.ts
…all sites Address review feedback on #2424. The previous regexes accepted inputs that nemoclaw-start.sh cannot turn into a valid http://${HOST}:${PORT} URL: - PROXY_HOST_RE = /^[A-Za-z0-9._:-]+$/ admitted raw IPv6 literals such as `2001:db8::1`. The runtime template does not bracket the host, so it would emit `http://2001:db8::1:1080`, which is not a legal URL. - PROXY_PORT_RE = /^[0-9]{1,5}$/ admitted out-of-range values such as `70000`. Extract isValidProxyHost / isValidProxyPort module-level helpers and use them in both `patchStagedDockerfile()` (build-time Dockerfile ARG override) and `createSandbox()` (runtime sandbox env whitelist). The host regex now drops `:` and the port path adds an explicit 1..65535 range check on Number(value). Keeping a single pair of helpers avoids the build-time and runtime paths drifting apart in future edits — the reviewer specifically asked for that alignment.
## Summary Refreshes the 0.0.29 documentation for user-facing changes merged in the past 24 hours. Version metadata stays on `0.0.29`. ## Changes - `docs/get-started/quickstart.md`, `docs/reference/commands.md`, and `docs/reference/troubleshooting.md`: Document dashboard port auto-allocation, `--control-ui-port`, and `nemoclaw list` dashboard URL output from [#2411](#2411). - `docs/inference/inference-options.md` and `docs/inference/switch-inference-providers.md`: Document local Ollama and local vLLM credential isolation from `OPENAI_API_KEY` from [#2580](#2580). - `docs/inference/inference-options.md`: Document Local NVIDIA NIM validation behavior from [#2505](#2505). - `docs/reference/commands.md`: Document the cloud-only NIM status display behavior from [#2622](#2622). - `docs/deployment/deploy-to-remote-gpu.md`: Clarify runtime propagation for `NEMOCLAW_PROXY_HOST` and `NEMOCLAW_PROXY_PORT` from [#2581](#2581). - `docs/workspace/backup-restore.md`: Document snapshot restore symlink handling for sandbox data paths from [#2488](#2488). - `docs/reference/commands.md`: Document `skill install --help` and OpenClaw plugin-shaped directory guidance from [#2585](#2585). ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Verification - [x] `npx prek run --all-files` passes - [ ] `npm test` passes - [ ] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [x] Docs updated for user-facing behavior changes - [x] `make docs` builds without warnings (doc changes only) - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) ## AI Disclosure - [x] AI-assisted — tool: Codex --- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added `--control-ui-port` flag for explicit dashboard port control * Implemented automatic port selection (18789–18799) when the default port is occupied * Clarified that local inference routes (Ollama, local vLLM) don't require `OPENAI_API_KEY` * Improved dashboard URL display in list and status commands * Enhanced symlink handling in workspace backup restoration * Updated multi-sandbox quickstart and troubleshooting guidance <!-- end of auto-generated comment: release notes by coderabbit.ai -->
…IA#2424) (NVIDIA#2581) <!-- markdownlint-disable MD041 --> ## Summary Fix NVIDIA#2424. `patchStagedDockerfile()` already substitutes `NEMOCLAW_PROXY_HOST` and `NEMOCLAW_PROXY_PORT` into the staged Dockerfile's ARG defaults at build time, so the resulting image's `Config.Env` carries the user-supplied values. But the runtime container does not see them: the create command emitted by `createSandbox()` is openshell sandbox create … -- env <whitelist> nemoclaw-start and only the env vars listed before `nemoclaw-start` reach the container — image-baked ENV is not forwarded by this path. The whitelist already covers `CHAT_UI_URL`, `NEMOCLAW_DASHBOARD_PORT`, Brave/Slack tokens, but omits the proxy pair. Effect: - **Build time**: Dockerfile `ENV` / `RUN python …` step sees the override. - **Runtime**: `nemoclaw-start.sh:898` reads `${NEMOCLAW_PROXY_HOST:-…}`, sees the var unset, falls back to `10.200.0.1:3128`, writes that into `/tmp/nemoclaw-proxy-env.sh`, and `HTTPS_PROXY` inside the sandbox ignores the host override entirely. Adds the two assignments to the whitelist with the same input validation regex used in `patchStagedDockerfile()` so build-time and runtime accept identical inputs. Conditional push (only when the host env is present) keeps the default behaviour byte-identical when no override is exported. ## Diagnosis trace End-to-end isolated tracing on a Jetson with reporter's exact inputs (`NEMOCLAW_PROXY_HOST=216.81.245.236`, `NEMOCLAW_PROXY_PORT=1080`): | Stage | Evidence | Status | |---|---|---| | host env | `env \| grep NEMOCLAW_PROXY` shows both | ✓ | | Dockerfile ARG | `Step 38/54 : ARG NEMOCLAW_PROXY_HOST=216.81.245.236` | ✓ | | image `Config.Env` | `docker inspect` shows the override | ✓ | | sandbox runtime ENV | `env \| grep NEMOCLAW_PROXY` empty | ✗ break | | `/tmp/nemoclaw-proxy-env.sh` | wrote default `10.200.0.1:3128` | ✗ default | The break is between image and runtime container ENV — `openshell sandbox create -- env … cmd` only forwards explicitly-listed vars. ## Test plan - [x] Isolated test of unchanged `patchStagedDockerfile()` against the real project Dockerfile with reporter's inputs — confirms ARG substitution still works (both `host` and `port` rewritten correctly). - [x] End-to-end on Ubuntu 2404 with override exported: - `HTTPS_PROXY` inside sandbox now reads `http://216.81.245.236:1080` (was `http://10.200.0.1:3128`). - `/tmp/nemoclaw-proxy-env.sh` is written with the override values. - [x] Regression check with no env exported: - Build still emits `ARG NEMOCLAW_PROXY_HOST=10.200.0.1` / `ARG NEMOCLAW_PROXY_PORT=3128`. - Onboard reaches [8/8] without changes to default behaviour. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Sandbox creation now correctly respects and validates custom proxy host and port, preventing silent fallback to a default proxy. * Proxy settings are reliably forwarded into the sandbox environment so containers use the intended network proxy configuration. * Dockerfile argument substitutions for proxy values are now conditionally applied based on validation, reducing misconfigured builds. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <!-- DCO sign-off required by CI. Run: git config user.name && git config user.email --> Signed-off-by: Yanyun Liao <yanyunl@nvidia.com>
## Summary Refreshes the 0.0.29 documentation for user-facing changes merged in the past 24 hours. Version metadata stays on `0.0.29`. ## Changes - `docs/get-started/quickstart.md`, `docs/reference/commands.md`, and `docs/reference/troubleshooting.md`: Document dashboard port auto-allocation, `--control-ui-port`, and `nemoclaw list` dashboard URL output from [NVIDIA#2411](NVIDIA#2411). - `docs/inference/inference-options.md` and `docs/inference/switch-inference-providers.md`: Document local Ollama and local vLLM credential isolation from `OPENAI_API_KEY` from [NVIDIA#2580](NVIDIA#2580). - `docs/inference/inference-options.md`: Document Local NVIDIA NIM validation behavior from [NVIDIA#2505](NVIDIA#2505). - `docs/reference/commands.md`: Document the cloud-only NIM status display behavior from [NVIDIA#2622](NVIDIA#2622). - `docs/deployment/deploy-to-remote-gpu.md`: Clarify runtime propagation for `NEMOCLAW_PROXY_HOST` and `NEMOCLAW_PROXY_PORT` from [NVIDIA#2581](NVIDIA#2581). - `docs/workspace/backup-restore.md`: Document snapshot restore symlink handling for sandbox data paths from [NVIDIA#2488](NVIDIA#2488). - `docs/reference/commands.md`: Document `skill install --help` and OpenClaw plugin-shaped directory guidance from [NVIDIA#2585](NVIDIA#2585). ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Verification - [x] `npx prek run --all-files` passes - [ ] `npm test` passes - [ ] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [x] Docs updated for user-facing behavior changes - [x] `make docs` builds without warnings (doc changes only) - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) ## AI Disclosure - [x] AI-assisted — tool: Codex --- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added `--control-ui-port` flag for explicit dashboard port control * Implemented automatic port selection (18789–18799) when the default port is occupied * Clarified that local inference routes (Ollama, local vLLM) don't require `OPENAI_API_KEY` * Improved dashboard URL display in list and status commands * Enhanced symlink handling in workspace backup restoration * Updated multi-sandbox quickstart and troubleshooting guidance <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Fix #2424.
patchStagedDockerfile()already substitutesNEMOCLAW_PROXY_HOSTandNEMOCLAW_PROXY_PORTinto the staged Dockerfile's ARG defaults at build time, so the resulting image'sConfig.Envcarries the user-supplied values. But the runtime container does not see them: the create command emitted bycreateSandbox()isand only the env vars listed before
nemoclaw-startreach the container — image-baked ENV is not forwarded by this path. The whitelist already coversCHAT_UI_URL,NEMOCLAW_DASHBOARD_PORT, Brave/Slack tokens, but omits the proxy pair.Effect:
ENV/RUN python …step sees the override.nemoclaw-start.sh:898reads${NEMOCLAW_PROXY_HOST:-…},sees the var unset, falls back to
10.200.0.1:3128, writes that into/tmp/nemoclaw-proxy-env.sh, andHTTPS_PROXYinside the sandboxignores the host override entirely.
Adds the two assignments to the whitelist with the same input validation regex used in
patchStagedDockerfile()so build-time and runtime accept identical inputs. Conditional push (only when the host env is present) keeps the default behaviour byte-identical when no override is exported.Diagnosis trace
End-to-end isolated tracing on a Jetson with reporter's exact inputs
(
NEMOCLAW_PROXY_HOST=216.81.245.236,NEMOCLAW_PROXY_PORT=1080):env | grep NEMOCLAW_PROXYshows bothStep 38/54 : ARG NEMOCLAW_PROXY_HOST=216.81.245.236Config.Envdocker inspectshows the overrideenv | grep NEMOCLAW_PROXYempty/tmp/nemoclaw-proxy-env.sh10.200.0.1:3128The break is between image and runtime container ENV —
openshell sandbox create -- env … cmdonly forwards explicitly-listed vars.Test plan
patchStagedDockerfile()against the real project Dockerfile with reporter's inputs — confirms ARG substitution still works (bothhostandportrewritten correctly).HTTPS_PROXYinside sandbox now readshttp://216.81.245.236:1080(was
http://10.200.0.1:3128)./tmp/nemoclaw-proxy-env.shis written with the override values.ARG NEMOCLAW_PROXY_HOST=10.200.0.1/ARG NEMOCLAW_PROXY_PORT=3128.Summary by CodeRabbit
Signed-off-by: Yanyun Liao yanyunl@nvidia.com