Running Claude Code in Docker#
The claude.sh script runs Claude Code
inside a Docker container with --dangerously-skip-permissions. The container
provides a sandboxed environment where Claude Code has full shell access but
cannot affect the host system beyond the mounted repository.
The container supports:
Building and testing OpenROAD with CMake and Bazel
Running ORFS flows (Makefile-based RTL-GDSII)
All file changes reflected on the host via volume mount
Prerequisites#
Docker installed on your machine
Claude Code credentials (run
claudeon the host once to authenticate, or setANTHROPIC_API_KEYin your environment)
Quick start#
./claude.sh
On first run the Docker image is built automatically. Credentials from
~/.claude/ are mounted into the container. The ORFS environment (env.sh)
is sourced automatically so tools are on PATH without any manual setup.
Usage#
./claude.sh [OPTIONS] [-- CLAUDE_ARGS...]
Options#
Option |
Description |
|---|---|
|
Force rebuild the Docker image |
|
Start a bash shell instead of Claude Code |
|
Override Docker image (default: |
|
Override container name (default: |
|
Show help |
Arguments after -- are passed directly to claude.
Examples#
# Interactive Claude Code session
./claude.sh
# Pass a prompt to Claude Code
./claude.sh -- -p "fix the failing test in src/drt"
# Interactive bash shell (for manual builds)
./claude.sh --shell
# Force rebuild the image after updates
./claude.sh --build
# Run a parallel session
CONTAINER_NAME=claude-2 ./claude.sh
Building and testing inside the container#
When using --shell, tools are already on PATH:
# CMake build
./build_openroad.sh --local --no_init -t $(nproc)
# Bazel build
cd tools/OpenROAD && bazel build //...
# Run an ORFS flow
cd flow && make DESIGN_CONFIG=./designs/nangate45/gcd/config.mk
Claude Code can run these same commands autonomously during an interactive session.
What persists across runs#
The container is removed on exit (--rm), but the following host directories
are mounted so their contents survive:
Host path |
Container path |
Content |
|---|---|---|
Repository root |
|
All source and build artifacts |
|
|
Credentials, settings, conversation history |
|
|
Bazel external dependencies |
|
|
Git identity (read-only) |
|
forwarded |
SSH agent for git over SSH |
Environment variables#
All environment variables are optional. They are passed into the container when set on the host.
Variable |
Purpose |
|---|---|
|
API key (alternative to stored credentials) |
|
Model override |
|
Docker image override (same as |
|
Container name override (same as |
|
Host path for Bazel cache (default: |
|
Use AWS Bedrock |
|
AWS credentials for Bedrock |
How it works#
The setup consists of three files:
docker/Dockerfile.claude#
Extends the openroad/flow-ubuntu22.04-dev base image (which has all
OpenROAD build dependencies) with:
Java 21 and Bazelisk (for Bazel 8.x builds)
Node.js 22 LTS and Claude Code CLI
VS Code CLI, sudo, and other convenience tools
No source code is copied into the image. Everything comes from the volume mount.
docker/claude-entrypoint.sh#
Handles UID/GID mapping so files created inside the container have the correct ownership on the host. The entrypoint:
Creates a user matching the host UID/GID
Sources
env.shto set up tool pathsDrops privileges via
setprivbefore running the command
This follows the same pattern as tools/OpenROAD/etc/docker-entrypoint.sh
and the --user mode in flow/util/docker_shell.
claude.sh#
Wrapper script that assembles the docker run command with the correct
volume mounts, environment variables, and entrypoint arguments.
Security model#
Claude Code runs with --dangerously-skip-permissions inside the
container, meaning it can execute any shell command without confirmation.
The Docker container provides the isolation:
File access is limited to the mounted repository
No access to host system packages, services, or other projects
No access to host network services bound to localhost
docker kill claude-orfsstops everything instantly
Warning
The container has network access (required for the Anthropic API and Bazel dependency fetching). Claude Code could in principle make outbound network requests. If this is a concern, use Docker network policies to restrict egress to only the Anthropic API endpoints.