skills/aradotso/trending-skills/holyclaude-ai-workstation

holyclaude-ai-workstation

SKILL.md

HolyClaude AI Workstation

Skill by ara.so — Daily 2026 Skills collection.

HolyClaude is a containerized AI development workstation that bundles Claude Code CLI, a CloudCLI web UI, Chromium headless browser with Playwright, 5 AI CLIs (Claude, Gemini, OpenAI Codex, Cursor, TaskMaster AI), and 50+ dev tools into a single Docker image. One docker compose up replaces hours of manual setup.


Installation

Prerequisites

  • Docker + Docker Compose installed
  • Existing Anthropic account (Max/Pro subscription or API key)

Quick Start

mkdir holyclaude && cd holyclaude

Create docker-compose.yaml:

services:
  holyclaude:
    image: CoderLuii/HolyClaude:latest
    container_name: holyclaude
    hostname: holyclaude
    restart: unless-stopped
    shm_size: 2g
    ports:
      - "3001:3001"
    volumes:
      - ./data/claude:/root/.claude
      - ./data/config:/root/.config
      - ./projects:/workspace
    environment:
      - PUID=1000
      - PGID=1000
docker compose up -d
# Open http://localhost:3001

Image Variants

# Full image — all tools pre-installed (recommended)
docker pull CoderLuii/HolyClaude:latest

# Slim image — smaller download, tools installed on demand
docker pull CoderLuii/HolyClaude:slim

# Pinned version for production stability
docker pull CoderLuii/HolyClaude:1.2.3
docker pull CoderLuii/HolyClaude:1.2.3-slim

Full Docker Compose Configuration

services:
  holyclaude:
    image: CoderLuii/HolyClaude:latest
    container_name: holyclaude
    hostname: holyclaude
    restart: unless-stopped
    shm_size: 2g                          # Required for Chromium
    ports:
      - "3001:3001"                       # CloudCLI web UI
    volumes:
      - ./data/claude:/root/.claude       # Claude credentials & config (persisted)
      - ./data/config:/root/.config       # App config (persisted)
      - ./projects:/workspace             # Your project files
    environment:
      # User/group IDs (match host user to avoid permission issues)
      - PUID=1000
      - PGID=1000

      # AI provider API keys (optional — can also set via web UI)
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - GEMINI_API_KEY=${GEMINI_API_KEY}
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - CURSOR_API_KEY=${CURSOR_API_KEY}

      # NAS/SMB mount polling (enable if using Synology/QNAP)
      - CHOKIDAR_USEPOLLING=true

      # Notification webhooks (optional)
      - DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
      - SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL}
    security_opt:
      - seccomp:unconfined               # Required for Chromium sandbox

Environment Variable Reference

Variable Required Description
PUID Recommended Host user ID (run id -u to find yours)
PGID Recommended Host group ID (run id -g to find yours)
ANTHROPIC_API_KEY Optional Anthropic API key (alternative to OAuth login)
GEMINI_API_KEY Optional Google AI API key for Gemini CLI
OPENAI_API_KEY Optional OpenAI API key for Codex CLI
CURSOR_API_KEY Optional Cursor API key
CHOKIDAR_USEPOLLING NAS only Set true for SMB/NFS mounts
DISCORD_WEBHOOK_URL Optional Discord notifications
SLACK_WEBHOOK_URL Optional Slack notifications

Authentication

Method 1: OAuth (Claude Max/Pro Subscription)

  1. Open http://localhost:3001
  2. Create a CloudCLI account (10 seconds)
  3. Sign in with your Anthropic account via OAuth
  4. No API key needed — uses your existing subscription

Method 2: API Key

environment:
  - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}

Or paste the key directly in the CloudCLI web UI settings.

Credential Persistence

Credentials are stored in the bind-mounted volume:

./data/claude/     →  /root/.claude/
./data/config/     →  /root/.config/

