Expose Cookbook user-install CLIs in Docker (#887)

Ensure pip --user console scripts like vLLM are visible to Docker
runtime and dependency probes by adding the user install bin directory
to PATH.
This commit is contained in:
Juan Pablo Jiménez
2026-06-01 22:23:29 -05:00
committed by GitHub
parent 9a1893760d
commit e58e4a185d
3 changed files with 74 additions and 0 deletions
+47
View File
@@ -183,13 +183,41 @@ def _package_status_note(name: str, probe: dict) -> str:
return ""
def _prepend_user_install_bins_to_path() -> None:
"""Make pip --user console scripts visible to dependency probes.
Docker Cookbook installs vLLM with `python -m pip install --user`, which
drops the `vllm` CLI in /app/.local/bin. The running app process does not
inherit that PATH update, so `shutil.which("vllm")` can report missing even
after a successful install.
"""
try:
import site
candidates = [os.path.join(site.USER_BASE, "bin")]
except Exception:
candidates = []
candidates.append(os.path.expanduser("~/.local/bin"))
parts = os.environ.get("PATH", "").split(os.pathsep) if os.environ.get("PATH") else []
changed = False
for path in reversed([p for p in candidates if p]):
if path not in parts:
parts.insert(0, path)
changed = True
if changed:
os.environ["PATH"] = os.pathsep.join(parts)
def _package_probe_script(names: list[str]) -> str:
names_lit = ",".join(repr(n) for n in names)
return f"""
import importlib.util
import importlib.metadata as md
import json
import os
import shutil
import site
names=[{names_lit}]
dist_names={{
@@ -204,6 +232,24 @@ bin_names={{
'llama_cpp':['llama-server'],
}}
def add_user_install_bins_to_path():
candidates = []
try:
candidates.append(os.path.join(site.USER_BASE, 'bin'))
except Exception:
pass
candidates.append(os.path.expanduser('~/.local/bin'))
parts = os.environ.get('PATH', '').split(os.pathsep) if os.environ.get('PATH') else []
changed = False
for path in reversed([p for p in candidates if p]):
if path not in parts:
parts.insert(0, path)
changed = True
if changed:
os.environ['PATH'] = os.pathsep.join(parts)
add_user_install_bins_to_path()
def mod_status(n):
spec = importlib.util.find_spec(n)
loader = getattr(spec, 'loader', None) if spec else None
@@ -793,6 +839,7 @@ def setup_shell_routes() -> APIRouter:
_require_admin(request)
_reject_cross_site(request)
import importlib, importlib.metadata as importlib_metadata, shlex, json as _json
_prepend_user_install_bins_to_path()
if ssh_port and str(ssh_port).strip() not in ("", "22"):
_port = str(ssh_port).strip()
if not _SSH_PORT_RE.match(_port) or not (1 <= int(_port) <= 65535):