Skip to content

CoderLuii/HolyClaude

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, 7 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.


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.

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.

💳 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 doesn't touch your credentials. They're stored locally in your bind-mounted volume (./data/claude/), same as they would be on bare metal.

↑ back to top


Table of Contents

Section
Quick Start
💻 Platform Support
🌟 Why HolyClaude
💳 Subscription & Authentication
📦 Image Variants
🐳 Docker Compose — Quick
🐋 Docker Compose — Full
🔧 Environment Variables
🚀 What's Inside
🤖 AI CLI Providers
🦙 Using Ollama
🏗️ Architecture
📁 Project Structure
💾 Data & Persistence
🔒 Permissions
🔔 Notifications
🔄 Upgrading
🚧 Troubleshooting
⚠️ Known Issues
🛠️ Building Locally
📊 Alternatives
🚀 Roadmap
🏆 Built with HolyClaude
🤝 Contributing
❤️ Support
📄 License

↑ back to top


⚡ 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.

↑ back to top


💻 Platform Support

Platform Status Notes
Linux (amd64) ✅ Fully supported Native performance, recommended
Linux (arm64) ✅ Fully supported Raspberry Pi 4+, Oracle Cloud, AWS Graviton
macOS (Docker Desktop) ✅ Fully supported Apple Silicon & Intel via Docker Desktop
Windows (WSL2 + Docker Desktop) ✅ Fully supported Requires WSL2 backend
Synology / QNAP NAS ✅ Fully supported Use CHOKIDAR_USEPOLLING=true for SMB mounts
Kubernetes 🔜 Coming soon Helm chart planned

↑ back to top


🌟 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.

HolyClaude Doing it yourself
Setup 30 seconds 1-2 hours (if it goes well)
Claude Code Pre-installed, pre-configured, ready Install, configure, debug installer hanging, fix WORKDIR
Web UI CloudCLI included with plugins Find a web UI, install it, configure it, wire it to Claude
Headless browser Chromium + Xvfb + Playwright, configured Install Chromium, install Xvfb, configure display :99, fix shm, fix sandbox, fix seccomp...
AI CLIs 7 providers, one container Install each one separately across 3 package managers
Dev tools 50+ tools, ready apt-get install / npm i -g / pip install for the next hour
Process management s6-overlay (auto-restart, graceful shutdown) Write your own supervisord config or hope Docker restart works
Persistence Bind mounts, credentials survive everything Figure out Docker volumes, debug "why is this a directory not a file"
Updates docker pull && docker compose up -d Update 50 tools manually, pray nothing breaks
Multi-arch AMD64 + ARM64 Pray 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


💳 Subscription & Authentication

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

What works:

Authentication method How Cost
Claude Max/Pro plan (subscription) Sign in through CloudCLI web UI — same OAuth flow as desktop Your existing subscription, no extra charge
Anthropic API key Paste your API key in the web UI Pay-per-use, same Anthropic billing

What doesn't work:

Why
ChatGPT Plus/Pro subscription That's for chat.openai.com only — doesn't provide API access
OpenAI API key for Claude Different company, different API. OpenAI keys work with the Codex CLI (also pre-installed)

Other AI CLIs included:

CLI What you need
Gemini CLI Google AI API key (GEMINI_API_KEY)
OpenAI Codex OpenAI API key (OPENAI_API_KEY) — separate from ChatGPT subscription
Cursor Cursor API key (CURSOR_API_KEY)
TaskMaster AI Uses your AI provider keys (Anthropic, OpenAI, etc.)
Junie JetBrains account (JetBrains AI subscription)
OpenCode Configure via opencode TUI (supports multiple providers)

HolyClaude is free and open source. You only pay your AI providers for usage, same as you already do. We don't proxy, intercept, or touch your credentials. They live in your local bind mount.

↑ back to top


📦 Image Variants

Two flavors. Same quality. Pick your weight class.

Tag What you get Best for
latest Everything pre-installed — every tool, every library, every CLI Most users. Zero wait time. Claude never has to stop and install something.
slim Core tools only — Claude installs extras on-demand Smaller VPS, limited disk, metered bandwidth
X.Y.Z Full image, pinned version Production stability — you control when to update
X.Y.Z-slim Slim image, pinned version Production + small footprint
# 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.

↑ back to top


