Sandbox
@CoderLuii/HolyClaude

Docker workstation for Claude Code and AI CLIs

HolyClaude packages an AI coding workstation into a Docker image and Compose setup. It brings together Claude Code, a browser UI, Chromium, Playwright, and multiple AI CLIs so you can work from one container instead of wiring the stack yourself.

2,560 starsβ€’270 forksβ€’JavaScriptβ€’Updated 8d ago
Who it's for

Builders who want a ready-made terminal and browser workstation for Claude Code, Codex, Gemini CLI, and similar tools.

What it delivers

You can start agent-led coding in a single command instead of assembling and debugging the workstation yourself.

What it does

Claude Code in a container

Runs the official Claude Code CLI with persistence for settings, credentials, and memory under `/home/claude/.claude`.

Web UI and browser access

Includes CloudCLI web UI plus Chromium, Xvfb, and Playwright for browser-based agent work and screenshots.

Multiple AI CLIs

Bundles several CLIs in one image, including Codex, Gemini CLI, Cursor, TaskMaster AI, Junie, OpenCode, and Pi Coding Agent.

Full and slim images

Offers a full image with everything preinstalled and a slimmer image that installs missing tools on demand.

Compose templates and rootless support

Provides quick and full Docker Compose files, plus a Podman rootless compose file for alternate setups.

Persistence and permissions handling

Includes mounted workspace and Claude state, along with user mapping, SMB polling, and startup scripts for container file handling.

How to get it

  1. 11. Create a folder for HolyClaude
    mkdir holyclaude && cd holyclaude
  2. 23. Pull and start
    docker compose up -d
  3. 34. Open the web UI
    http://localhost:3001
  4. 4Run
    # Delete the sentinel file β€” NOT the whole folder
    rm ./data/claude/.holyclaude-bootstrapped
    docker compose restart holyclaude

README

🌍 English | EspaΓ±ol | FranΓ§ais | Italiano | PortuguΓͺs | Deutsch | Русский | ΰ€Ήΰ€Ώΰ€¨ΰ₯ΰ€¦ΰ₯€ | δΈ­ζ–‡ | ζ—₯本θͺž | ν•œκ΅­μ–΄

HolyClaude HolyClaude

HolyClaude Banner

License: MIT Docker Pulls Full Image Slim Image
GitHub Stars Twitter Follow PayPal Buy Me A Coffee Website GitHub Release Issues Contributors

Stop configuring. Start building.

One command. Full AI development workstation. Claude Code, web UI, headless browser, 8 AI CLIs, 50+ dev tools β€” containerized and ready.

You were going to spend 2 hours setting this up manually. Or you could just docker compose up.

Works with your existing Claude Code subscription. Max/Pro plan, API key β€” whatever you have, it just works.

[!TIP] Stop maintaining. Start building.

A hosted AI workstation. Always-on Linux box.

holycode.cloud


What is this?

You know the drill. You want Claude Code. But you also want it in a browser. With a headless browser for screenshots and testing. With Playwright configured. With every AI CLI. With TypeScript, Python, deployment tools, database clients, GitHub CLI.

v1.5.9 keeps the v1.5.8 workstation stack and corrects two configuration details. Tracked Markdown files now stay on LF line endings, and new or persisted Codex configurations use the current hooks feature flag without overwriting an existing setting.

Release-sensitive facts are also published in contracts/product-facts.json. The release workflow checks that contract against the Dockerfile and Compose files before building images.

So you start installing things. One by one. Then Chromium won't launch because Docker's shared memory is 64MB. Then Xvfb isn't configured. Then the UID inside the container doesn't match your host and everything is permission denied. Then you realize Claude Code's installer hangs when WORKDIR is root-owned. Then SQLite locks on your NAS mount. Thenβ€”

HolyClaude is the container I built after solving every single one of those problems.

I've been running this daily on my own server for weeks. Every bug has been hit, diagnosed, and fixed. Every edge case has been handled. Every "why doesn't this work in Docker" has been answered.

You pull it. You run it. You open your browser. You build.

:credit_card: Use Your Existing Subscription

This runs the real Claude Code CLI. Not a wrapper. Not a proxy. Not a knock-off.

Your existing Anthropic account works directly:

  • Claude Max/Pro plan β€” authenticate through the web UI (OAuth), same as desktop Claude Code
  • Anthropic API key β€” set it through the web UI, same billing as always
  • No extra cost β€” HolyClaude is free and open source. You only pay Anthropic for what you use, like you already do.

