Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions dockerfiles/Dockerfile.sandbox
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# =============================================================================
# Dependency Locking
# =============================================================================
# The sandbox uses pinned dependencies from two lock files:
# - requirements/sandbox-core.lock (from code_execution.txt — always installed)
# - requirements/sandbox.lock (from code_execution.txt + stem.txt — skip on CI/arm64)
#
# To regenerate after changing code_execution.txt or stem.txt:
# uv pip compile requirements/code_execution.txt \
# --python-version 3.10 -o requirements/sandbox-core.lock
# uv pip compile requirements/code_execution.txt requirements/stem.txt \
# --extra-index-url https://download.pytorch.org/whl/cpu \
# --python-version 3.10 -o requirements/sandbox.lock
# =============================================================================

# Use the base image with Python 3.10 and Flask
FROM tiangolo/uwsgi-nginx-flask:python3.10

Expand Down Expand Up @@ -59,26 +74,25 @@ RUN cd /lean4/my_project && \
ENV LEAN_PATH="/lean4/my_project"
ENV PATH="/lean4/my_project:$PATH"

# Set up application code and install Python dependencies
COPY requirements/code_execution.txt /app/requirements.txt
RUN pip install --no-cache-dir -r /app/requirements.txt


# Install STEM related libraries
COPY requirements/stem.txt /app/stem_requirements.txt


# Speed/size/env hygiene
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
UV_SYSTEM_PYTHON=1 \
PATH="/root/.local/bin:${PATH}"

# Install uv
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Piping curl to shell (curl | sh) downloads and executes remote code without verification. Consider downloading the script first, verifying its checksum, then executing it for better security.

Suggested change
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
RUN curl -LsSf https://astral.sh/uv/install.sh -o /tmp/uv-install.sh && \
sh /tmp/uv-install.sh && rm /tmp/uv-install.sh

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +82 to +83
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

uv install script version pinning astral.sh

💡 Result:

To pin a specific uv version when using Astral’s install scripts, put the version in the URL path:

  • macOS/Linux (sh):
    curl -LsSf https://astral.sh/uv/0.10.0/install.sh | sh
  • Windows (PowerShell):
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/0.10.0/install.ps1 | iex"

[1]

For Docker, pin the installer URL the same way (or pin the Docker image tag / digest):

ADD https://astral.sh/uv/0.10.0/install.sh /uv-installer.sh

[2]

If you also need reproducible install behavior (path, no PATH modification, etc.), the installer supports environment variables like UV_INSTALL_DIR, UV_NO_MODIFY_PATH, and UV_UNMANAGED_INSTALL. [3]


🏁 Script executed:

# Look for any version hints in lock files or documentation
fd -type f \( -name "uv.lock" -o -name "uv.toml" -o -name "pyproject.toml" -o -name "requirements*.txt" \) | head -20

Repository: NVIDIA-NeMo/Skills

Length of output: 232


🏁 Script executed:

# Check the Dockerfile context for other version pins or version references
cat -n dockerfiles/Dockerfile.sandbox | head -100

Repository: NVIDIA-NeMo/Skills

Length of output: 5242


🏁 Script executed:

# Look for CI/CD files and setup configurations that may specify uv version
fd -name "*.yml" -o -name "*.yaml" -o -name ".github" | head -20

Repository: NVIDIA-NeMo/Skills

Length of output: 292


🏁 Script executed:

# Search for uv version references in the entire repo
rg "uv.*[0-9]+\.[0-9]+" --max-count 10

Repository: NVIDIA-NeMo/Skills

Length of output: 523


🏁 Script executed:

# Check the lock files themselves for version info
fd -name "*.lock" -type f

Repository: NVIDIA-NeMo/Skills

Length of output: 292


🏁 Script executed:

# Find lock files and CI files
git ls-files | grep -E "(\.lock|\.yml|\.yaml|pyproject\.toml)" | head -30

Repository: NVIDIA-NeMo/Skills

Length of output: 1318


🏁 Script executed:

# Search for uv version references more carefully
rg "uv" --type py --type txt --type toml | grep -i "version\|0\.[0-9]" | head -20

Repository: NVIDIA-NeMo/Skills

Length of output: 374


🏁 Script executed:

# Check if there's a pyproject.toml with uv config
fd "pyproject.toml" -type f

Repository: NVIDIA-NeMo/Skills

Length of output: 232


🏁 Script executed:

# Find lock files more simply
find . -name "*.lock" -type f 2>/dev/null | head -20

Repository: NVIDIA-NeMo/Skills

Length of output: 122


🏁 Script executed:

# Check the GitHub workflow files for uv version pins
cat .github/workflows/tests.yml | head -100

Repository: NVIDIA-NeMo/Skills

Length of output: 3631


🏁 Script executed:

# Look for any mentions of uv version in the codebase
rg "astral.*uv" --max-count 10

Repository: NVIDIA-NeMo/Skills

Length of output: 464


🏁 Script executed:

# Check Dockerfile.nemo-rl to see what UV_VERSION is set to
cat -n dockerfiles/Dockerfile.nemo-rl | grep -A 5 -B 5 "UV_VERSION"

Repository: NVIDIA-NeMo/Skills

Length of output: 576


🏁 Script executed:

