Skip to content

Run managed vLLM Docker with argv - #5475

Closed
fallintoplace wants to merge 1 commit into
NVIDIA:mainfrom
fallintoplace:fix/vllm-docker-argv
Closed

Run managed vLLM Docker with argv#5475
fallintoplace wants to merge 1 commit into
NVIDIA:mainfrom
fallintoplace:fix/vllm-docker-argv

Conversation

@fallintoplace

@fallintoplace fallintoplace commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary

The managed vLLM startup path built docker run as one shell string by joining profile flags, Hugging Face token flags, image/container fields, and the cache mount before executing through bash -c. That made profile-controlled values and host paths more fragile than they needed to be, and created an avoidable host-side command injection surface.

This changes the long-lived vLLM container startup to build Docker argv tokens and execute through the existing Docker adapter helpers. It also moves container cleanup from shell strings to Docker argv helpers, resolves the Hugging Face cache mount with os.homedir(), and removes the Station multi-GPU shell quote workaround now that --gpus device=0,1 is passed as a single argv token.

The in-container /bin/bash -lc boundary remains intentional for the existing pip install ... && vllm serve ... behavior; the host Docker invocation no longer depends on shell parsing.

Validation

  • npm test -- src/lib/inference/vllm.test.ts src/lib/inference/vllm-models.test.ts
  • npm test -- test/detect-vllm-profile.test.ts
  • npm test -- src/lib/inference/vllm.test.ts
  • npx @biomejs/biome lint src/lib/inference/vllm.ts src/lib/inference/vllm.test.ts
  • npm run build:cli
  • npm run typecheck:cli

Summary by CodeRabbit

  • Refactor
    • Improved vLLM container initialization to use safer Docker argument handling, replacing shell-based command construction with direct argument arrays for enhanced reliability.
    • Enhanced Hugging Face token forwarding and cache directory mounting to work more consistently across platform configurations.
    • Strengthened GPU selection integration with vLLM container startup.

@copy-pr-bot

copy-pr-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 687b247c-a8cd-47ca-a7f2-36d3d1893155

📥 Commits

Reviewing files that changed from the base of the PR and between 543bbd4 and 0c85ca1.

📒 Files selected for processing (2)
  • src/lib/inference/vllm.test.ts
  • src/lib/inference/vllm.ts

📝 Walkthrough

Walkthrough

The PR refactors vLLM container launch in vllm.ts from shell-string command construction to an argv-based approach. It introduces shared Hugging Face cache mount helpers, replaces the exported buildVllmRunCommand with buildVllmRunArgs (with argument validation), migrates container start/stop operations to typed Docker adapter functions, and updates tests accordingly.

Changes

vLLM Docker argv refactor

Layer / File(s) Summary
HF cache helpers and shared run flags
src/lib/inference/vllm.ts
Adds HF_CACHE_CONTAINER_DIR, hfCacheMount(), and vllmDockerRunFlags() to centralize GPU/IPC/cache-mount/HF_HOME flag generation; updates imports to use os/path and new Docker adapters; switches hf download to the shared cache mount helpers; refines the HF token forwarding comment.
buildVllmRunArgs: validated argv construction
src/lib/inference/vllm.ts, src/lib/inference/vllm.test.ts
Removes buildVllmRunCommand and adds buildVllmRunArgs with validateDockerArg(s) guards, constructing a full docker run argv array with --restart unless-stopped, port mapping, container name, and bash -lc serve command. Tests assert restart policy, metadata, custom flags, shell-metacharacter safety, HF cache mount formatting, and Station multi-GPU rendering.
Container startup and teardown via typed Docker adapters
src/lib/inference/vllm.ts
Startup calls dockerForceRm before launch; buildVllmRunArgs output is passed to dockerRunDetached with buildHfTokenForwardEnv() in runner options; installVllm failure-path teardown switches from runShell('docker stop ...') to dockerStop(profile.containerName).
Test infrastructure and installVllm integration test
src/lib/inference/vllm.test.ts
Expands hoisted mocks to include dockerForceRm, dockerRunDetached, dockerSpawn, and dockerStop; adds mockDockerSpawnSuccess() helper; drops runShell mock; adds an installVllm test verifying cleanup, argv correctness, no shell string leakage, vllm serve in the -lc payload, and { env: { HF_TOKEN } } options wiring.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5038: Adds resolveVllmInstallModel and platform-scoped model defaults to vllm.ts, which the new buildVllmRunArgs and installVllm changes in this PR build upon directly.

Suggested labels

provider: vllm, area: onboarding, v0.0.63