HolyClaude operates no credential relay. Bundled tools read credentials from container files, bind mounts, or environment variables, then contact the providers you configure directly.

↑ back to top


Table of Contents

Section
:zap:Quick Start
:computer:Platform Support
:star2:Why HolyClaude
:credit_card:Subscription & Authentication
:package:Image Variants
:whale:Docker Compose β€” Quick
:whale2:Docker Compose β€” Full
:wrench:Environment Variables
:rocket:What's Inside
:robot:AI CLI Providers
:mag:Desloppify
:llama:Using Ollama
:building_construction:Architecture
:file_folder:Project Structure
:floppy_disk:Data & Persistence
:lock:Permissions
:shield:Remote Access & Exposure
:bell:Notifications
:arrows_counterclockwise:Upgrading
:construction:Troubleshooting
:warning:Known Issues
:hammer_and_wrench:Building Locally
:bar_chart:Alternatives
:rocket:Roadmap
:trophy:Built with HolyClaude
:handshake:Contributing
:heart:Support
:scroll:Third-Party Software
:page_facing_up:License

↑ back to top


:zap: Quick Start

1. Create a folder for HolyClaude:

mkdir holyclaude && cd holyclaude

2. Create a docker-compose.yaml file. Copy one of the templates below:

3. Pull and start:

docker compose up -d

4. Open the web UI:

http://localhost:3001

5. Create a CloudCLI account (takes 10 seconds), sign in with your Anthropic account, and you're live.

No .env files. No pre-configuration. No reading 40 pages of docs before you can start. It just runs.

Want to reach it from outside your network? Don't port-forward it. See Remote Access & Exposure β€” use Tailscale or Cloudflare Tunnel instead.

↑ back to top


:computer: Platform Support

PlatformStatusNotes
Linux (amd64)βœ… Fully supportedNative performance, recommended
Linux (arm64)βœ… Fully supportedRaspberry Pi 4+, Oracle Cloud, AWS Graviton
macOS (Docker Desktop)βœ… Fully supportedApple Silicon & Intel via Docker Desktop
Windows (WSL2 + Docker Desktop)βœ… Fully supportedRequires WSL2 backend
Synology / QNAP NASβœ… Fully supportedUse CHOKIDAR_USEPOLLING=true for SMB mounts
KubernetesπŸ”œ Coming soonHelm chart planned

↑ back to top


:star2: Why HolyClaude

I built this because I was tired of re-doing the same setup every time. Installing Claude Code, wiring up a web UI, configuring Chromium in Docker, fixing permission issues, debugging process supervision. Every time.

So I made a container that does all of it. And then I hit every possible bug so you don't have to.

HolyClaudeDoing it yourself
Setup30 seconds1-2 hours (if it goes well)
Claude CodePre-installed, pre-configured, readyInstall, configure, debug installer hanging, fix WORKDIR
Web UICloudCLI included with pluginsFind a web UI, install it, configure it, wire it to Claude
Headless browserChromium + Xvfb + Playwright, configuredInstall Chromium, install Xvfb, configure display :99, fix shm, fix sandbox, fix seccomp...
AI CLIs8 providers, one containerInstall each one separately across 3 package managers
Dev tools50+ tools, readyapt-get install / npm i -g / pip install for the next hour
Process managements6-overlay (auto-restart, graceful shutdown)Write your own supervisord config or hope Docker restart works
PersistenceBind-mounted tool config and workspace survive rebuildsFigure out Docker volumes, debug "why is this a directory not a file"
Updatesdocker compose pull && docker compose up -dUpdate 50 tools manually, pray nothing breaks
Multi-archAMD64 + ARM64Pray your Dockerfile builds on ARM

The last row of every manual setup is "works on my machine." HolyClaude works on every machine.

↑ back to top


:credit_card: Subscription & Authentication

HolyClaude runs the official Claude Code CLI from Anthropic. Your existing account works out of the box.

What works:

Authentication methodHowCost
Claude Max/Pro plan (subscription)Sign in through CloudCLI web UI β€” same OAuth flow as desktopYour existing subscription, no extra charge
Anthropic API keyPaste your API key in the web UIPay-per-use, same Anthropic billing

What doesn't work:

Why
OpenAI API key for ClaudeDifferent company, different API. OpenAI keys work with the Codex CLI (also pre-installed)

