Repository navigation
claude-docker: add --registry flag for private package registries (uv / pnpm / pip) - #57
Conversation
stefanwb
left a comment
There was a problem hiding this comment.
Adds an opt-in --registry flag that surfaces the host's native package-manager registry config (~/.npmrc, uv.toml, platform-aware pip.conf + scoped env vars) read-only into the container. Faithfully mirrors the existing --aws/--gh/--glab/--tfe pattern.
Correctness — verified against surrounding code:
- Arrays (
ENV_ARGS/MOUNT_ARGS) initialized before the registry blocks;set -u/bash-3.2 guards preserved. HOME=/root(entrypoint.sh:17) confirms mount targets are the paths the tools actually read.compgen -escan ispipefail-safe (process substitution) and correctly suffix-scoped to avoid theUV_CACHE_DIRfoot-gun.-xdevin the entrypoint chown prunes the new:romounts — no ownership conflict.
Security — well reasoned: default-deny, all mounts :ro, and the deliberate ~/.netrc exclusion (D9) is the right call. Whole-file exposure is honestly documented (
Suggestions (non-blocking):
smoke/smoke.shwasn't extended for--registry— it has structured coverage foraws/glab/tfeand this fits the same pattern. Worth adding to lock in the no-flag invariant.tasks.mdhas stale references: task 1.2 still says to mount~/.netrc(contradicts shipped D9), and 3.6's "superseded by 5.5" points at a non-existent task. Cosmetic cleanup of archived artifacts.
TL;DR Thanks for this PR, it does LGTM. Could you consider implementing #1 as well? That would be appreciated, also fine to merge as-is.
Summary
Adds a
--registryopt-in flag toclaude-dockerso in-containeruv,pnpm,and pip-based tools (
pip/pipenv) resolve against a private package feed —AWS CodeArtifact, Artifactory, Nexus, GitLab/Azure — the same way the team's
pipelines do, instead of always hitting public npm / PyPI.
The approach is deliberately a thin wrapper concern: rather than invent any
claude-docker-specific registry config,
--registrysurfaces the packagemanagers' own native config from the host (read-only mounts + native env-var
forwarding), exactly mirroring how
--aws/--gh/--glab/--tfealreadysurface other host credentials. This inherits every registry vendor for free —
they all speak the npm/PyPI dialect — and means a host that already runs
aws codeartifact loginworks with zero extra steps.Off by default; nothing reaches the container without the flag.
What it does
When
--registryis passed,run.sh:(
~/.npmrc, or thenpm_config_userconfigtarget if relocated) →/root/.npmrc,~/.config/uv/uv.toml, and the platform-appropriatepip.conf(macOS
~/Library/Application Support/pip/pip.conf, Linux~/.config/pip/pip.conf).npm_config_registry/NPM_CONFIG_REGISTRY/NODE_AUTH_TOKEN/NPM_TOKEN,UV_INDEX_URL/UV_DEFAULT_INDEX/UV_EXTRA_INDEX_URL/UV_INDEX/UV_KEYRING_PROVIDERplus any
UV_INDEX_<NAME>_USERNAME/_PASSWORD(uv's per-index credentials,whose names embed a user-chosen index name), and
PIP_INDEX_URL/PIP_EXTRA_INDEX_URL/PIP_TRUSTED_HOST/PIPENV_PYPI_MIRROR.docker:…,registry.No image/Dockerfile change —
uv/pnpmalready ship.pip/pipenvaren'tbundled (the image ships no Python by design); run them via
uvx pipenv …or achild image, and the forwarded config flows through to whichever pip executes.
Security posture
:ro— the container can't mutate host registry config, and asession can't persist registry credentials into the named volume.
~/.netrcis deliberately NOT mounted. It's a machine-keyed store thatroutinely holds logins for hosts unrelated to the registry; forwarding the
whole file into a full-egress container is too broad.
UV_NETRCisn'tforwarded either. Registry auth belongs in
~/.npmrc/pip.conf/ the indexURL /
UV_INDEX_*_PASSWORD.UV_INDEX_*scan is scoped strictly to the_USERNAME/_PASSWORDsuffixes — no blanket
UV_*forward (avoids dragging in path-valued vars likeUV_CACHE_DIRthat would point at absent host paths).--registryis registry-resolution config, not a network boundary — itnarrows where the package managers resolve, but egress is unchanged.
public npm/PyPI regardless of host registry config, keeping builds
reproducible from the committed pins.
~/.npmrc/pip.confare whole-file mounts, so a token-bearing file exposesevery entry it holds — documented as a
🤖 Generated with Claude Code
✅ verified by carlovoSBP