Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
146 changes: 146 additions & 0 deletions agents/claude/claude_agent/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Claude Code Container for Red Hat OpenShift AI
#
# A customer-facing container image for running Claude Code on RHOAI.
# Defaults to headless (non-interactive) mode for programmatic use.
# Interactive mode available by overriding CMD at runtime.
#
# Features:
# - UBI 10 minimal base (RHEL-compatible, supported)
# - Claude Code installed via npm (version-pinned)
# - Non-root user compatible with restricted-v2 SCC
# - Configurable API endpoint (Anthropic, vLLM, OGX)
# - Skills injectable at runtime via ConfigMap/PVC mount
# - MCP configuration injectable at runtime via environment variables:
# MCP_CONFIG_FILE - path to mounted JSON config file
# MCP_CONFIG_JSON - inline JSON string with MCP server definitions
#
# Build:
# podman build -t claude-code:latest -f Containerfile .
#
# Build with specific version:
# podman build --build-arg CLAUDE_CODE_VERSION=2.1.123 -t claude-code:2.1.123 .

FROM registry.access.redhat.com/ubi10/ubi-minimal:10.1

LABEL name="claude-code" \
vendor="Red Hat" \
summary="Claude Code agent for OpenShift AI" \
description="Container image for running Anthropic's Claude Code CLI on Red Hat OpenShift AI"

# =============================================================================
# Build Arguments
# =============================================================================

# Claude Code version to install (pinned for reproducibility)
ARG CLAUDE_CODE_VERSION=2.1.123

# User configuration
ARG USER_NAME=claude-agent
ARG USER_UID=1001
ARG USER_GID=0

# =============================================================================
# Install System Dependencies
# =============================================================================

# Install Node.js and minimal utilities
# - nodejs: Required for Claude Code (npm package)
# - npm: Package manager for installing Claude Code
# - git: Version control (agent may need to clone repos)
# - curl: HTTP client (agent may need to fetch resources)
# - jq: JSON processor (useful for scripting)
RUN microdnf install -y --nodocs \
nodejs \
npm \
git \
curl \
jq \
&& microdnf clean all \
&& rm -rf /var/cache/yum

# =============================================================================
# Create Non-Root User
# =============================================================================

# Create user with specific UID for OpenShift compatibility
# GID=0 (root group) is required for OpenShift's random UID assignment.
# OpenShift runs containers with a random UID that is a member of GID 0.
# Directories below use chmod 775 so GID 0 members have write access.
RUN useradd -u ${USER_UID} -g ${USER_GID} -d /home/${USER_NAME} -m -s /bin/bash ${USER_NAME}

# =============================================================================
# Install Claude Code
# =============================================================================

# Install Claude Code globally with pinned version
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION} \
&& npm cache clean --force

# Verify installation
RUN claude --version

# =============================================================================
# Create Directory Structure
# =============================================================================

# Skills directory - empty, mountable via ConfigMap/PVC
# Customers inject their skills here at deploy time
# Each skill should be a subdirectory containing a SKILL.md file
#
# Mount at runtime:
# podman run -v /path/to/skills:/opt/skills:ro,z ...
# Or in OpenShift, mount a ConfigMap or PVC to /opt/skills
RUN mkdir -p /opt/skills \
&& chown -R ${USER_UID}:${USER_GID} /opt/skills \
&& chmod -R 775 /opt/skills

# Workspace directory - for agent working files
# Can be mounted with PVC for persistence
RUN mkdir -p /workspace \
&& chown -R ${USER_UID}:${USER_GID} /workspace \
&& chmod -R 775 /workspace

# Claude config directory
RUN mkdir -p /home/${USER_NAME}/.claude \
&& chown -R ${USER_UID}:${USER_GID} /home/${USER_NAME}/.claude \
&& chmod -R 775 /home/${USER_NAME}/.claude

# Ensure home directory has correct permissions for OpenShift random UID
RUN chown -R ${USER_UID}:${USER_GID} /home/${USER_NAME} \
&& chmod -R 775 /home/${USER_NAME}

# =============================================================================
# Copy Entrypoint
# =============================================================================

COPY --chmod=755 entrypoint.sh /usr/local/bin/entrypoint.sh

# =============================================================================
# Environment Configuration
# =============================================================================

# Disable Claude Code auto-updater (we control versions via image builds)
ENV DISABLE_AUTOUPDATER=1

# Default working directory
WORKDIR /workspace

# =============================================================================
# Runtime Configuration
# =============================================================================

# Switch to non-root user
USER ${USER_UID}

# Expose no ports by default (Claude Code is CLI-based)
# If a gateway/API layer is added later, ports can be exposed

# Entrypoint handles environment setup and runs Claude Code
ENTRYPOINT ["entrypoint.sh"]

# Default command - can be overridden at runtime
# This runs Claude in print (non-interactive) mode with stream-json for programmatic interaction
#
# For interactive mode, override the CMD at runtime:
# podman run -it --rm ... claude-code:latest claude
CMD ["claude", "--print", "--output-format", "stream-json", "--input-format", "stream-json"]
Loading
Loading