ChatGPT Plus/Pro subscribers: Your subscription works with the Codex CLI. Run codex login --device-auth inside the container to authenticate with your ChatGPT account. If you need Codex's browser callback flow from your host, expose port 1455 in the full compose template below.

Other AI CLIs included:

CLIWhat you need
Gemini CLIGoogle AI API key (GEMINI_API_KEY)
OpenAI CodexOpenAI API key (OPENAI_API_KEY) or ChatGPT Plus/Pro subscription (codex login --device-auth)
CursorCursor API key (CURSOR_API_KEY)
TaskMaster AIUses your AI provider keys (Anthropic, OpenAI, etc.)
JunieJetBrains account (JetBrains AI subscription)
OpenCodeConfigure via opencode TUI (OpenRouter and other providers)
Pi Coding AgentConfigure through pi (supports multiple providers)

HolyClaude is free and open source. You only pay your AI providers for usage, same as you already do. HolyClaude does not relay provider credentials. Bundled tools read them from container files, bind mounts, or environment variables and contact providers directly.

↑ back to top


:package: Image Variants

Two flavors. Same quality. Pick your weight class.

TagWhat you getBest forDocker Hub compressed size
latestEverything pre-installed β€” every tool, every library, every CLIMost users. Zero wait time. Claude never has to stop and install something.~4.1 GB
slimCore tools only β€” Claude installs extras on-demandSmaller VPS, limited disk, metered bandwidth~2.4 GB
X.Y.ZFull image, pinned versionProduction stability β€” you control when to updateSame as latest for that release
X.Y.Z-slimSlim image, pinned versionProduction + small footprintSame as slim for that release
# Full β€” batteries included (recommended)
docker pull coderluii/holyclaude

# Slim β€” lean and mean
docker pull coderluii/holyclaude:slim

latest is always the full image. Slim users: don't worry β€” when you ask Claude to do something that needs a missing tool, it installs it in seconds. You get the same capabilities, just with a smaller initial download.

Docker Hub reports compressed transfer size. Docker, Synology Container Manager, and NAS filesystems can show a larger unpacked size after layers are extracted. That is expected; use slim when disk space or bandwidth matters more than having every tool ready on first boot.

↑ back to top


:whale: Docker Compose β€” Quick

The "I just want it running" template. Copy this entire block into a docker-compose.yaml file:

# ==============================================================================
# HolyClaude β€” Quick Start
# Just run: docker compose up -d
# Then open: http://localhost:3001
# ==============================================================================

services:
  holyclaude:
    image: coderluii/holyclaude:latest     # Full image (use :slim for smaller download)
    container_name: holyclaude
    hostname: holyclaude
    restart: unless-stopped
    shm_size: 2g                           # Retained browser default for this release
    network_mode: bridge
    cap_add:
      - SYS_ADMIN                          # Current browser profile for this release; hardening is separate
      - SYS_PTRACE                         # Debugging-related capability
    security_opt:
      - seccomp=unconfined                 # Current browser profile for this release; hardening is separate
    ports:
      - "127.0.0.1:3001:3001"              # CloudCLI web UI, localhost only
    volumes:
      #
      # ./data/claude β€” Your settings, credentials, API keys, and Claude's memory.
      #                  This is what survives container rebuilds.
      #                  NEVER delete this folder β€” your auth lives here.
      #
      - ./data/claude:/home/claude/.claude
      #
      # ./workspace β€” Your code. All projects go here.
      #               Bind-mounted so you can access files from your host.
      #
      - ./workspace:/workspace
    environment:
      - TZ=UTC                             # Your timezone (e.g., America/New_York, Europe/London)

Then:

docker compose up -d

Open http://localhost:3001. Create a CloudCLI account. Sign in with your Anthropic account. Build something.

That's the whole setup. You're done.

Why these browser caps? This release keeps HolyClaude's current browser container profile in place. Chromium does not universally require SYS_ADMIN, SYS_PTRACE, or seccomp=unconfined, and SYS_PTRACE is debugging-related. Keep the web UI bound to 127.0.0.1 unless you put a real private tunnel or access layer in front of it. Treat any hardening pass as a separate change.

Why shm_size: 2g? Docker gives containers 64MB of shared memory by default. HolyClaude keeps 2GB as the retained browser default for this release because Chromium uses /dev/shm heavily for tab rendering. At 64MB, tabs crash randomly. For heavy browser use (many tabs, complex pages), increase to 4GB.

↑ back to top


:whale2: Docker Compose β€” Full