🐇 From shell strings I now leap free,
Each argv token safe as can be!
--restart unless-stopped, port and name—
No metachar mischief, no quoting game.
HF cache mounts tidy, Docker adapters true,
This bunny hops safely through each docker run queue! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Run managed vLLM Docker with argv' directly and accurately summarizes the main change: refactoring vLLM Docker invocation from shell string construction to argv-based execution.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@wscurran wscurran added area: local-models Local model providers, downloads, launch, or connectivity bug-fix PR fixes a bug or regression provider: vllm vLLM local or hosted provider behavior labels Jun 23, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for the proposed fix addressing the shell-string-based Docker invocation that created a command injection surface in the managed vLLM startup path. This proposes a way to build Docker argv tokens and execute through Docker adapter helpers, moving container cleanup to argv helpers and resolving the Hugging Face cache mount with os.homedir().

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Superseded by #6523, which rebases this two-file security hardening onto current main with a clean verified/DCO-compliant history. Minh Vu's implementation credit is preserved in the PR body and as Co-authored-by on the signed commit.

apurvvkumaria added a commit that referenced this pull request Jul 9, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 sentences: what this PR does and why. -->

Replace shell-composed managed vLLM Docker startup with validated
argument vectors so profile flags and sensitive environment forwarding
reach Docker without shell interpolation.
This supersedes #5475 with a current-main, DCO-compliant history.
Original implementation credit: Minh Vu (`fallintoplace`).

## Changes
<!-- Bullet list of key changes. -->

- Build the long-lived vLLM container invocation as validated Docker
argv and reject empty or NUL-bearing tokens.
- Use typed Docker lifecycle adapters for container removal, detached
startup, and shutdown instead of composing shell commands.
- Keep Hugging Face token values in the subprocess environment while
forwarding only the selected variable name to Docker.
- Normalize Hugging Face cache mounts and multi-GPU flags as individual
argv tokens.
- Add adversarial and lifecycle coverage for metacharacter handling,
token secrecy, profile flags, and managed startup.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates
<!-- Check exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: Independent documentation
review found no command, configuration, default, output contract, or
supported workflow change; this hardens the existing managed vLLM launch
path.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Independent
nine-category security review returned PASS with no blocking findings.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable —
diff-scoped prek validation and the normal pre-push CLI type-check
passed on the current commit.
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: 56
focused CLI tests and 19 profile integration tests passed with one
worker (75/75).
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Broad gates were not run;
the CLI build and type-check passed.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] 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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Improved vLLM container startup using structured Docker argv calls,
including clearer Hugging Face cache mounting and GPU-related launch
flags.
* Updated token handling so inference containers receive token keys
while token values are supplied via the runner environment.

* **Bug Fixes**
* Eliminated shell-assembled container run strings to reliably handle
special characters and invalid inputs (e.g., empty/NUL tokens).
* Improved idempotent cleanup and container stop behavior on
startup/readiness failures.

* **Tests**
* Expanded coverage for vLLM install and run argument validation,
including HF token forwarding and rejection of invalid Docker run flags.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Minh Vu <vuhoangminh97@gmail.com>
Co-authored-by: cjagwani <cjagwani@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 sentences: what this PR does and why. -->

Replace shell-composed managed vLLM Docker startup with validated
argument vectors so profile flags and sensitive environment forwarding
reach Docker without shell interpolation.
This supersedes NVIDIA#5475 with a current-main, DCO-compliant history.
Original implementation credit: Minh Vu (`fallintoplace`).

## Changes
<!-- Bullet list of key changes. -->

- Build the long-lived vLLM container invocation as validated Docker
argv and reject empty or NUL-bearing tokens.
- Use typed Docker lifecycle adapters for container removal, detached
startup, and shutdown instead of composing shell commands.
- Keep Hugging Face token values in the subprocess environment while
forwarding only the selected variable name to Docker.
- Normalize Hugging Face cache mounts and multi-GPU flags as individual
argv tokens.
- Add adversarial and lifecycle coverage for metacharacter handling,
token secrecy, profile flags, and managed startup.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates
<!-- Check exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: Independent documentation
review found no command, configuration, default, output contract, or
supported workflow change; this hardens the existing managed vLLM launch
path.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Independent
nine-category security review returned PASS with no blocking findings.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable —
diff-scoped prek validation and the normal pre-push CLI type-check
passed on the current commit.
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: 56
focused CLI tests and 19 profile integration tests passed with one
worker (75/75).
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Broad gates were not run;
the CLI build and type-check passed.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] 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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Improved vLLM container startup using structured Docker argv calls,
including clearer Hugging Face cache mounting and GPU-related launch
flags.
* Updated token handling so inference containers receive token keys
while token values are supplied via the runner environment.

* **Bug Fixes**
* Eliminated shell-assembled container run strings to reliably handle
special characters and invalid inputs (e.g., empty/NUL tokens).
* Improved idempotent cleanup and container stop behavior on
startup/readiness failures.

* **Tests**
* Expanded coverage for vLLM install and run argument validation,
including HF token forwarding and rejection of invalid Docker run flags.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Minh Vu <vuhoangminh97@gmail.com>
Co-authored-by: cjagwani <cjagwani@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: local-models Local model providers, downloads, launch, or connectivity bug-fix PR fixes a bug or regression provider: vllm vLLM local or hosted provider behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants