This guide shows how to run claude-code in a Podman container while preserving your configuration and working directory access.
Clone the repository and run the setup script to build the container and optionally create a YOLO command:
git clone https://github.com/con/yolo
cd yolo
./setup-yolo.shThis will:
- Build the container image if it doesn't exist
- Optionally create a
YOLOshell function - Configure everything for you
After setup, just run yolo from any directory to start Claude Code in YOLO mode!
By default, yolo preserves your original host paths to ensure session compatibility with native Claude Code. This means:
- Your
~/.claudedirectory is mounted at its original path - Your current directory is mounted at its original path (not
/workspace) - Sessions created in the container can be resumed in your native environment and vice versa
If you prefer the old behavior with anonymized paths (/claude and /workspace), use the --anonymized-paths flag:
yolo --anonymized-pathsWhen running in a git worktree, yolo can detect and optionally bind mount the original repository. This allows Claude to access git objects and perform operations like commit and fetch. Control this behavior with the --worktree option:
--worktree=ask(default): Prompts whether to bind mount the original repo--worktree=bind: Automatically bind mounts the original repo--worktree=skip: Skip bind mounting and continue normally--worktree=error: Exit with error if running in a worktree
# Prompt for bind mount decision (default)
yolo
# Always bind mount in worktrees
yolo --worktree=bind
# Skip bind mounting, continue normally
yolo --worktree=skip
# Disallow running in worktrees
yolo --worktree=errorSecurity note: Bind mounting the original repo exposes more files and allows modifications. The prompt helps prevent unintended access.
TODO: Add curl-based one-liner setup once this PR is merged
On your first run, you'll need to authenticate:
- Claude Code will display a URL like
https://claude.ai/oauth/authorize?... - Copy the URL and paste it into a browser on your host machine
- Complete the authentication in your browser
- Copy the code from the browser and paste it back into the container terminal
Your credentials are stored in ~/.claude on your host, so you only need to login once. Subsequent runs will use the stored credentials automatically.
If you prefer to run commands manually, first build the image from the images/ directory:
podman build --build-arg TZ=$(timedatectl show --property=Timezone --value) -t con-bomination-claude-code images/Then run (with original host paths preserved by default):
podman run -it --rm \
--userns=keep-id \
-v "$HOME/.claude:$HOME/.claude:Z" \
-v ~/.gitconfig:/tmp/.gitconfig:ro,Z \
-v "$(pwd):$(pwd):Z" \
-w "$(pwd)" \
-e CLAUDE_CONFIG_DIR="$HOME/.claude" \
-e GIT_CONFIG_GLOBAL=/tmp/.gitconfig \
con-bomination-claude-code \
claude --dangerously-skip-permissionsOr with anonymized paths (old behavior):
podman run -it --rm \
--userns=keep-id \
-v ~/.claude:/claude:Z \
-v ~/.gitconfig:/tmp/.gitconfig:ro,Z \
-v "$(pwd):/workspace:Z" \
-w /workspace \
-e CLAUDE_CONFIG_DIR=/claude \
-e GIT_CONFIG_GLOBAL=/tmp/.gitconfig \
con-bomination-claude-code \
claude --dangerously-skip-permissions--dangerously-skip-permissions to bypass all permission prompts. This is safe in containerized environments where the container provides isolation from your host system.
The Dockerfile is based on Anthropic's official setup and includes Claude Code CLI plus common development tools. See the Dockerfile for the complete list.
--userns=keep-id: Maps your host user ID inside the container so files are owned correctly-v "$HOME/.claude:$HOME/.claude:Z": Bind mounts your Claude configuration directory at its original path with SELinux relabeling-v ~/.gitconfig:/tmp/.gitconfig:ro,Z: Mounts git config read-only for commits (push operations not supported)-v "$(pwd):$(pwd):Z": Bind mounts your current working directory at its original path-w "$(pwd)": Sets the working directory inside the container to match your host path-e CLAUDE_CONFIG_DIR="$HOME/.claude": Tells Claude Code where to find its configuration (at original path)-e GIT_CONFIG_GLOBAL=/tmp/.gitconfig: Points git to the mounted configclaude --dangerously-skip-permissions: Skips all permission prompts (safe in containers)--rm: Automatically removes the container when it exits-it: Interactive terminal
This default behavior ensures that session histories and project paths are compatible between containerized and native Claude Code environments.
When using --anonymized-paths, paths are mapped to generic container locations:
-v ~/.claude:/claude:Z: Mounts to/claudein container-v "$(pwd):/workspace:Z": Mounts to/workspacein container-w /workspace: Working directory is/workspace-e CLAUDE_CONFIG_DIR=/claude: Config directory is/claude
-
Persist configuration: The
~/.claudebind mount ensures your settings, API keys, and session history persist between container runs -
Session compatibility: By default, paths are preserved to match your host environment. This means:
- Sessions created in the container can be resumed outside the container using
claude --continuein your native environment - Each project maintains its own session history based on its actual path (e.g.,
/home/user/project) - You can seamlessly switch between containerized and native Claude Code for the same project
Note: With
--anonymized-paths, all projects appear to be in/workspace, which allowsclaude --continueto retain context across different projects that were also run with this flag. This can be useful for maintaining conversation context when working on related codebases. - Sessions created in the container can be resumed outside the container using
-
File ownership: The
--userns=keep-idflag ensures files created or modified inside the container will be owned by your host user, regardless of your UID -
Git operations: Git config is mounted read-only, so Claude Code can read your identity and make commits. However, SSH keys are not mounted, so
git pushoperations will fail. You'll need to push from your host after Claude Code commits your changes. -
Multiple directories: Mount additional directories as needed:
yolo -v ~/projects:~/projects -v ~/data:~/data -- "help with this code"
Or with anonymized paths:
yolo --anonymized-paths -v ~/projects:/projects -v ~/data:/data -- "help with this code"
YOLO mode runs Claude Code with --dangerously-skip-permissions, providing unrestricted command execution within the container. The container provides isolation through:
- Filesystem boundaries: Only
~/.claude,~/.gitconfig, and your current working directory are accessible to Claude - Process isolation: Rootless podman user namespace isolation (
--userns=keep-id) - Limited host access: SSH keys and other sensitive files are not mounted
What is NOT restricted:
- Network access: Claude can make arbitrary network connections from within the container (to package registries, APIs, external services, etc.)
When to be cautious:
- Untrusted repositories: Malicious code comments or documentation could exploit prompt injection to trick Claude into executing harmful commands or exfiltrating data
- Mounting directories with sensitive data (credentials, private keys, confidential files)
- Projects that access production systems or databases
For higher security needs, consider running untrusted code in a separate container without mounting sensitive directories, or wait for integration with Anthropic's modern sandbox runtime which provides network-level restrictions.