mirror of
https://github.com/coder/code-server.git
synced 2026-02-19 18:01:15 +08:00
Added clauder user and backward compatibility
This commit is contained in:
parent
8077b23bd4
commit
82ca4283e2
48
Dockerfile
48
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"]
|
||||
|
||||
|
||||
112
README.md
112
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**
|
||||
|
||||
[](https://railway.com/template/claude-code-server)
|
||||
[](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 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user