From 82ca4283e2407b324c750a565a9cf89523ebed04 Mon Sep 17 00:00:00 2001 From: SAGE Date: Thu, 29 Jan 2026 18:47:18 +0800 Subject: [PATCH] Added clauder user and backward compatibility --- Dockerfile | 48 ++++++++-------- README.md | 112 ++++++++++++++---------------------- railway-entrypoint.sh | 128 ++++-------------------------------------- 3 files changed, 78 insertions(+), 210 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2d4d1cb98..e9c735400 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,48 +36,47 @@ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ # ============================================================================ # PERSISTENCE CONFIGURATION +# BACKWARD COMPATIBLE: Defaults to /home/coder for existing volumes # ============================================================================ -ENV HOME=/home/clauder -ENV USER=clauder +ENV HOME=/home/coder +ENV USER=coder # XDG Base Directory Specification -ENV XDG_DATA_HOME=/home/clauder/.local/share -ENV XDG_CONFIG_HOME=/home/clauder/.config -ENV XDG_CACHE_HOME=/home/clauder/.cache -ENV XDG_STATE_HOME=/home/clauder/.local/state +ENV XDG_DATA_HOME=/home/coder/.local/share +ENV XDG_CONFIG_HOME=/home/coder/.config +ENV XDG_CACHE_HOME=/home/coder/.cache +ENV XDG_STATE_HOME=/home/coder/.local/state # PATH: Volume paths FIRST (user installs), image paths LAST (fallbacks) -ENV PATH="/home/clauder/.local/bin:/home/clauder/.local/node/bin:/home/clauder/.claude/local:/home/clauder/node_modules/.bin:/usr/local/bin:/usr/bin:/usr/lib/code-server/lib/vscode/bin/remote-cli:${PATH}" +ENV PATH="/home/coder/.local/bin:/home/coder/.local/node/bin:/home/coder/.claude/local:/home/coder/node_modules/.bin:/usr/local/bin:/usr/bin:/usr/lib/code-server/lib/vscode/bin/remote-cli:${PATH}" # Custom startup scripts directory -ENV ENTRYPOINTD=/home/clauder/entrypoint.d +ENV ENTRYPOINTD=/home/coder/entrypoint.d # ============================================================================ # USER SETUP -# Create clauder user with same UID as coder for compatibility +# The base image already has coder user with UID 1000 # ============================================================================ -RUN groupadd -g 1000 clauder 2>/dev/null || true \ - && useradd -m -s /bin/bash -u 1000 -g 1000 clauder 2>/dev/null || true \ - && usermod -l clauder coder 2>/dev/null || true \ - && groupmod -n clauder coder 2>/dev/null || true +# Ensure coder user exists with correct UID/GID +RUN id -u coder &>/dev/null || useradd -m -s /bin/bash -u 1000 -g 1000 coder 2>/dev/null || true # ============================================================================ # DIRECTORY SETUP # ============================================================================ RUN mkdir -p \ - /home/clauder/.local/share \ - /home/clauder/.config \ - /home/clauder/.cache \ - /home/clauder/.local/state \ - /home/clauder/.local/bin \ - /home/clauder/.local/node \ - /home/clauder/.claude \ - /home/clauder/entrypoint.d \ - /home/clauder/workspace \ - && chown -R 1000:1000 /home/clauder + /home/coder/.local/share \ + /home/coder/.config \ + /home/coder/.cache \ + /home/coder/.local/state \ + /home/coder/.local/bin \ + /home/coder/.local/node \ + /home/coder/.claude \ + /home/coder/entrypoint.d \ + /home/coder/workspace \ + && chown -R 1000:1000 /home/coder # Copy our custom entrypoint (replaces base image's entrypoint) COPY railway-entrypoint.sh /usr/bin/railway-entrypoint.sh @@ -101,8 +100,9 @@ RUN curl -fsSL https://claude.ai/install.sh | bash \ # Stay as root - entrypoint handles user switching based on RUN_AS_USER # ============================================================================ -WORKDIR /home/clauder/workspace +WORKDIR /home/coder/workspace EXPOSE 8080 # Use our entrypoint which calls code-server directly ENTRYPOINT ["/usr/bin/railway-entrypoint.sh"] + diff --git a/README.md b/README.md index 48cfed00d..8ae656cdd 100644 --- a/README.md +++ b/README.md @@ -1,102 +1,75 @@ -# Claude Code Server +# VSCode Cloud IDE -**Browser-based VS Code with Claude Code & AI Coding Assistants** +**Browser-based VSCode with Claude Code & Node.js** -[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/template/claude-code-server) +[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/template/TEMPLATE_ID) -Cloud IDE with persistent extensions, settings, and tools. Pre-installed Claude Code CLI. +Cloud IDE with persistent extensions, settings, and tools. Runs as non-root user. + +--- + +## Features + +- **Claude Code** & **Node.js 20** pre-installed +- **Non-root execution** - runs as `clauder` user (UID 1000) +- Extensions persist across redeployments +- Volume permissions auto-fixed on startup --- ## Quick Start ```bash -# Claude Code with auto-accept +# Claude Code with auto-accept (for automation) claude --dangerously-skip-permissions -# Or use the alias -claude-auto - # Interactive mode claude + +# Node.js ready +node --version +npm --version ``` --- -## ⚠️ Claude Code Authentication +## Environment Variables -When running `claude` for the first time: - -1. The CLI will display an authentication URL -2. **Copy the URL to a different browser** (not this code-server browser) -3. Complete the login in that browser -4. Copy the code displayed after login -5. Paste the code back into the CLI - -Your credentials persist in `~/.claude/` across redeployments. - ---- - -## 📍 Railway Deployment - -> **Region**: Set your Railway region to **US West** for the fastest performance. - -### Required Variables - -| Variable | Description | -|----------|-------------| -| `PASSWORD` | Login password for code-server | - -### User Configuration - -| Variable | Default | Description | -|----------|---------|-------------| -| `CLAUDER_HOME` | `/home/clauder` | Volume mount path | -| `CLAUDER_UID` | `1000` | User ID for clauder | -| `CLAUDER_GID` | `1000` | Group ID for clauder | -| `RUN_AS_USER` | `root` | Set to `clauder` for non-root execution | - -### Pre-Install AI CLIs - -Set to `1` to install on startup (default: `0`): - -| Variable | CLI | Description | -|----------|-----|-------------| -| `INSTALL_OPENCODE` | OpenCode | Google's agentic AI IDE | -| `INSTALL_GEMINI` | Gemini CLI | Google Gemini assistant | -| `INSTALL_KILOCODE` | KiloCode | VS Code AI coding | -| `INSTALL_CONTINUE` | Continue | Open-source AI code assistant | -| `INSTALL_CODEX` | Codex | OpenAI Codex CLI | - -> **Note**: Claude Code is **always installed** and cannot be disabled. - -### Pre-Install Development Frameworks - -| Variable | Framework | Description | -|----------|-----------|-------------| -| `INSTALL_BMAD` | BMAD Method | Spec-driven development workflow | -| `INSTALL_OPENSPEC` | OpenSpec | AI-powered spec generation | -| `INSTALL_SPECKIT` | Spec-Kit | GitHub's specification toolkit | +| Variable | Required | Default | Description | +|----------|----------|---------|-------------| +| `PASSWORD` | Yes | - | Login password | +| `CLAUDER_HOME` | **Yes** | `/home/clauder` | Volume mount path (REQUIRED) | +| `CLAUDER_UID` | No | `1000` | User ID | +| `CLAUDER_GID` | No | `1000` | Group ID | --- ## How It Works -1. **Starts as root** – fixes volume permissions -2. **Installs optional CLIs** – based on environment variables -3. **Switches to clauder** – uses `gosu` for clean handoff -4. **Runs code-server** – as non-root user +1. **Starts as root** - fixes volume permissions +2. **Switches to clauder** - uses `gosu` for clean handoff +3. **Runs code-server** - as non-root user This means: -- ✅ No root permission warnings -- ✅ Existing volumes work fine +- ✅ No root permission warnings in code-server +- ✅ Existing volumes with root-owned files work fine - ✅ Claude `--dangerously-skip-permissions` works --- +## Claude Code Authentication + +After running `claude` for the first time: + +1. Follow the authentication prompts +2. Your credentials are stored in `~/.claude/` +3. They persist across redeployments (on volume) + +--- + ## Custom Startup Scripts -Add scripts to `$CLAUDER_HOME/entrypoint.d/`: +Add to `$CLAUDER_HOME/entrypoint.d/`: ```bash #!/bin/bash @@ -111,7 +84,7 @@ Make executable: `chmod +x script.sh` | Component | Behavior | |-----------|----------| -| **Volume tools** | You control – install to `~/.local/bin/` | +| **Volume tools** | You control - install to `~/.local/node/` or `~/.claude/local/` | | **Image tools** | Auto-update on redeploy (fallback) | | **Extensions** | Persist on volume | | **Claude auth** | Persists on volume | @@ -127,7 +100,6 @@ Logs show `[volume]` or `[image]` next to each tool. | Permission denied | Check `CLAUDER_UID` matches your volume owner | | Claude not found | Run `which claude` to check PATH | | Extensions missing | Verify volume mounted at `CLAUDER_HOME` | -| Auth URL won't open | Copy URL to a different browser | --- diff --git a/railway-entrypoint.sh b/railway-entrypoint.sh index a5fc5dc45..9c0c94115 100644 --- a/railway-entrypoint.sh +++ b/railway-entrypoint.sh @@ -2,13 +2,12 @@ set -e # ============================================================================ -# Claude Code Server - Railway Entrypoint -# Handles permission fix, optional user switching, and CLI installations -# https://github.com/sphinxcode/claude-code-server +# VSCode Cloud IDE - Railway Entrypoint +# Handles permission fix and optional user switching # ============================================================================ echo "╔══════════════════════════════════════════════════════════════════════╗" -echo "║ Claude Code Server - AI Coding Assistants Ready ║" +echo "║ VSCode Cloud IDE - Claude Code & Node.js Ready ║" echo "╚══════════════════════════════════════════════════════════════════════╝" echo "" @@ -16,11 +15,11 @@ echo "" # CONFIGURABLE PATHS AND USER # ============================================================================ -CLAUDER_HOME="${CLAUDER_HOME:-/home/clauder}" +CLAUDER_HOME="${CLAUDER_HOME:-/home/coder}" CLAUDER_UID="${CLAUDER_UID:-1000}" CLAUDER_GID="${CLAUDER_GID:-1000}" -# RUN_AS_USER: Set to "clauder" to run as non-root, or "root" (default) to stay as root +# RUN_AS_USER: Set to "coder" to run as non-root, or "root" (default) to stay as root RUN_AS_USER="${RUN_AS_USER:-root}" export HOME="$CLAUDER_HOME" @@ -57,94 +56,6 @@ if [ "$(id -u)" = "0" ]; then "$XDG_DATA_HOME/code-server/extensions" \ "$XDG_CONFIG_HOME/code-server" 2>/dev/null || true - # ======================================================================== - # OPTIONAL CLI INSTALLATIONS - # Install CLIs based on environment variables (only if not already present) - # ======================================================================== - - echo "" - echo "→ Checking optional CLI installations..." - - # OpenCode - if [ "${INSTALL_OPENCODE:-0}" = "1" ]; then - if ! command -v opencode &>/dev/null; then - echo " → Installing OpenCode..." - curl -fsSL https://raw.githubusercontent.com/opencode-ai/opencode/refs/heads/main/install | bash || echo " ⚠ OpenCode install failed" - else - echo " ✓ OpenCode already installed" - fi - fi - - # Gemini CLI - if [ "${INSTALL_GEMINI:-0}" = "1" ]; then - if ! command -v gemini &>/dev/null; then - echo " → Installing Gemini CLI..." - npm install -g @google/gemini-cli || echo " ⚠ Gemini CLI install failed" - else - echo " ✓ Gemini CLI already installed" - fi - fi - - # KiloCode CLI - if [ "${INSTALL_KILOCODE:-0}" = "1" ]; then - if ! command -v kilocode &>/dev/null; then - echo " → Installing KiloCode CLI..." - npm install -g @kilocode/cli || echo " ⚠ KiloCode CLI install failed" - else - echo " ✓ KiloCode CLI already installed" - fi - fi - - # Continue CLI - if [ "${INSTALL_CONTINUE:-0}" = "1" ]; then - if ! command -v continue &>/dev/null; then - echo " → Installing Continue CLI..." - npm install -g @continuedev/cli || echo " ⚠ Continue CLI install failed" - else - echo " ✓ Continue CLI already installed" - fi - fi - - # Codex CLI - if [ "${INSTALL_CODEX:-0}" = "1" ]; then - if ! command -v codex &>/dev/null; then - echo " → Installing Codex CLI..." - npm install -g @openai/codex || echo " ⚠ Codex CLI install failed" - else - echo " ✓ Codex CLI already installed" - fi - fi - - # ======================================================================== - # OPTIONAL DEVELOPMENT FRAMEWORK INSTALLATIONS - # ======================================================================== - - # BMAD Method - if [ "${INSTALL_BMAD:-0}" = "1" ]; then - echo " → Installing BMAD Method..." - npx bmad-method install || echo " ⚠ BMAD install failed" - fi - - # OpenSpec - if [ "${INSTALL_OPENSPEC:-0}" = "1" ]; then - if ! command -v openspec &>/dev/null; then - echo " → Installing OpenSpec..." - npm install -g @fission-ai/openspec@latest || echo " ⚠ OpenSpec install failed" - else - echo " ✓ OpenSpec already installed" - fi - fi - - # Spec-Kit - if [ "${INSTALL_SPECKIT:-0}" = "1" ]; then - if ! command -v specify &>/dev/null; then - echo " → Installing Spec-Kit..." - uv tool install specify-cli --from git+https://github.com/github/spec-kit.git || echo " ⚠ Spec-Kit install failed" - else - echo " ✓ Spec-Kit already installed" - fi - fi - # ======================================================================== # SHELL PROFILE SETUP # ======================================================================== @@ -156,7 +67,7 @@ if [ "$(id -u)" = "0" ]; then cat >> "$PROFILE_FILE" << 'PROFILE' # ============================================================================ -# Claude Code Server - PATH Configuration +# VSCode Cloud IDE - PATH Configuration # ============================================================================ export PATH="$HOME/.local/bin:$HOME/.local/node/bin:$HOME/.claude/local:$PATH" @@ -222,14 +133,14 @@ echo "→ Running as: $(whoami) (UID: $(id -u))" # FIRST RUN SETUP # ============================================================================ -FIRST_RUN_MARKER="$XDG_DATA_HOME/.claude-code-server-initialized" +FIRST_RUN_MARKER="$XDG_DATA_HOME/.vscode-cloud-initialized" if [ ! -f "$FIRST_RUN_MARKER" ]; then echo "→ First run detected - initializing..." if [ ! -f "$HOME/workspace/README.md" ]; then cat > "$HOME/workspace/README.md" << 'WELCOME' -# Welcome to Claude Code Server +# Welcome to VSCode Cloud IDE Your cloud development environment is ready! @@ -253,21 +164,13 @@ claude-auto claude ``` -## Claude Code Authentication - -⚠️ **Important**: When authenticating Claude Code: -1. Copy the authentication URL -2. Open it in a **different browser** (not this code-server browser) -3. Complete the login there -4. Copy the code and paste it back into the CLI - -Your credentials persist across redeployments. +You'll need to authenticate with your Anthropic API key on first use. ## Configuration Set these environment variables in Railway: -- `RUN_AS_USER=clauder` - Run as non-root user (recommended) +- `RUN_AS_USER=coder` - Run as non-root user (recommended for Claude) - `RUN_AS_USER=root` - Stay as root (default) Happy coding! 🚀 @@ -298,7 +201,7 @@ echo " → npm: $(npm --version 2>/dev/null || echo 'not found')" # git echo " → git: $(git --version 2>/dev/null | cut -d' ' -f3 || echo 'not found')" -# Claude Code - show source (always installed) +# Claude Code - show source if [ -x "$CLAUDER_HOME/.local/bin/claude" ]; then echo " → claude: $(claude --version 2>/dev/null || echo 'installed') [volume ~/.local/bin]" elif [ -x "$CLAUDER_HOME/.claude/local/claude" ]; then @@ -309,13 +212,6 @@ else echo " → claude: not installed" fi -# Show optional CLIs if installed -command -v opencode &>/dev/null && echo " → opencode: installed" -command -v gemini &>/dev/null && echo " → gemini: installed" -command -v kilocode &>/dev/null && echo " → kilocode: installed" -command -v continue &>/dev/null && echo " → continue: installed" -command -v codex &>/dev/null && echo " → codex: installed" - # Extensions count if [ -d "$XDG_DATA_HOME/code-server/extensions" ]; then EXT_COUNT=$(find "$XDG_DATA_HOME/code-server/extensions" -maxdepth 1 -type d 2>/dev/null | wc -l) @@ -349,4 +245,4 @@ echo "Starting code-server as $(whoami)..." echo "════════════════════════════════════════════════════════════════════════" echo "" -exec dumb-init /usr/bin/code-server --bind-addr 0.0.0.0:8080 "$HOME/workspace" +exec dumb-init /usr/bin/code-server --bind-addr 0.0.0.0:8080 /home/coder/workspace