This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a LinuxServer.io Docker container for code-server (VS Code running on a remote server, accessible through the browser). The repository contains multiple Dockerfiles and follows the LinuxServer.io build pipeline conventions.
docker build --no-cache --pull -t lscr.io/linuxserver/code-server:latest .docker build --no-cache --pull -f Dockerfile.custom -t lscr.io/linuxserver/code-server:latest .First enable QEMU for cross-platform builds:
docker run --rm --privileged lscr.io/linuxserver/qemu-static --resetThen build with the ARM64 Dockerfile:
docker build --no-cache --pull -f Dockerfile.aarch64 -t lscr.io/linuxserver/code-server:latest .- Dockerfile - Standard AMD64 build (auto-generated, do NOT edit directly)
- Dockerfile.aarch64 - ARM64 build (auto-generated, do NOT edit directly)
- Dockerfile.custom - Custom variant with Claude Code, Node.js, and Google Cloud CLI pre-installed
- README.md - Auto-generated from
readme-vars.yml(do NOT edit directly) - Jenkinsfile - Auto-generated from
jenkins-vars.yml(do NOT edit directly) - readme-vars.yml - Template variables for generating README.md
- jenkins-vars.yml - Build pipeline configuration
The /root directory contains files copied into the container at build time:
- root/etc/s6-overlay/s6-rc.d/init-code-server/run - Initialization script that sets up sudo access, SSH permissions, and directory structure
- root/etc/s6-overlay/s6-rc.d/init-claude-code/run - Initialization script that installs/updates Claude Code in user-writable location for auto-updates
- root/etc/s6-overlay/s6-rc.d/svc-code-server/run - Service script that launches code-server with appropriate flags
- root/usr/local/bin/install-extension - Helper script for installing VS Code extensions (used by Docker mods)
The Dockerfile.custom variant includes:
Development Tools:
- Claude Code: Installed at first startup via init script to
/config/.npm-globalfor auto-update support (latest from npm registry) - GitHub CLI (
gh): Latest version from official GitHub CLI apt repository - Google Cloud CLI (
gcloud): Latest version from official Google Cloud apt repository - Node.js: Latest stable version auto-detected from nodejs.org, supporting both amd64 and arm64 architectures
AI API Tools:
- OpenAI CLI: Latest Python package for accessing OpenAI APIs including Codex (
openai) - Google Generative AI: Latest Python SDK for Gemini API (
google-generativeai)
Environment Variables: Pre-configured for Anthropic's Vertex AI integration:
CLAUDE_CODE_USE_VERTEX=1CLOUD_ML_REGION=us-east5ANTHROPIC_VERTEX_PROJECT_ID=oa-data-btdpexploration-npDISABLE_PROMPT_CACHING=0
NEVER edit README.md directly. Instead:
- Edit
readme-vars.yml - Use the Jenkins Builder to regenerate files
Common variables:
project_blurb- Description above the project logoapp_setup_block- "Application Setup" section contentparam_env_vars/opt_param_env_vars- Environment variable documentationchangelogs- Version history
When adding packages to ANY Dockerfile:
- Add packages to ALL architecture Dockerfiles (Dockerfile, Dockerfile.aarch64)
- Keep packages in alphabetical order
- Update the changelog in
readme-vars.yml:- {date: "DD.MM.YY:", desc: "Added some love to templates"}
Changes to files in /root (init scripts, service scripts) also require updating the changelog in readme-vars.yml.
The container uses s6-overlay for process supervision. The initialization flow:
-
init-code-server runs first:
- Creates
/config/{extensions,data,workspace,.ssh}directories - Sets up sudo access if
SUDO_PASSWORDorSUDO_PASSWORD_HASHis set - Manages ownership/permissions (skips
/config/workspacecontents for performance) - Sets SSH directory permissions (700 for directories, 600 for private keys, 644 for public keys)
- Creates
-
init-claude-code runs after config initialization:
- Creates
/config/.npm-globaldirectory for user-writable npm packages - Installs Claude Code as user
abc(first startup only) - Checks for and applies updates on subsequent startups
- Enables Claude Code's built-in auto-update feature
- Creates
-
svc-code-server starts the service:
- Configures authentication (password, hashed password, or none)
- Sets up proxy domain if specified
- Launches code-server bound to
0.0.0.0:8443(or[::]:8443for non-root) - Opens default workspace (
DEFAULT_WORKSPACEor/config/workspace)
Key variables supported by the container:
PUID/PGID- User/group IDs for volume permissionsPASSWORD/HASHED_PASSWORD- Web UI authenticationSUDO_PASSWORD/SUDO_PASSWORD_HASH- Terminal sudo accessPROXY_DOMAIN- Subdomain proxying configurationDEFAULT_WORKSPACE- Directory opened by defaultPWA_APPNAME- Progressive Web App name
Always test builds locally before submitting PRs. Each commit after PR creation triggers a full build pipeline.
The workflow builds for both linux/amd64 and linux/arm64. Ensure:
- Architecture detection uses
uname -mcorrectly - Both
x86_64→amd64/x64andaarch64→arm64mappings are defined - Download URLs support both architectures
The abc user is created by the LinuxServer.io baseimage during container startup, not at build time. Therefore:
- Never use
chown abc:abcin Dockerfile RUN commands - Never use
su abcin Dockerfile RUN commands - Install packages globally as root, not as a specific user
- User-specific configuration should be done in init scripts (in
/root/etc/s6-overlay/)
/config is a volume mount point. Do not install application data there during build:
- Anything installed to
/configat build time will be overwritten at runtime - Install global packages to system paths (
/usr/local,/app, etc.) - User data belongs in init scripts that run after volumes are mounted