Credentials survive container restarts, updates, and recreation.


Platform-Specific Configuration

Linux (amd64/arm64) — Default

# No extra config needed
shm_size: 2g

macOS (Docker Desktop)

# Works out of the box with Docker Desktop
shm_size: 2g

Windows (WSL2 + Docker Desktop)

# Requires WSL2 backend enabled in Docker Desktop
shm_size: 2g

Synology / QNAP NAS

environment:
  - CHOKIDAR_USEPOLLING=true    # Fixes file watching on SMB mounts
volumes:
  - /volume1/docker/holyclaude/data/claude:/root/.claude
  - /volume1/docker/holyclaude/projects:/workspace

Kubernetes (ARM64 / Oracle Cloud Graviton)

# arm64 image is published alongside amd64
image: CoderLuii/HolyClaude:latest   # multi-arch manifest auto-selects correct arch

What's Inside the Container

AI CLIs

CLI Invocation Key Provider
Claude Code claude Anthropic (ANTHROPIC_API_KEY or OAuth)
Gemini CLI gemini Google (GEMINI_API_KEY)
OpenAI Codex codex OpenAI (OPENAI_API_KEY)
Cursor cursor Cursor (CURSOR_API_KEY)
TaskMaster AI task-master Uses configured AI provider keys

Headless Browser Stack

  • Chromium — pre-installed and configured
  • Xvfb — virtual display on :99
  • Playwright — configured and ready
  • Shared memoryshm_size: 2g pre-configured (fixes the 64MB Docker default)

Dev Tools (50+)

  • Languages: Node.js, Python 3, TypeScript, Bun, Deno
  • Package managers: npm, yarn, pnpm, pip, cargo
  • Database clients: PostgreSQL, MySQL, SQLite, Redis CLI
  • Cloud CLIs: AWS CLI, Google Cloud SDK, Azure CLI
  • Dev tools: GitHub CLI (gh), Git, curl, jq, ripgrep, fd
  • Process manager: s6-overlay (auto-restart, graceful shutdown)

Working with Projects

Mount your project directory

volumes:
  - ./projects:/workspace
  # Or mount a specific project:
  - /path/to/my-app:/workspace/my-app

Inside the container

# Access the container shell
docker exec -it holyclaude bash

# Navigate to workspace
cd /workspace

# Run Claude Code directly
claude

# Run other AI CLIs
gemini
codex

Playwright / Headless Browser Usage

Playwright is pre-configured. Use it from Claude Code tasks or directly:

// playwright.config.ts — already works inside the container
import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    // Chromium is pre-installed, no download needed
    browserName: 'chromium',
    launchOptions: {
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage',  // Use /tmp instead of /dev/shm
      ],
    },
  },
});
// Direct Playwright usage inside container
import { chromium } from 'playwright';

const browser = await chromium.launch({
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage',
  ],
});
const page = await browser.newPage();
await page.goto('https://example.com');
const screenshot = await page.screenshot({ path: '/workspace/screenshot.png' });
await browser.close();
# Run Playwright tests inside container
docker exec -it holyclaude bash -c "cd /workspace && npx playwright test"

# Run with headed mode via Xvfb
docker exec -it holyclaude bash -c "DISPLAY=:99 npx playwright test --headed"

Updating HolyClaude

# Pull latest image
docker compose pull

# Recreate container with new image (zero data loss — data is in bind mounts)
docker compose up -d

# Or explicit recreation
docker compose down && docker compose up -d

Pinned Version Strategy

# For production: pin to a specific version
image: CoderLuii/HolyClaude:1.2.3

# Update by changing the tag and running:
docker compose up -d

Data & Persistence

holyclaude/
├── docker-compose.yaml
├── data/
│   ├── claude/          # Claude credentials, .claude.json, history
│   └── config/          # CloudCLI and app configuration
└── projects/            # Your workspace (mount your code here)

