Skip to content
Open
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
52 changes: 35 additions & 17 deletions components/runners/claude-code-runner/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Build context must be: components/runners/
# Example: docker build -f claude-code-runner/Dockerfile -t vteam_claude_runner .
FROM python:3.11-slim

# Install system dependencies
# Install system dependencies including uv
RUN apt-get update && apt-get install -y \
git \
curl \
Expand All @@ -10,19 +12,8 @@ RUN apt-get update && apt-get install -y \
&& npm install -g @anthropic-ai/claude-code \
&& rm -rf /var/lib/apt/lists/*

# Create working directory
WORKDIR /app

# Copy and install runner-shell package (expects build context at components/runners)
COPY runner-shell /app/runner-shell
RUN cd /app/runner-shell && pip install --no-cache-dir .

# Copy claude-runner specific files
COPY claude-code-runner /app/claude-runner

# Install runner wrapper as a package (pulls dependencies like claude-agent-sdk)
RUN pip install --no-cache-dir /app/claude-runner \
&& pip install --no-cache-dir aiofiles
# Install uv from official container image (recommended method)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

# Set environment variables
ENV PYTHONUNBUFFERED=1
Expand All @@ -31,9 +22,36 @@ ENV RUNNER_TYPE=claude
ENV HOME=/app
ENV SHELL=/bin/bash
ENV TERM=xterm-256color
# UV_SYSTEM_PYTHON=1: Allow uv to use system Python instead of managing its own
ENV UV_SYSTEM_PYTHON=1

# Create working directory
WORKDIR /app

# Copy runner-shell package first (shared infrastructure layer)
COPY runner-shell /app/runner-shell

# Install runner-shell using uv pip install (installed globally in system Python)
# This provides the base runner framework used by wrapper.py
RUN cd /app/runner-shell && uv pip install --no-cache .

# Copy dependency files first for better layer caching
# Changes to these files are infrequent, so this layer will be cached
COPY claude-code-runner/pyproject.toml claude-code-runner/uv.lock /app/claude-runner/

# Install claude-runner dependencies using uv.lock
# --frozen: Fail if lock file is out of sync with pyproject.toml (ensures reproducibility)
# --no-dev: Skip development dependencies for smaller production image
# Creates a virtual environment at /app/claude-runner/.venv with exact dependency versions
RUN cd /app/claude-runner && uv sync --frozen --no-dev

# Copy application code (changes frequently, so placed after dependency installation)
COPY claude-code-runner/wrapper.py /app/claude-runner/

# OpenShift compatibility
# OpenShift compatibility: Set group permissions equal to owner for arbitrary user IDs
RUN chmod -R g=u /app && chmod -R g=u /usr/local && chmod g=u /etc/passwd

# Default command - run via runner-shell
CMD ["python", "/app/claude-runner/wrapper.py"]
# Use 'uv run' to execute wrapper.py in the project's virtual environment
# --frozen: Use exact dependencies from uv.lock without checking for updates
# This ensures wrapper.py has access to claude-agent-sdk and other project dependencies
CMD ["uv", "run", "--frozen", "/app/claude-runner/wrapper.py"]
1 change: 0 additions & 1 deletion components/runners/claude-code-runner/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
name = "claude-code-runner"
version = "0.1.0"
description = "Runner that streams via Claude Code SDK and syncs workspace via PVC proxy"
readme = "CLAUDE.md"
requires-python = ">=3.11"
authors = [
{ name = "vTeam" }
Expand Down
Loading
Loading