Same image, every knob exposed. Copy this entire block into a docker-compose.yaml file:

# ==============================================================================
# HolyClaude β€” Full Configuration
# All options documented inline.
# Detailed docs: https://github.com/CoderLuii/HolyClaude/blob/master/docs/configuration.md
# ==============================================================================

services:
  holyclaude:
    image: coderluii/holyclaude:latest     # Full image (use :slim for smaller download)
    container_name: holyclaude
    hostname: holyclaude
    restart: unless-stopped
    shm_size: 2g                           # Chromium shared memory β€” increase to 4g for heavy browser use
    network_mode: bridge
    cap_add:
      - SYS_ADMIN                          # Current browser profile for this release; hardening is separate
      - SYS_PTRACE                         # Debugging-related capability (strace, lsof)
    security_opt:
      - seccomp=unconfined                 # Current browser profile for this release; hardening is separate
    ports:
      #
      # CloudCLI web UI β€” this is the only port you need.
      # Override the host-side port from `.env` if 3001 is already in use.
      #
      - "127.0.0.1:${HOLYCLAUDE_HOST_PORT:-3001}:3001"
      #
      # Dev server ports β€” uncomment as needed.
      # These let you access dev servers running inside the container from your host browser.
      #
      # - "127.0.0.1:3000:3000"            # Next.js / Express
      # - "127.0.0.1:4321:4321"            # Astro
      # - "127.0.0.1:5173:5173"            # Vite
      # - "127.0.0.1:8787:8787"            # Wrangler (Cloudflare Workers)
      # - "127.0.0.1:9229:9229"            # Node.js debugger
      # - "127.0.0.1:1455:1455"            # Codex auth callback port
      # - "127.0.0.1:2222:22"              # Optional SSH, localhost/VPN only
      # - "127.0.0.1:60000-60010:60000-60010/udp"  # Optional Mosh UDP range
    volumes:
      #
      # PERSISTENT DATA
      #
      # ./data/claude β€” Settings, credentials, API keys, Claude's memory file.
      #                  Survives container rebuilds. NEVER delete this folder.
      #                  Override the host path from `.env` if you want it elsewhere.
      #
      - ${HOLYCLAUDE_HOST_CLAUDE_DIR:-./data/claude}:/home/claude/.claude
      #
      # ./workspace β€” Your code and projects. Everything you build goes here.
      #               Accessible from your host machine.
      #               Override the host path from `.env` if you want a different root.
      #
      - ${HOLYCLAUDE_HOST_WORKSPACE_DIR:-./workspace}:/workspace
      #
      # OPTIONAL SSH/MOSH REMOTE SHELL
      # Keep authorized_keys outside .claude and /workspace. Mount it read-only.
      #
      # - ./data/ssh/authorized_keys:/run/holyclaude-ssh/authorized_keys:ro
      # - holyclaude-ssh:/var/lib/holyclaude-ssh
    environment:
      #
      # TIMEZONE
      # Full list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
      #
      - TZ=UTC
      #
      # PERFORMANCE
      # Node.js heap memory limit in MB. Increase if you work on large monorepos
      # and hit out-of-memory errors. 4096 (4GB) is a solid default.
      #
      - NODE_OPTIONS=--max-old-space-size=4096
      #
      # USER MAPPING
      # Docker-style UID/GID remapping. Run `id -u` and `id -g` on your host.
      # Rootless Podman users should use docker-compose.podman-rootless.yaml instead.
      #
      - PUID=1000
      - PGID=1000
      #
      # SMB/CIFS NETWORK MOUNTS
      # Only enable these if your volumes are on a NAS, Samba share, or CIFS mount.
      # They enable polling-based file watching since network mounts don't support inotify.
      # Leave commented out for local storage β€” polling uses more CPU.
      #
      # - CHOKIDAR_USEPOLLING=1
      # - WATCHFILES_FORCE_POLLING=true
      #
      # NOTIFICATIONS (optional)
      # Get notified when Claude finishes a task or hits an error.
      # Uses Apprise β€” supports 100+ services. Also requires creating a flag file
      # inside the container: touch ~/.claude/notify-on
      #
      # - NOTIFY_DISCORD=discord://webhook_id/webhook_token
      # - NOTIFY_TELEGRAM=tgram://bot_token/chat_id
      # - NOTIFY_PUSHOVER=pover://user_key@app_token
      # - NOTIFY_SLACK=slack://token_a/token_b/token_c
      # - NOTIFY_EMAIL=mailto://user:pass@gmail.com?to=you@gmail.com
      # - NOTIFY_GOTIFY=gotify://hostname/token
      # - NOTIFY_URLS=                                   # catch-all: comma-separated Apprise URLs
      #
      # AI PROVIDER KEYS (optional)
      # Claude Code can authenticate via web UI (OAuth) or ANTHROPIC_API_KEY.
      # Set these if you want to use additional AI CLIs or API-based auth.
      #
      # - GEMINI_API_KEY=your_key
      # - OPENAI_API_KEY=your_key
      # - CURSOR_API_KEY=your_key
      #
      # WEB UI BASE PATH (optional)
      # Use only when a reverse proxy mounts HolyClaude below a path.
      # Example: Tailscale Serve --set-path=/holyclaude
      # Do not add a trailing slash.
      #
      # - HOLYCLAUDE_BASE_PATH=/holyclaude
      #
      # CODEX PERMISSION MODES (optional)
      # CloudCLI Codex chat uses this only when a request omits permissionMode.
      # The current browser client sends permissionMode explicitly.
      # Raw codex CLI reads HOLYCLAUDE_CODEX_CLI_PERMISSION_MODE only when first creating ~/.codex/config.toml.
      # Valid values: default, acceptEdits, bypassPermissions. Recommended: acceptEdits.
      # bypassPermissions gives full access with no approval. Use it only for trusted local workspaces.
      #
      # - HOLYCLAUDE_CODEX_CHAT_PERMISSION_MODE=acceptEdits
      # - HOLYCLAUDE_CODEX_CLI_PERMISSION_MODE=acceptEdits
      #
      # SSH/MOSH REMOTE SHELL (optional, disabled by default)
      # Keep this behind localhost, VPN, Tailscale, or a firewall.
      #
      # - HOLYCLAUDE_SSH_ENABLE=false
      # - HOLYCLAUDE_SSH_AUTHORIZED_KEYS=/run/holyclaude-ssh/authorized_keys
      # - HOLYCLAUDE_SSH_HOST_KEYS_DIR=/var/lib/holyclaude-ssh/host_keys
      # - HOLYCLAUDE_MOSH_ENABLE=false
      # - HOLYCLAUDE_MOSH_UDP_START=60000
      # - HOLYCLAUDE_MOSH_UDP_END=60010