🐳 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                           # Chromium needs this — don't remove
    network_mode: bridge
    cap_add:
      - SYS_ADMIN                          # Required: Chromium sandboxing
      - SYS_PTRACE                         # Required: debugging tools
    security_opt:
      - seccomp=unconfined                 # Required: Chromium in Docker
    ports:
      - "3001:3001"                        # CloudCLI web UI
    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 SYS_ADMIN + seccomp=unconfined? Chromium needs these to run inside Docker — it's standard for any containerized browser (Playwright docs, Puppeteer docs, every CI pipeline that runs browser tests). Without them, Chromium crashes on startup. This is not a security risk unique to HolyClaude.

Why shm_size: 2g? Docker gives containers 64MB of shared memory by default. Chromium uses /dev/shm heavily for tab rendering. At 64MB, tabs crash randomly. 2GB is the recommended minimum for any Chromium-in-Docker setup.

↑ back to top


🐋 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/main/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                          # Required: Chromium sandboxing
      - SYS_PTRACE                         # Required: debugging tools (strace, lsof)
    security_opt:
      - seccomp=unconfined                 # Required: Chromium syscall requirements
    ports:
      #
      # CloudCLI web UI — this is the only port you need.
      # Override the host-side port from `.env` if 3001 is already in use.
      #
      - "${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.
      #
      # - "3000:3000"                      # Next.js / Express
      # - "4321:4321"                      # Astro
      # - "5173:5173"                      # Vite
      # - "8787:8787"                      # Wrangler (Cloudflare Workers)
      # - "9229:9229"                      # Node.js debugger
    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
    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
      # Match these to your host user so files created inside the container
      # have the right ownership on your host. Run `id -u` and `id -g` on your host.
      #
      - 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=tg://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

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:

Section What it does When to change it
Timezone Container clock Always — set to your local TZ
Performance Node.js memory ceiling Only if you hit OOM errors on large projects
User mapping File permissions between container and host If you get "permission denied" (id -u and id -g on your host)
SMB/CIFS File watcher polling mode Only if your volumes live on a NAS or network share
Notifications Push alerts via Apprise (Discord, Telegram, Slack, Email, 100+ services) If you want to walk away and know when Claude is done
AI providers API keys for Gemini, Codex, Cursor, Junie, OpenCode If you want to use AI CLIs other than Claude

Every single environment variable is optional. The container runs perfectly with just TZ=UTC. Everything else has sensible defaults or is handled through the web UI.

↑ back to top


🔧 Environment Variables

The complete reference. Every variable, what it defaults to, what it does.

