mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-11-11 09:36:42 +08:00
Closes #44 ## Summary - Add `nav sandbox image push --dockerfile <path>` command to build and push custom container images into the cluster - Fix sandbox Docker build failure caused by OpenClaw installer TTY access - Fix sandbox proxy crash when network namespace is unavailable (fall back to loopback) - Add e2e test for the full custom image build and sandbox creation flow - Rename and rewrite BYOC architecture doc to reflect current state ## Changes ### `navigator-bootstrap` - New `build` module (`src/build.rs`) with `build_and_push_image()` public API - Builds via bollard `Docker::build_image()`, streams output to caller - `.dockerignore` support with glob matching, 8 unit tests ### `navigator-cli` - Added `SandboxImageCommands::Push` subcommand with `--dockerfile`, `--tag`, `--context`, `--build-arg` flags - Added `test:e2e:custom-image` mise task ### `navigator-sandbox` - Proxy now falls back to `127.0.0.1:3128` when no network namespace or explicit bind address is available, instead of erroring out ### Docker / Infra - Sandbox Dockerfile: replaced OpenClaw native installer (`curl | bash`) with `npm install -g openclaw` to avoid `/dev/tty` failures in Docker build ### Documentation - Renamed `architecture/sandbox-byoc.md` to `sandbox-custom-containers.md` - Rewrote doc to describe current behavior (CLI usage, push pipeline, supervisor behavior, design decisions) instead of listing implementation changes ### Tests - Added `e2e/bash/test_sandbox_custom_image.sh` covering image push + sandbox create with custom image
121 lines
4.5 KiB
Docker
121 lines
4.5 KiB
Docker
# syntax=docker/dockerfile:1.4
|
|
# Supervisor container for navigator
|
|
# Multi-stage build with cross-compilation support for multi-arch
|
|
|
|
# Stage 1: Rust builder (runs on build platform, cross-compiles for target)
|
|
FROM --platform=$BUILDPLATFORM rust:1.88-slim AS rust-builder
|
|
ARG RUST_BUILD_PROFILE=debug
|
|
ARG TARGETARCH
|
|
ARG BUILDARCH
|
|
|
|
# Install build dependencies
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
cmake g++ make protobuf-compiler && rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install cross-compilation toolchain + Rust target (no-ops for native builds)
|
|
COPY deploy/docker/cross-build.sh /usr/local/bin/
|
|
RUN . cross-build.sh && install_cross_toolchain && add_rust_target
|
|
|
|
WORKDIR /build
|
|
COPY Cargo.toml Cargo.lock ./
|
|
COPY crates/ crates/
|
|
COPY proto/ proto/
|
|
COPY dev-sandbox-policy.rego ./
|
|
|
|
# Build with cross-compilation support.
|
|
# Cache mounts are keyed by TARGETARCH so parallel multi-platform builds
|
|
# don't corrupt each other's cargo registry or build artifacts.
|
|
RUN --mount=type=cache,id=cargo-registry-sandbox-${TARGETARCH},sharing=locked,target=/usr/local/cargo/registry \
|
|
--mount=type=cache,id=cargo-target-sandbox-${TARGETARCH},sharing=locked,target=/build/target \
|
|
. cross-build.sh && \
|
|
if [ "$RUST_BUILD_PROFILE" = "release" ]; then \
|
|
cargo_cross_build --release -p navigator-sandbox; \
|
|
else \
|
|
cargo_cross_build -p navigator-sandbox; \
|
|
fi && \
|
|
mkdir -p /build/out && \
|
|
cp "$(cross_output_dir "$RUST_BUILD_PROFILE")/navigator-sandbox" /build/out/
|
|
|
|
# Stage 2: Python base (uses target platform)
|
|
FROM python:3.12-slim AS base
|
|
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1
|
|
|
|
WORKDIR /sandbox
|
|
|
|
# Install system dependencies
|
|
# iproute2 is needed for network namespace management (ip netns, veth pairs)
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl dnsutils iproute2 iputils-ping \
|
|
net-tools netcat-openbsd traceroute \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create supervisor and sandbox users/groups
|
|
RUN groupadd -r supervisor && useradd -r -g supervisor -s /usr/sbin/nologin supervisor && \
|
|
groupadd -r sandbox && useradd -r -g sandbox -s /usr/sbin/nologin sandbox
|
|
|
|
# Stage 3: Python dependencies builder
|
|
FROM base AS builder
|
|
|
|
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
|
|
# Copy project files for dependency resolution
|
|
COPY pyproject.toml uv.lock ./
|
|
|
|
# Install dependencies into a virtual environment
|
|
RUN uv venv /app/.venv && \
|
|
uv sync --frozen --no-dev --no-install-project 2>/dev/null || \
|
|
uv sync --no-dev --no-install-project 2>/dev/null || true
|
|
|
|
# Install navigator SDK dependencies
|
|
RUN uv pip install --python /app/.venv/bin/python --no-cache-dir cloudpickle grpcio protobuf
|
|
|
|
# Stage 4: Coding agents layer
|
|
FROM base AS coding-agents
|
|
|
|
# Install Node.js 22 via NodeSource (required by OpenClaw and other agents)
|
|
# build-essential & python3 are needed for npm packages with native addons (node-gyp)
|
|
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
|
|
apt-get install -y --no-install-recommends git nodejs build-essential python3 && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install Claude CLI via native installer (npm method is deprecated)
|
|
RUN curl -fsSL https://claude.ai/install.sh | bash \
|
|
&& cp /root/.local/bin/claude /usr/local/bin/claude \
|
|
&& chmod 755 /usr/local/bin/claude
|
|
|
|
# Install OpenClaw CLI via npm (the native installer uses npm under the hood;
|
|
# installing directly avoids TTY and onboarding issues in Docker builds)
|
|
RUN npm install -g openclaw
|
|
|
|
# Install OpenCode CLI and Codex CLI (OpenAI)
|
|
RUN npm install -g opencode-ai @openai/codex
|
|
|
|
# Stage 5: Final image
|
|
FROM coding-agents AS final
|
|
ARG RUST_BUILD_PROFILE=debug
|
|
|
|
COPY --from=builder /app/.venv /app/.venv
|
|
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
|
|
COPY --from=rust-builder /build/out/navigator-sandbox /usr/local/bin/
|
|
|
|
# Copy navigator Python SDK into the virtual environment
|
|
COPY python/navigator/ /app/.venv/lib/python3.12/site-packages/navigator/
|
|
|
|
# Add venv to PATH
|
|
ENV PATH="/app/.venv/bin:$PATH"
|
|
|
|
RUN mkdir -p /var/navigator /sandbox /var/log && \
|
|
touch /var/log/navigator.log && \
|
|
chown supervisor:supervisor /var/log/navigator.log && \
|
|
chmod 0664 /var/log/navigator.log && \
|
|
chown sandbox:sandbox /sandbox
|
|
|
|
# OpenClaw startup helper for environments without systemd (e.g. sandboxes).
|
|
# Usage: nav sandbox create --forward 18789 -- openclaw-start
|
|
COPY deploy/docker/openclaw-start.sh /usr/local/bin/openclaw-start
|
|
RUN chmod +x /usr/local/bin/openclaw-start
|
|
|
|
ENTRYPOINT ["navigator-sandbox"]
|