Solutions to common issues when running HolyClaude.
Symptom: CloudCLI web UI opens to /home/claude instead of /workspace.
Cause: WORKSPACES_ROOT environment variable not reaching the CloudCLI process. Docker-compose env vars don't automatically pass through s6-overlay's s6-setuidgid.
Fix: Already handled in HolyClaude — the s6 run script sets WORKSPACES_ROOT=/workspace directly. If you've modified the s6 service scripts, ensure the env var is set in the env command.
Symptom: Constant lock errors from CloudCLI account database or other SQLite databases.
Cause: SQLite uses file-level locking that CIFS/SMB doesn't support properly.
Fix: Don't store SQLite databases on network mounts. HolyClaude keeps .cloudcli in container-local storage for this reason. If you're using your own SQLite databases in /workspace on a network mount, move them to a local path.
If you want the CloudCLI account to persist across rebuilds, use a named Docker volume for
/home/claude/.cloudcli(see the README's Data & Persistence section). Named volumes live on the Docker engine's local filesystem, so SQLite file locking works. Never bind-mount.cloudclito a NAS, SMB, or NFS path.
Symptom: Playwright tests fail, screenshots are blank, Lighthouse hangs.
Cause: Insufficient shared memory.
Fix: Ensure shm_size: 2g or higher in your docker-compose file. If running many concurrent tabs, increase to 4g.
Symptom: Hot reload doesn't work. Dev servers don't pick up file changes.
Cause: Running on SMB/CIFS mounts which don't support inotify.
Fix: Add polling environment variables:
environment:
- CHOKIDAR_USEPOLLING=1
- WATCHFILES_FORCE_POLLING=trueNote: Polling uses more CPU than inotify. Only enable when needed.
Symptom: Can't write files, git operations fail, npm install fails.
Cause: Usually one of these:
PUID/PGIDdoesn't match your host user- Docker auto-created
./workspaceasroot:rooton first start because the directory did not exist yet
Fix: Set PUID and PGID to match your host user:
# On your host, check your IDs
id -u # This is your PUID
id -g # This is your PGIDThen in your compose file:
environment:
- PUID=1000
- PGID=1000HolyClaude also auto-fixes the top-level /workspace ownership on boot if Docker created it as root. If you still have permission errors after startup, the remaining mismatch is in your host files, not the container's workspace mount point.
Symptom: Bootstrap sentinel (.holyclaude-bootstrapped) survives deletion, so bootstrap never re-runs.
Cause: Bash glob * doesn't match dotfiles (files starting with .).
Fix: Target the sentinel directly:
rm ./data/claude/.holyclaude-bootstrappedNever delete the entire ./data/claude/ directory — this wipes your credentials.
Symptom: Claude Code CLI crashes on startup with cryptic errors.
Cause: If the bind-mount target doesn't exist as a file before container start, Docker creates it as a directory.
Fix: Already handled in entrypoint.sh — it pre-creates the file if missing. If you're running a custom setup, ensure ~/.claude.json exists as a file before starting the container.
Symptom: After docker compose down && up, Claude Code prompts for OAuth / API key again.
Cause: Versions before v1.1.7 didn't persist ~/.claude.json, which holds the Claude Code session state. Container recreation wiped it.
Fix: Upgrade to v1.1.7 or later. The session is now auto-saved to ./data/claude/.claude.json.persist on every boot and every 60 seconds, then restored on the next start. If you're on v1.1.7+ and still losing the session, check that ./data/claude/ is actually writable by the container user (PUID/PGID mismatch).
Symptom: curl -fsSL https://claude.ai/install.sh | bash hangs indefinitely during docker build.
Cause: Installer prompts or behaves differently when WORKDIR is root-owned.
Fix: Already handled in the Dockerfile — WORKDIR /workspace and USER claude are set before the installer runs.
Symptom: New settings/memory from updated image aren't applied.
Cause: Sentinel file .holyclaude-bootstrapped exists, so bootstrap is skipped.
Fix:
rm ./data/claude/.holyclaude-bootstrapped
docker compose restart holyclaudeIf your volumes are on a Samba/CIFS network share (common with Hyper-V VMs, NAS devices):
File watchers must use polling:
- CHOKIDAR_USEPOLLING=1
- WATCHFILES_FORCE_POLLING=truenpm global installs and Python .local can break. This is why HolyClaude keeps .npm and .local in container-local storage — don't mount them on network shares.
If you need symlinks on CIFS, add mfsymlinks to your mount options:
//server/share /mnt/share cifs mfsymlinks,... 0 0
Any SQLite database on CIFS will get "database is locked" errors. Keep SQLite databases on local storage.
chmod/chown silently succeed but don't actually change permissions on CIFS (depends on mount options). Use uid=, gid=, file_mode=, dir_mode= in mount options to set permissions.
If your issue isn't covered here:
- Check the GitHub Issues for existing reports
- Open a new issue with:
- Your docker-compose file (redact API keys)
- Output of
docker logs holyclaude - What you expected vs what happened