1- # syntax=docker/dockerfile:1.4
1+ # syntax=docker/dockerfile:1
22
33# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
44# SPDX-License-Identifier: Apache-2.0
@@ -20,9 +20,9 @@ ENV DEBIAN_FRONTEND=noninteractive \
2020WORKDIR /sandbox
2121
2222# Core system dependencies
23- # python3.13 + pip: agent scripting and SDK usage (deadsnakes PPA for Noble)
2423# iproute2: network namespace management (ip netns, veth pairs)
2524# dnsutils: dig, nslookup
25+ # Python is managed entirely by uv (see devtools stage).
2626RUN apt-get update && apt-get install -y --no-install-recommends \
2727 ca-certificates \
2828 curl \
@@ -33,16 +33,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
3333 netcat-openbsd \
3434 openssh-sftp-server \
3535 procps \
36- software-properties-common \
3736 traceroute \
38- && add-apt-repository -y ppa:deadsnakes/ppa \
39- && apt-get update \
40- && apt-get install -y --no-install-recommends \
41- python3.13 \
42- python3.13-venv \
43- && curl -sS https://bootstrap.pypa.io/get-pip.py | python3.13 \
44- && update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.13 1 \
45- && update-alternatives --install /usr/bin/python python /usr/bin/python3.13 1 \
4637 && rm -rf /var/lib/apt/lists/*
4738
4839# Create supervisor and sandbox users/groups
@@ -52,20 +43,36 @@ RUN groupadd -r supervisor && useradd -r -g supervisor -s /usr/sbin/nologin supe
5243# Developer tools
5344FROM system AS devtools
5445
55- # Node.js 22 + build toolchain (needed by npm packages with native addons)
46+ # Node.js 22 + build toolchain (needed by npm packages with native addons).
47+ # Pin to a specific patch version for reproducible builds.
48+ # CVE-2026-21637, CVE-2025-59466, CVE-2025-59465, CVE-2025-55131 affect
49+ # Node.js <= 22.22.1. Update to 22.23.0+ when a patched release ships.
50+ #
51+ # npm is upgraded to v11 in the same layer to avoid caching the old npm.
52+ # npm 11 ships tar@^7.5.9, fixing tar@6.2.1 vulns bundled in npm 10
53+ # (GHSA-r6q2-hw4h-h46w, GHSA-8qq5-rm4j-mr97, GHSA-83g3-92jg-28cx,
54+ # GHSA-34x7-hfp2-rc4v, GHSA-qffp-2rhf-9h96).
5655RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
5756 apt-get install -y --no-install-recommends \
5857 build-essential \
5958 git \
60- nodejs \
59+ nodejs=22.22.1-1nodesource1 \
6160 vim-tiny \
6261 nano \
63- && rm -rf /var/lib/apt/lists/*
64-
65- # Fix transitive tar vulnerabilities (GHSA-qffp-2rhf-9h96,
66- # GHSA-9ppj-qmqm-q256, GHSA-8qq5-rm4j-mr97, GHSA-r6q2-hw4h-h46w,
67- # GHSA-34x7-hfp2-rc4v, GHSA-83g3-92jg-28cx).
68- RUN npm install -g tar@7.5.11
62+ && rm -rf /var/lib/apt/lists/* \
63+ && npm install -g npm@11.11.0
64+
65+ # Global npm packages — pinned for reproducibility.
66+ # tar + @hono/node-server: transitive vuln fixes
67+ # (GHSA-qffp-2rhf-9h96, GHSA-9ppj-qmqm-q256, GHSA-8qq5-rm4j-mr97,
68+ # GHSA-r6q2-hw4h-h46w, GHSA-34x7-hfp2-rc4v, GHSA-83g3-92jg-28cx,
69+ # GHSA-wc8c-qw6v-h7f6).
70+ # opencode-ai + @openai/codex: agent CLIs.
71+ RUN npm install -g \
72+ tar@7.5.11 \
73+ @hono/node-server@1.19.11 \
74+ opencode-ai@1.2.18 \
75+ @openai/codex@0.111.0
6976
7077# GitHub CLI
7178RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
@@ -75,20 +82,61 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
7582 apt-get update && apt-get install -y --no-install-recommends gh && \
7683 rm -rf /var/lib/apt/lists/*
7784
78- # uv (Python package manager)
79- COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
85+ # Install Claude CLI via native installer (npm method is deprecated)
86+ RUN curl -fsSL https://claude.ai/install.sh | bash \
87+ && cp /root/.local/bin/claude /usr/local/bin/claude \
88+ && chmod 755 /usr/local/bin/claude
89+
90+ # uv (Python package/project manager) — pinned for reproducibility.
91+ # uv manages the Python toolchain; no system Python packages are needed.
92+ COPY --from=ghcr.io/astral-sh/uv:0.10.8 /uv /usr/local/bin/uv
93+ ENV UV_PYTHON_INSTALL_DIR="/sandbox/.uv/python"
94+ RUN uv python install 3.13 && \
95+ ln -s $(uv python find 3.13) /usr/local/bin/python3 && \
96+ ln -s $(uv python find 3.13) /usr/local/bin/python && \
97+ uv cache clean
8098
8199# Final base image
82100FROM devtools AS final
83101
84- # Ensure policy directory exists
85- RUN mkdir -p /etc/navigator
102+ # Add venvs to PATH -- /sandbox/.venv (writable, user-installed packages)
103+ # takes priority over system paths.
104+ # VIRTUAL_ENV and UV_PYTHON_INSTALL_DIR are also exported in .bashrc
105+ # so that login shell sessions (interactive and exec) see them.
106+ ENV PATH="/sandbox/.venv/bin:/usr/local/bin:/usr/bin:/bin" \
107+ VIRTUAL_ENV="/sandbox/.venv"
108+
109+ # Default sandbox network / filesystem policy
110+ COPY policy.yaml /etc/navigator/policy.yaml
111+
112+ # Copy custom skills into the image.
113+ # To add a skill, create a subdirectory under sandboxes/base/skills/
114+ # with a SKILL.md file (and any supporting files). It will be installed into
115+ # both ~/.claude/skills/ and ~/.agents/skills/ for agent discovery.
116+ COPY skills/ /sandbox/.agents/skills/
86117
87118# Set up sandbox user home directory
88- RUN mkdir -p /sandbox/.agents/skills && \
89- printf 'export PS1="\\ u@\\ h:\\ w\\ $ "\n ' > /sandbox/.bashrc && \
119+ RUN mkdir -p /sandbox/.claude/skills && \
120+ # Create a writable venv using uv-managed Python 3.13.
121+ # Sandbox users can `uv pip install` (or `pip install`) into
122+ # this venv without touching the base image layer.
123+ uv venv --python 3.13 --seed /sandbox/.venv && \
124+ uv cache clean && \
125+ chown -R sandbox:sandbox /sandbox/.venv && \
126+ # Minimal shell init files so interactive and non-interactive shells
127+ # get a sane PATH and prompt. Without these, bash sources nothing
128+ # under /sandbox and tools like VS Code Remote-SSH may mis-detect
129+ # the platform.
130+ printf 'export PATH="/sandbox/.venv/bin:/usr/local/bin:/usr/bin:/bin"\n export VIRTUAL_ENV="/sandbox/.venv"\n export UV_PYTHON_INSTALL_DIR="/sandbox/.uv/python"\n export PS1="\\ u@\\ h:\\ w\\ $ "\n ' \
131+ > /sandbox/.bashrc && \
90132 printf '[ -f ~/.bashrc ] && . ~/.bashrc\n ' > /sandbox/.profile && \
91- chown -R sandbox:sandbox /sandbox
133+ chown sandbox:sandbox /sandbox/.bashrc /sandbox/.profile && \
134+ # Symlink skills into agent discovery directories
135+ for skill in /sandbox/.agents/skills/*/; do \
136+ [ -d "$skill" ] || continue; \
137+ ln -sf "$skill" "/sandbox/.claude/skills/$(basename " $skill")" ; \
138+ done && \
139+ chown -R sandbox:sandbox /sandbox/.claude /sandbox/.agents /sandbox
92140
93141USER sandbox
94142
0 commit comments