Fetching latest headlines…
How I Run Claude Code in Docker with a Web UI and Headless Browser
NORTH AMERICA
πŸ‡ΊπŸ‡Έ United Statesβ€’March 22, 2026

How I Run Claude Code in Docker with a Web UI and Headless Browser

1 views0 likes0 comments
Originally published byDev.to

You know the drill. You want Claude Code on a server. In a browser. With Playwright so it can actually interact with web pages. With every AI CLI you might need. With TypeScript, Python, database clients, the works.

So you start installing things.

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 Claude Code's installer hangs silently because WORKDIR is root-owned. Then SQLite locks on your NAS mount.

Two hours later you haven't written a single line of code.

I got tired of doing this on every new server. So I built a container that handles all of it, and I ran it on my own server daily until every edge case surfaced and got fixed. That container is HolyClaude. It's free and open source, MIT license.

getting it running

Create a folder, drop in a compose file, pull, start.

mkdir holyclaude && cd holyclaude

Here's the compose file:

services:
  holyclaude:
    image: coderluii/holyclaude:latest
    container_name: holyclaude
    ports:
      - "3001:3001"
    volumes:
      - ./data/claude:/home/claude/.claude
      - ./workspace:/workspace
    environment:
      - TZ=UTC
    restart: unless-stopped
    shm_size: 2g
    cap_add:
      - SYS_ADMIN
      - SYS_PTRACE
    security_opt:
      - seccomp=unconfined
docker compose up -d

Open http://localhost:3001. Create a CloudCLI account (takes about 10 seconds), then sign in with your Anthropic credentials. You're in Claude Code, in your browser, with a headless browser ready to go.

That shm_size: 2g line is important. Chromium crashes without it because Docker allocates 64MB of shared memory by default. This is the number one issue people hit and the error messages don't point you anywhere useful.

how authentication works

HolyClaude runs the real Claude Code CLI from Anthropic. Not a wrapper, not a proxy. Your existing account works directly.

If you're on the Max or Pro plan, sign in through CloudCLI. It's the same OAuth flow as desktop Claude Code. Your subscription works as-is. If you prefer API keys, paste your Anthropic API key in the web UI. Pay-per-use, same billing.

Your credentials live in ./data/claude/ on your host. The container doesn't intercept or proxy anything.

the headless browser situation

This is the part that takes the most work to get right in Docker. Here's what HolyClaude handles for you:

Chromium needs more than 64MB of shared memory. It needs a virtual display, so Xvfb has to be configured at :99 and start before Chromium. It needs specific sandbox flags for running in a container. Playwright needs to find the system Chromium instead of trying to download its own copy.

When you ask Claude to take a screenshot, run Playwright tests, fill out a form, or scrape a site, it works. Because all of this is already configured.

process management

The container runs multiple services: Xvfb, the web UI server, file watchers. A shell script loop won't handle restarts cleanly or guarantee startup order.

I'm using s6-overlay. It gives proper dependency ordering (Xvfb starts before anything that needs a display), auto-restart on crash, and clean shutdown when you run docker compose down. It's what Linuxserver.io uses in their images, and for good reason.

image variants

The full image is about 4GB because it bundles Chromium, Playwright, and a full dev toolchain. If you don't need the browser stuff, the slim tag is about 2GB.

docker pull coderluii/holyclaude:latest
docker pull coderluii/holyclaude:slim

Both are multi-arch. AMD64 and ARM64. Works on Linux, macOS with Docker Desktop, Windows with WSL2, and Synology/QNAP NAS.

what I actually use it for

Long-running Claude Code sessions on my home server. I close my laptop and come back the next day. Session is still there.

Browser automation. I ask Claude to screenshot a URL, run tests, interact with a page. Chromium is ready. I don't configure anything.

Multi-model comparison. Claude, Gemini, and Codex are all in the same environment. Useful when I want to see how each handles a task on the same codebase.

Everything persists in ./data/. Files, auth, configs, state. Upgrade the container and nothing changes.

things it doesn't do

No built-in HTTPS. Put it behind Caddy, Traefik, or nginx if you're exposing it outside localhost. No multi-user access control. CloudCLI is a third-party web UI, not the official Anthropic desktop app.

troubleshooting the common stuff

If Chromium crashes, check shm_size: 2g in your compose file. If file changes aren't detected on a NAS mount, add CHOKIDAR_USEPOLLING=true.

if you try it and hit something, open an issue on GitHub. free and open source, MIT license.

GitHub: https://github.com/CoderLuii/HolyClaude
Docker Hub: https://hub.docker.com/r/coderluii/holyclaude
Website: https://holyclaude.coderluii.dev

Comments (0)

Sign in to join the discussion

Be the first to comment!