# volumes:
#   holyclaude-ssh:

Then:

docker compose up -d

If you want to change the host-side port or bind-mount paths without editing compose, copy .env.example to .env and set:

HOLYCLAUDE_HOST_PORT=3003
HOLYCLAUDE_HOST_CLAUDE_DIR=./data/claude
HOLYCLAUDE_HOST_WORKSPACE_DIR=./workspace

These values are read by Docker Compose on the host. They are not container environment variables.

What each section controls:

SectionWhat it doesWhen to change it
TimezoneContainer clockAlways β€” set to your local TZ
PerformanceNode.js memory ceilingOnly if you hit OOM errors on large projects
User mappingFile permissions between container and hostDocker users: match id -u and id -g. Rootless Podman users: use the Podman compose file below.
SMB/CIFSFile watcher polling modeOnly if your volumes live on a NAS or network share
NotificationsPush alerts via Apprise (Discord, Telegram, Slack, Email, 100+ services)If you want to walk away and know when your AI agents are done
AI providersAPI keys for Gemini, Codex, Cursor, Junie, OpenCodeIf you want to use AI CLIs other

Files in the repo

Repository payloadβ€’24 top-level entries
  • .github
  • assets
  • config
  • contracts
  • docs
  • s6-overlay
  • scripts
  • security
  • tests
  • vendor
  • workspace
  • .dockerignore
  • .env.example
  • .gitattributes
  • .gitignore
  • CODE_OF_CONDUCT.md
  • CONTRIBUTING.md
  • docker-compose.full.yaml
  • docker-compose.podman-rootless.yaml
  • docker-compose.yaml
  • Dockerfile
  • LICENSE
  • README.md
  • THIRD-PARTY-NOTICES

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More tools

JuliusBrussee/
caveman

πŸͺ¨ why use many token when few token do trick β€” Claude Code skill that cuts 65% of tokens by talking like caveman

105k
1 add
MemPalace/
mempalace

The best-benchmarked open-source AI memory system. And it's free.

59k
stablyai/
orca

Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.

66k

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

132k

Never stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors

64k
headroomlabs-ai/
headroom

Compress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.

71k