All credentials and config survive:

  • Container restarts
  • docker compose down && up
  • Image updates via docker compose pull
  • Container recreation

Common Patterns

Pattern: Multiple Projects

volumes:
  - ./data/claude:/root/.claude
  - ./data/config:/root/.config
  - ~/code/project-a:/workspace/project-a
  - ~/code/project-b:/workspace/project-b
  - ~/code/project-c:/workspace/project-c

Pattern: Read-only API Keys via .env file

# .env (never commit this)
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=AIza...
OPENAI_API_KEY=sk-...
# docker-compose.yaml
services:
  holyclaude:
    env_file: .env

Pattern: Custom Port

ports:
  - "8080:3001"    # Access via http://localhost:8080

Pattern: Remote Server Access

ports:
  - "0.0.0.0:3001:3001"    # Accessible from network
# Then access via http://your-server-ip:3001
# Recommend putting behind nginx/Caddy with HTTPS for production

Pattern: Nginx Reverse Proxy

services:
  holyclaude:
    image: CoderLuii/HolyClaude:latest
    # Don't expose ports directly — nginx handles it
    expose:
      - "3001"
    networks:
      - web

  nginx:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./certs:/etc/nginx/certs
    networks:
      - web

networks:
  web:

Troubleshooting

Container won't start

# Check logs
docker compose logs holyclaude

# Check if port 3001 is already in use
lsof -i :3001

Chromium crashes / headless browser fails

# Ensure shm_size is set (CRITICAL)
shm_size: 2g

# Ensure seccomp is unconfined
security_opt:
  - seccomp:unconfined
# Verify display is available inside container
docker exec holyclaude bash -c "echo $DISPLAY"
# Should output: :99

Permission denied errors on bind mounts

environment:
  - PUID=1000    # Must match your host user: `id -u`
  - PGID=1000    # Must match your host group: `id -g`
# Fix existing permissions on host
sudo chown -R 1000:1000 ./data ./projects

File watching broken on NAS / SMB mounts

environment:
  - CHOKIDAR_USEPOLLING=true

Claude Code installer hangs

This is pre-solved in HolyClaude — the container sets the correct WORKDIR ownership. If you're building a custom image on top:

# Ensure WORKDIR is not root-owned before running Claude Code installer
RUN chown -R node:node /app
WORKDIR /app

SQLite locks on NAS mount

volumes:
  # Move SQLite databases to a local volume, not NAS mount
  - holyclaude-db:/root/.local/share/holyclaude
  - /nas/mount:/workspace    # NAS mount only for project files

volumes:
  holyclaude-db:

Claude Code authentication lost after restart

# Ensure this volume is mounted (credentials live here)
volumes:
  - ./data/claude:/root/.claude

Process keeps dying / not restarting

HolyClaude uses s6-overlay for process supervision. Check service status:

docker exec holyclaude s6-svstat /run/service/cloudcli
docker exec holyclaude s6-svstat /run/service/xvfb

Building Locally

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

# Build full image
docker build -t holyclaude:local .

# Build slim image
docker build -t holyclaude:local-slim --target slim .

# Build for specific platform
docker buildx build --platform linux/arm64 -t holyclaude:arm64 .

# Run your local build
docker run -d \
  --name holyclaude \
  --shm-size=2g \
  -p 3001:3001 \
  -v $(pwd)/data/claude:/root/.claude \
  holyclaude:local

Quick Reference

# Start
docker compose up -d

# Stop
docker compose down

# View logs (live)
docker compose logs -f holyclaude

# Shell access
docker exec -it holyclaude bash

# Update to latest
docker compose pull && docker compose up -d

# Restart only the container
docker compose restart holyclaude

# Check resource usage
docker stats holyclaude
Weekly Installs
10
GitHub Stars
11
First Seen
1 day ago
Installed on
opencode10
gemini-cli10
deepagents10
antigravity10
github-copilot10
codex10