# Look for ARG UV_VERSION or ENV UV_VERSION definitions
rg "UV_VERSION" -B 2 -A 2

Repository: NVIDIA-NeMo/Skills

Length of output: 525


Pin the uv version for reproducible builds.

The whole point of this PR is reproducible sandbox builds, but uv itself is installed without a version pin. Future uv releases could change behavior or introduce incompatibilities. Pin the version in the install URL using an ARG (following the pattern already established in Dockerfile.nemo-rl).

Dockerfile.nemo-rl correctly pins this with:

ARG UV_VERSION=0.9.7
RUN curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh

Apply the same pattern to Dockerfile.sandbox, using the uv version that was used to generate the lock files.

🤖 Prompt for AI Agents
In `@dockerfiles/Dockerfile.sandbox` around lines 82 - 83, Add a pinned UV version
ARG and use it in the existing uv install RUN command: introduce an ARG named
UV_VERSION (set to the uv version used to generate the lock files) near the top
of Dockerfile.sandbox and change the existing RUN curl -LsSf
https://astral.sh/uv/install.sh | sh invocation to use
https://astral.sh/uv/${UV_VERSION}/install.sh so the RUN line that installs uv
is reproducible; reference the ARG name UV_VERSION and the RUN command that
currently installs uv to locate the change.


# Set up application code directory
WORKDIR /app

# Install uv (adds to ~/.local/bin), then install deps
# Install core Python dependencies from lock file (always)
COPY requirements/sandbox-core.lock /app/requirements-core.lock
RUN uv pip install --system -r /app/requirements-core.lock

# Install full dependencies including STEM libraries (skip on CI/arm64)
COPY requirements/sandbox.lock /app/requirements.lock
RUN if [ "$GITHUB_CI" != "1" ] && [ "$TARGETARCH" != "arm64" ]; then \
curl -LsSf https://astral.sh/uv/install.sh | sh && \
uv pip install --upgrade pip && \
uv pip install -r /app/stem_requirements.txt --no-cache-dir --extra-index-url https://download.pytorch.org/whl/cpu; \
uv pip install --system -r /app/requirements.lock --extra-index-url https://download.pytorch.org/whl/cpu; \
fi

# For scicode eval - create data directory and download test data
Expand Down Expand Up @@ -132,9 +146,6 @@ RUN gcc -shared -fPIC -o /usr/lib/libblock_network.so /tmp/block_network.c -ldl
COPY dockerfiles/sandbox/start-with-nginx.sh /start-with-nginx.sh
RUN chmod +x /start-with-nginx.sh

# Set the working directory to /app
WORKDIR /app

# Environment variables for multi-worker setup
ENV NGINX_PORT=6000

Expand Down
2 changes: 2 additions & 0 deletions requirements/code_execution.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

# this are requirements for code execution - put all packages that LLM should have access to in here
annotated-types>=0.7.0
flask
gunicorn
h5py
# needed for persistent sessions
ipython
Expand Down
91 changes: 91 additions & 0 deletions requirements/sandbox-core.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# This file was autogenerated by uv via the following command:
# uv pip compile requirements/code_execution.txt --python-version 3.10 -o requirements/sandbox-core.lock
annotated-types==0.7.0
# via -r requirements/code_execution.txt
asttokens==3.0.1
# via stack-data
blinker==1.9.0
# via flask
click==8.3.1
# via flask
decorator==5.2.1
# via ipython
exceptiongroup==1.3.1
# via ipython
executing==2.2.1
# via stack-data
flask==3.1.2
# via -r requirements/code_execution.txt
gunicorn==25.0.3
# via -r requirements/code_execution.txt
h5py==3.15.1
# via -r requirements/code_execution.txt
ipython==8.38.0
# via -r requirements/code_execution.txt
itsdangerous==2.2.0
# via flask
jedi==0.19.2
# via ipython
jinja2==3.1.6
# via flask
markupsafe==3.0.3
# via
# flask
# jinja2
# werkzeug
matplotlib-inline==0.2.1
# via ipython
mpmath==1.3.0
# via sympy
numpy==2.2.6
# via
# -r requirements/code_execution.txt
# h5py
# pandas
# scipy
packaging==26.0
# via gunicorn
pandas==2.3.3
# via -r requirements/code_execution.txt
parso==0.8.6
# via jedi
pexpect==4.9.0
# via ipython
prompt-toolkit==3.0.52
# via ipython
psutil==7.2.2
# via -r requirements/code_execution.txt
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.3
# via stack-data
pygments==2.19.2
# via ipython
python-dateutil==2.9.0.post0
# via pandas
pytz==2025.2
# via pandas
scipy==1.15.3
# via -r requirements/code_execution.txt
six==1.17.0
# via python-dateutil
stack-data==0.6.3
# via ipython
sympy==1.14.0
# via -r requirements/code_execution.txt
tqdm==4.67.3
# via -r requirements/code_execution.txt
traitlets==5.14.3
# via
# ipython
# matplotlib-inline
typing-extensions==4.15.0
# via
# exceptiongroup
# ipython
tzdata==2025.3
# via pandas
wcwidth==0.6.0
# via prompt-toolkit
werkzeug==3.1.5
# via flask
Loading
Loading