This guide explains what container images need to work with Clauderon. Requirements are derived from Clauderon's codebase behavior, not assumptions or preferences.
Your image MUST have:
claudeORcodexexecutable in PATHbashshell (not just/bin/sh)- Writable
/workspacedirectory curlbinary- Standard Unix utilities:
mkdir,chmod,cat,date
Strongly recommended:
gitCLI (for git operations from within sessions)
Everything else (dev tools, shell preferences, package managers) is your choice.
Understanding what Clauderon does helps explain why these requirements exist:
- Creates a Docker container or Kubernetes pod
- Runs
claude(orcodex) as the main command, wrapped in a shell script - Sets
HOME=/workspaceand mounts your session's git worktree there - Mounts cache volumes for Rust builds (
/workspace/.cargo/,/workspace/.cache/sccache/) - Mounts configuration files to
/etc/clauderon/(proxy CA cert, Codex/Talos configs) - Installs Claude Code hooks that report events back to the host via HTTP
- Sets environment variables for proxy, git config, and credential placeholders
- Uses
--user $(id -u):$(id -g)so files have correct ownership
These are hard requirements - without them, Clauderon sessions won't work.
Why: Clauderon runs this as the container's main command.
Source: src/backends/docker.rs, src/backends/kubernetes.rs
What to do: Install the Claude Code CLI or Codex CLI and ensure it's in PATH (typically /usr/local/bin/claude or /usr/local/bin/codex).
Why: The hooks system requires bash specifically, not just /bin/sh.
Details:
- Hooks run via
bash -c '/workspace/.clauderon/hooks/send_status.sh <event>' - The hook script uses bash-isms like
set -euo pipefail(pipefail is not in POSIX sh) - Hook installation uses bash for heredoc file writing
Source: src/hooks/installer.rs (hook invocation at line 12, shebang at line 64, pipefail at line 75)
Important: Images with only /bin/sh (like Alpine Linux without bash) won't work. If using Alpine, you must apk add bash.
Why: Clauderon sets HOME=/workspace, and Claude/Codex need to write configuration, history, and cache files.
Source: Environment variables in all backends
What Clauderon writes:
/workspace/.claude/- Claude Code config and session history/workspace/.codex/- Codex session data/workspace/.cargo/,/workspace/.cache/sccache/- Rust build caches/workspace/.clauderon/hooks/- Hook scripts
Why: The hooks system uses curl to POST events back to the Clauderon daemon on the host.
Source: src/hooks/installer.rs (send_status.sh script uses curl at lines 98-104)
Usage: curl -s -X POST -H "Content-Type: application/json" -d "$MESSAGE" "http://host.docker.internal:${CLAUDERON_HTTP_PORT}/api/hooks"
Why: Hook installation and script execution need these.
Required utilities:
mkdir- Create directories (hook installation)chmod- Make scripts executable (hook installation)cat- Write files via heredoc (hook script)date- Timestamp generation with-uflag (hook script)
Source: src/hooks/installer.rs (mkdir around line 128, chmod around line 175), hook script (cat, date)
Note: These are present in all standard base images (Debian, Ubuntu, Alpine, etc.). Only the most minimal images might lack them.
Why: For git operations from within sessions (commit, push, branch, etc.).
Note: Clauderon creates git worktrees on the HOST, but you'll want git inside the container for actual development work.
If missing: Sessions will start fine, but git commands won't work inside the container.
These are common assumptions that are actually wrong. Clauderon handles these for you:
Don't: Create specific users or set UIDs in your Dockerfile.
Why: Clauderon uses --user $(id -u):$(id -g) to run the container as your host user, ensuring correct file ownership.
Don't: Configure host.docker.internal resolution or add host entries.
Why: Clauderon adds --add-host host.docker.internal:host-gateway automatically.
Don't: Set HTTP_PROXY, HTTPS_PROXY, or NO_PROXY in your image.
Why: Clauderon sets these environment variables dynamically based on proxy configuration.
Don't: Pre-create /workspace/.cargo/ or other cache directories.
Why: Clauderon mounts these as named volumes. Docker creates them automatically with appropriate permissions.
Clauderon has Rust-specific optimizations built-in, even if you don't use Rust.
- Sets
CARGO_HOME=/workspace/.cargo - Sets
RUSTC_WRAPPER=sccache - Sets
SCCACHE_DIR=/workspace/.cache/sccache - Mounts named volumes:
clauderon-cargo-registry,clauderon-cargo-git,clauderon-sccache - Checks if
sccacheexists (warns if missing, but continues)
Install these in your image:
- Rust toolchain (rustup, cargo, rustc)
sccachefor faster compilation- C/C++ compiler (gcc/clang) for native dependencies
- Ignore this entirely
- Cache volumes will still be mounted (harmlessly)
- sccache warnings can be safely ignored
Here's a minimal Dockerfile that meets all requirements:
FROM debian:bookworm-slim
# Install core requirements
RUN apt-get update && apt-get install -y \
bash \
ca-certificates \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# Install Claude Code CLI
# (Replace with your preferred installation method)
RUN curl -fsSL https://install.claude.ai/cli.sh | sh
# Set working directory
# Clauderon will mount the session worktree here
WORKDIR /workspace
# Default to bash
# Clauderon will override this with the claude/codex command
CMD ["/bin/bash"]Note: You don't need to create users, set HOME, or configure networking - Clauderon handles all that.
For more complete examples, see examples/.
Problem: Your image only has /bin/sh (common with Alpine Linux).
Solution: Install bash. For Alpine: RUN apk add bash
Problem: Claude CLI not installed or not in PATH.
Solution:
- Verify installation:
docker run --rm your-image:latest which claude - Ensure claude is in
/usr/local/bin/or another directory in PATH - Check that the binary is executable:
chmod +x /usr/local/bin/claude
Problem: Container user doesn't have write access.
Solution: This shouldn't happen - Clauderon uses --user $(id -u):$(id -g). If it does:
- Verify your image doesn't set a specific USER in the Dockerfile
- Check that
/workspaceisn't owned by a specific user in the image - Ensure the parent directory has appropriate permissions
Problem: Git not installed or parent .git directory not accessible.
Solution:
- Install git:
apt-get install gitorapk add git - Verify Clauderon mounted the parent
.gitdirectory correctly - Check git config:
git config --list
Problem: Tools don't respect the custom CA certificate.
Solution: Clauderon sets these environment variables:
SSL_CERT_FILE=/etc/clauderon/proxy-ca.pemNODE_EXTRA_CA_CERTS=/etc/clauderon/proxy-ca.pem(Node.js)REQUESTS_CA_BUNDLE=/etc/clauderon/proxy-ca.pem(Python)
Most tools respect these automatically. If a tool doesn't, configure it manually to trust $SSL_CERT_FILE.
Problem: Docker creates named volumes as root:root, causing permission warnings.
Solution: This is a Docker limitation. Options:
- Accept the warnings (recommended) - Clauderon will work fine, you'll just see warnings
- Add
sudoto your image and use it for cache writes (not recommended) - Use an init container to fix permissions (Kubernetes only)
Impact: Non-fatal. Rust compilation proceeds without caching (slower builds).
Solution:
- If building Rust: Install sccache:
cargo install sccache - If not building Rust: Ignore the warning
# Test that required binaries exist
docker run --rm your-image:latest bash -c "which claude && which bash && which curl && which git"
# Test Claude CLI
docker run --rm your-image:latest claude --version# Start Clauderon daemon
clauderon daemon --http-port 3030
# Create a session with your custom image
clauderon create \
--image your-image:latest \
--name test-session \
--repository /path/to/your/repo
# Verify session started
clauderon list
# Attach to the session
docker attach clauderon-test-session- Session creates without errors
- Can attach to session and get bash prompt
- Claude Code responds to prompts
- Git operations work (
git status,git log) - Can create files and directories in
/workspace - Environment variables are set (
echo $HOME,echo $CARGO_HOME) - Hooks are working (check Clauderon logs for hook events)
- Proxy works if enabled (test HTTPS requests)
Clauderon sets many environment variables. Your image doesn't need to set these - they're provided at runtime.
HOME=/workspace- Home directoryTERM=xterm-256color- Terminal typeLANG=en_US.UTF-8- Locale (if your image sets it)
CARGO_HOME=/workspace/.cargoRUSTC_WRAPPER=sccacheSCCACHE_DIR=/workspace/.cache/sccache
GIT_AUTHOR_NAME,GIT_COMMITTER_NAMEGIT_AUTHOR_EMAIL,GIT_COMMITTER_EMAIL
CODEX_HOME=/workspace/.codex
HTTP_PROXY=http://host.docker.internal:{port}HTTPS_PROXY=http://host.docker.internal:{port}NO_PROXY=localhost,127.0.0.1,host.docker.internalSSL_CERT_FILE=/etc/clauderon/proxy-ca.pemNODE_EXTRA_CA_CERTS=/etc/clauderon/proxy-ca.pemREQUESTS_CA_BUNDLE=/etc/clauderon/proxy-ca.pem
GH_TOKEN=clauderon-proxyGITHUB_TOKEN=clauderon-proxyCLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-clauderon-proxy-placeholderOPENAI_API_KEY=sk-openai-clauderon-proxy-placeholder(Codex)CODEX_API_KEY=sk-openai-clauderon-proxy-placeholder(Codex)
CLAUDERON_SESSION_ID={uuid}- Session ID for hook communicationCLAUDERON_HTTP_PORT={port}- HTTP port for hook communication
TALOSCONFIG=/etc/clauderon/talos/config
Clauderon mounts these volumes automatically. Don't pre-create them in your image.
/workspace- Your session's git worktree (read-write)/workspace/.claude.json- Claude Code configuration (read-write)- Parent
.gitdirectory - Mounted at same absolute path as host (read-write)
/workspace/.cargo/registry- Rust crate downloads (named volume:clauderon-cargo-registry)/workspace/.cargo/git- Rust git dependencies (named volume:clauderon-cargo-git)/workspace/.cache/sccache- Compilation cache (named volume:clauderon-sccache)
/etc/clauderon/proxy-ca.pem- Proxy CA certificate/etc/clauderon/codex/- Codex configuration directory/etc/clauderon/codex/auth.json- Codex authentication/etc/clauderon/codex/config.toml- Codex config/etc/clauderon/talos/- Talos configuration directory/etc/clauderon/talos/config- Talos config file/etc/claude-code/managed-settings.json- Claude Code managed settings (proxy mode only)
Named volumes may be created by Docker as root:root. Your image should handle both root-owned and user-owned volumes gracefully. Most images do this by default.
The default Clauderon image is ghcr.io/shepherdjerred/dotfiles.
It includes:
- All required dependencies (claude, bash, curl, git)
- Rust toolchain with sccache
- Development tools (Node.js, Python, Go via mise)
- Modern shell (Fish)
- Size optimizations (multi-stage build, debug symbol stripping)
This is a full-featured development image. You don't need all these features - just the core requirements listed in the TL;DR.
Found an issue with this guide or have suggestions? Please open an issue on the Clauderon repository.