Variable Default What it does
TZ UTC Container timezone
PUID 1000 Container user ID — match your host to avoid permission issues
PGID 1000 Container group ID — match your host to avoid permission issues
NODE_OPTIONS --max-old-space-size=4096 Node.js heap memory limit in MB
GIT_USER_NAME HolyClaude User Git commit author (set once on first boot)
GIT_USER_EMAIL noreply@holyclaude.local Git commit email (set once on first boot)
CHOKIDAR_USEPOLLING (unset) Set to 1 for SMB/CIFS — enables polling file watchers
WATCHFILES_FORCE_POLLING (unset) Set to true for SMB/CIFS — enables Python polling
NOTIFY_DISCORD (unset) Discord webhook URL for notifications
NOTIFY_TELEGRAM (unset) Telegram bot URL for notifications
NOTIFY_PUSHOVER (unset) Pushover URL for notifications
NOTIFY_SLACK (unset) Slack webhook URL for notifications
NOTIFY_EMAIL (unset) Email (SMTP) URL for notifications
NOTIFY_GOTIFY (unset) Gotify URL for notifications
NOTIFY_URLS (unset) Catch-all — comma-separated Apprise URLs
ANTHROPIC_API_KEY (unset) Anthropic API key (alternative to web UI OAuth)
ANTHROPIC_AUTH_TOKEN (unset) Anthropic auth token (alternative to API key)
ANTHROPIC_BASE_URL (unset) Custom Anthropic API endpoint (proxies, private deployments)
CLAUDE_CODE_USE_BEDROCK (unset) Set to 1 to use Amazon Bedrock backend
CLAUDE_CODE_USE_VERTEX (unset) Set to 1 to use Google Vertex AI backend
GEMINI_API_KEY (unset) Google Gemini API key
OPENAI_API_KEY (unset) OpenAI API key (for Codex CLI — NOT ChatGPT)
CURSOR_API_KEY (unset) Cursor API key
OLLAMA_HOST (unset) Ollama endpoint URL (e.g., http://host.docker.internal:11434)

↑ back to top


🚀 What's Inside

This is not a minimal container. This is an entire development workstation.

Both variants (full + slim)

Node.js 22 LTS + npm global packages
Package What it's for
typescript, tsx TypeScript compilation and execution
pnpm Fast, disk-efficient package manager
vite, esbuild Lightning-fast build tools
eslint, prettier Code quality and formatting
serve, nodemon Static file server, auto-restart dev server
concurrently Run multiple scripts in parallel
dotenv-cli Load env vars from .env files
Python 3 packages
Package What it's for
requests, httpx HTTP clients
beautifulsoup4, lxml Web scraping and HTML parsing
Pillow Image processing (pre-compiled — no waiting)
pandas, numpy Data manipulation (pre-compiled — seriously, you don't want to pip install these at runtime)
openpyxl Read/write Excel files
python-docx Read/write Word documents
jinja2, markdown Templating and markdown rendering
pyyaml, python-dotenv Config file parsing
rich, click, tqdm Beautiful CLIs and progress bars
playwright Browser automation (Chromium already configured and ready)
System tools
Tool What it's for
git, gh Version control + GitHub CLI (PRs, issues, releases from the terminal)
ripgrep (rg), fd, fzf Blazing-fast search — Claude uses these constantly
bat, tree, jq Better cat (syntax highlighting), directory trees, JSON processing
curl, wget HTTP downloads
tmux Terminal multiplexer — run things in the background
htop, lsof, strace Process monitoring and debugging
imagemagick Image conversion (convert, identify, mogrify)
chromium Headless browser — screenshots, Playwright, Lighthouse
psql, redis-cli, sqlite3 Talk to databases directly
openssh-client SSH into things
AI CLIs — every major provider
CLI Command What it's for
Claude Code claude The main event — you're running inside this
Gemini CLI gemini Google's AI coding agent
OpenAI Codex codex OpenAI's coding agent
Cursor cursor Cursor's AI agent
TaskMaster AI task-master Task planning and orchestration
Junie junie JetBrains' AI coding agent
OpenCode opencode Open source AI agent (multiple providers)

Seven AI CLIs. One container. Switch between them instantly. No other Docker image does this.

Full image only (additional packages)

The full image includes everything above, plus:

Additional npm packages — deployment, ORMs, performance
Package What it's for
wrangler, @cloudflare/next-on-pages Cloudflare Workers deployment
vercel Vercel deployment
netlify-cli Netlify deployment
az Azure CLI for cloud deployment and management
prisma, drizzle-kit The two most popular Node.js ORMs
pm2 Production process manager
eas-cli Expo / React Native builds
lighthouse, @lhci/cli Performance auditing (Chromium is already there)
sharp-cli Image processing CLI
json-server, http-server Mock REST APIs, static file serving
@marp-team/marp-cli Markdown to presentation slides
Additional Python packages — PDFs, data viz, web frameworks
Package What it's for
reportlab, weasyprint, cairosvg, fpdf2, PyMuPDF, pdfkit, img2pdf Every major PDF library. Generate them, read them, convert them, merge them.
xlsxwriter, xlrd Excel formats beyond what openpyxl covers
matplotlib, seaborn Data visualization and charts
python-pptx PowerPoint generation
fastapi, uvicorn Python web framework
httpie Human-friendly HTTP client (like curl but readable)
Additional system packages — media, documents
Package What it's for
pandoc Convert between any document format (markdown, HTML, PDF, docx, epub...)
ffmpeg Video and audio processing (extract, convert, transcode)
libvips-dev High-performance image processing library

Slim users: Missing a package? Ask Claude. It installs npm/pip packages in seconds. System packages (pandoc, ffmpeg) take 1-2 minutes. You get the same capabilities — the full image just has zero wait time.

↑ back to top


🤖 AI CLI Providers

Seven AI CLIs. One container. No other Docker image gives you this.

Provider Command How to authenticate Subscription works?
Claude Code claude CloudCLI web UI (OAuth) Yes — Max/Pro plan or API key
Gemini CLI gemini GEMINI_API_KEY env var API key (pay-per-use)
OpenAI Codex codex OPENAI_API_KEY env var API key only — ChatGPT Plus does NOT work
Cursor cursor CURSOR_API_KEY env var API key
TaskMaster AI task-master Uses existing AI provider keys Works with configured keys
Junie junie JetBrains AI subscription JetBrains account required
OpenCode opencode Configure via TUI Supports multiple providers

Claude Code is the primary CLI. The others are there because sometimes you want a second opinion, or a specific model's strengths, or you're comparing outputs. Having all of them one Tab away is the whole point.

↑ back to top


🦙 Using Ollama

HolyClaude works with Ollama as an alternative to an Anthropic subscription. Set two environment variables and use local or cloud models.

See the full setup guide: docs/ollama.md

↑ back to top


🏗️ Architecture

graph TB
    subgraph Docker Container
        EP["entrypoint.sh"] --> BS["bootstrap.sh\n(first boot only)"]
        EP --> S6["s6-overlay\n(PID 1)"]
        S6 --> CC["CloudCLI\n(:3001)"]
        S6 --> XV["Xvfb\n(:99)"]
        CC --> CLAUDE["Claude Code CLI"]
        CLAUDE --> TOOLS["Dev Tools\n(Node, Python, Git...)"]
        CLAUDE --> CHROME["Chromium\n(headless)"]
        XV -.-> CHROME
    end

    subgraph Host
        DATA["./data/claude"] -.->|bind mount| HOME["~/.claude"]
        WS["./workspace"] -.->|bind mount| WORK["/workspace"]
    end

    USER["Browser"] -->|":3001"| CC

    style S6 fill:#2d3748,color:#fff
    style CC fill:#6366f1,color:#fff
    style CLAUDE fill:#f59e0b,color:#000
Loading

How the pieces fit together

  1. Container startsentrypoint.sh runs as root. Remaps UID/GID to match your host user, pre-creates required files (preventing Docker's "create it as a directory" bug), checks if this is a first boot.

  2. First boot onlybootstrap.sh runs once. Copies default settings, memory template, configures git identity. Creates a sentinel file (.holyclaude-bootstrapped) so it never runs again. Your customizations are safe from that point on.

  3. s6-overlay takes over as PID 1 — This isn't supervisord. It's s6-overlay, purpose-built for Docker. Supervises CloudCLI and Xvfb. Auto-restarts on crash. Forwards signals. Reaps zombies. Shuts down gracefully.

  4. CloudCLI serves the web UI — Port 3001. Browser-based interface to Claude Code with project management, multiple sessions, and plugins (project stats + web terminal included).

  5. Xvfb provides a virtual display — Chromium needs a screen to render to, even in "headless" mode. Xvfb gives it a 1920x1080 virtual display at :99. This is why Playwright, screenshots, and Lighthouse all work out of the box.

See docs/architecture.md for the full technical deep-dive — including why we chose s6 over supervisord, why plugins are baked into the image, and why runuser instead of su.

↑ back to top


📁 Project Structure

holyclaude/
├── .github/                 # CI/CD workflows, issue & PR templates
│   ├── FUNDING.yml          # Sponsor/donation links
│   ├── ISSUE_TEMPLATE/      # Bug report, feature request, package request
│   ├── pull_request_template.md
│   ├── SECURITY.md          # Security policy
│   └── workflows/           # Docker build & push automation
├── assets/                  # Logo and banner images
├── config/                  # Claude Code configuration
│   ├── claude-memory-full.md
│   ├── claude-memory-slim.md
│   └── settings.json
├── docs/                    # Extended documentation
│   ├── architecture.md
│   ├── CHANGELOG.md
│   ├── configuration.md
│   ├── dockerhub-description.md
│   ├── ollama.md
│   └── troubleshooting.md
├── scripts/                 # Container lifecycle scripts
│   ├── bootstrap.sh         # First-run setup
│   ├── entrypoint.sh        # Container entrypoint
│   └── notify.py            # Notification helper (Apprise)
├── s6-overlay/              # Process supervision (s6-rc services)
├── Dockerfile               # Single-stage build
├── docker-compose.yaml      # Quick start (minimal config)
├── docker-compose.full.yaml # Full config (all options)
├── LICENSE
└── README.md

↑ back to top


💾 Data & Persistence

What Where (container) Where (host) Survives rebuild?
Settings, credentials, API keys /home/claude/.claude ./data/claude Yes
Your code and projects /workspace ./workspace Yes
CloudCLI account /home/claude/.cloudcli (container only) No
Onboarding state /home/claude/.claude.json (container only) No

What survives docker compose down && docker compose up:

  • Your Anthropic authentication and API keys
  • Claude Code settings and memory (CLAUDE.md)
  • All your code in ./workspace
  • Git configuration

What you'll redo (10 seconds):

  • CloudCLI web account — quick signup, that's it

Re-triggering first-boot setup:

# Delete the sentinel file — NOT the whole folder
rm ./data/claude/.holyclaude-bootstrapped
docker compose restart holyclaude

Never delete ./data/claude/ entirely. That's where your credentials live. Delete the sentinel file if you want a fresh bootstrap. Delete specific config files if you want to reset settings. But never nuke the whole folder.

↑ back to top


🔒 Permissions

Claude Code runs in allowEdits mode by default. This is the safest useful setting:

Action Allowed?
Read files Yes
Edit / create files Yes
Run shell commands Asks you first
Install packages Asks you first

Want full bypass? (power users)

This is how I personally run it. Edit ./data/claude/settings.json on your host:

{
  "permissions": {
    "defaultMode": "bypassPermissions"
  }
}

Bypass mode means Claude executes any command without confirmation. Fast, powerful, and exactly what you want if you trust what you're building. But allowEdits is the safe default for a reason.

↑ back to top


🔔 Notifications

Walk away from your computer and know when Claude is done. Uses Apprise for notifications — supports 100+ services including Discord, Telegram, Slack, Email, Pushover, Gotify, and more.

To enable:

  1. Add one or more NOTIFY_* variables to your compose environment:
    - NOTIFY_DISCORD=discord://webhook_id/webhook_token
    - NOTIFY_TELEGRAM=tg://bot_token/chat_id
  2. Inside the container: touch ~/.claude/notify-on

See configuration docs for all supported variables and URL formats.

To disable: rm ~/.claude/notify-on

Events that trigger notifications:

Event What happened
stop Claude finished the current task
error A tool use failure occurred

Completely silent when not configured. No NOTIFY_* vars set? No flag file? Zero network calls. Zero log spam. Zero overhead.

↑ back to top


🔄 Upgrading

# Pull the latest image
docker compose pull

# Recreate the container with the new image
docker compose up -d

Your data persists in ./data/claude and ./workspace — upgrading only replaces the container, not your files.

To pin a specific version instead of latest:

image: coderluii/holyclaude:1.1.2   # instead of :latest

↑ back to top


🚧 Troubleshooting

CloudCLI shows wrong default directory

CloudCLI opens to /home/claude instead of /workspace.

Cause: WORKSPACES_ROOT not reaching the CloudCLI process. Docker-compose env vars don't pass through s6-overlay's s6-setuidgid — it runs with a clean environment by design (security feature, not a bug).

Fix: Already handled in HolyClaude. The s6 run script sets WORKSPACES_ROOT=/workspace directly in the process environment.

SQLite "database is locked"

Cause: SQLite databases on SMB/CIFS network mounts. CIFS doesn't support the file-level locking SQLite requires.

Fix: Don't store SQLite databases on network shares. HolyClaude keeps .cloudcli in container-local storage for exactly this reason. If you have your own SQLite databases in /workspace on a NAS, move them to a local path.

Chromium crashes / blank pages / tab failures

Cause: Insufficient shared memory. Docker defaults to 64MB.

Fix: Ensure shm_size: 2g in your compose file. For heavy browser use (many tabs, complex pages), increase to 4g.

File watchers not detecting changes (hot reload broken)

Cause: SMB/CIFS network mounts don't support inotify.

Fix: Enable polling in your compose environment:

- CHOKIDAR_USEPOLLING=1
- WATCHFILES_FORCE_POLLING=true

Note: Polling uses more CPU than inotify. Only enable on network mounts.

Permission denied errors

Cause: Container UID/GID doesn't match host file ownership.

Fix:

# On your host machine
id -u  # → this is your PUID
id -g  # → this is your PGID

Set them in your compose file:

- PUID=1000
- PGID=1000
Docker creates .claude.json as a directory

Cause: If a bind-mount target file doesn't exist before container start, Docker helpfully creates it as a directory. Thanks, Docker.

Fix: Already handled — entrypoint.sh pre-creates it as a file.

See docs/troubleshooting.md for the complete guide including all SMB/CIFS gotchas and the full history of bugs we encountered and fixed.

↑ back to top


⚠️ Known Issues

These are not HolyClaude bugs — they're upstream issues or intentional trade-offs.

Issue Why Workaround
"Continue in Shell" button broken CloudCLI upstream bug (race condition in terminal init) Use the Web Terminal plugin instead (pre-installed)
Cursor CLI "Command timeout" No API key configured — cosmetic only, doesn't affect anything Set CURSOR_API_KEY or ignore
CloudCLI account lost on rebuild SQLite can't persist on network mounts — intentional trade-off Re-create account (~10 seconds)
Web push notifications "not supported" Browser limitation in CloudCLI, standard behavior Use Apprise notifications instead (see Notifications)

↑ back to top


🛠️ Building Locally

Want to build the image yourself instead of pulling from Docker Hub? Go for it:

git clone https://github.com/CoderLuii/HolyClaude.git
cd holyclaude

# Build full image
docker build -t holyclaude .

# Build slim image
docker build --build-arg VARIANT=slim -t holyclaude:slim .

# Build for ARM (Apple Silicon, Raspberry Pi, AWS Graviton)
docker buildx build --platform linux/arm64 -t holyclaude .

Then use image: holyclaude instead of image: coderluii/holyclaude:latest in your compose file.

↑ back to top


📊 Alternatives

How does HolyClaude compare to other approaches?

Approach Web UI Multi-AI Pre-configured tools Headless browser One command setup Persistence
HolyClaude CloudCLI 5 CLIs 50+ tools Chromium + Xvfb + Playwright docker compose up Bind mounts
Claude Code (bare metal) No No Install yourself Install yourself Multi-step install Manual
Claude Code + oh-my-openagent No Yes (multi-model) Some No npm install Manual
DIY Docker + Claude Code Maybe Maybe Whatever you add If you configure it If you write the Dockerfile If you set up volumes
Cursor IDE Built-in Cursor only IDE-bundled No Download app App data

HolyClaude isn't competing with coding agents — it's the infrastructure layer that makes them all work better. It's the container you run them inside.

↑ back to top


🚀 Roadmap

What's coming next:

Status Feature
🔜 ARM-native builds — optimized native ARM64 images, not just emulated
🔜 VS Code tunnel integration — built-in VS Code Server or tunnel for connecting from VS Code desktop
🔜 Notification routing — different notification destinations per event type (errors to Telegram, completions to Discord)

Have an idea? Start a discussion or request a feature.

↑ back to top


🏆 Built with HolyClaude

Using HolyClaude to build something? We'd love to see it.

Open an issue with the showcase label or submit a PR to add your project here:

Be the first to add your project here.

↑ back to top


🤝 Contributing

Contributions welcome. This project was born from real daily usage, and it gets better when more people use it and find edge cases.

  1. Fork it
  2. Branch it (git checkout -b feature/something)
  3. Commit it
  4. Push it
  5. PR it

Bugs, feature requests, questions: open an issue.

Get in touch

Channel Use for
GitHub Discussions Questions, show your setup, ideas
Issues Bug reports, feature & package requests
Security Advisories Vulnerability reports (private)

Want a tool added?

Use the 📦 Package Request issue template. Include the package name, install method, and which variant (full/slim) it should target.

↑ back to top


❤️ Support

HolyClaude is free, open source, and maintained by one developer who uses it every day.

If it saved you time, here's how you can help:

  • Star this repo — it's the single biggest thing you can do for visibility
  • Share it — tell a friend, post it, tweet it
  • Open issues — bug reports and feature requests make HolyClaude better for everyone
  • Contribute — PRs are always welcome

PayPal Buy Me A Coffee

↑ back to top


📄 License

MIT — see LICENSE. Use it however you want.

↑ back to top



Built by CoderLuii · coderluii.dev

This container is what I use every day. If it saves you even half the setup time it saved me, a star would be nice.