Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d868d96
Added railway entry
sphinxcode Jan 27, 2026
da6737c
Easy install Claude Code
sphinxcode Jan 29, 2026
f81bbd1
Railway template
sphinxcode Jan 29, 2026
02cd81e
Added filepath installation
sphinxcode Jan 29, 2026
5dd4e6a
Force rebuild with gosu installation
sphinxcode Jan 29, 2026
d384d20
Add RUN_AS_USER variable - default root, set to coder for non-root
sphinxcode Jan 29, 2026
7035b6d
Fix entrypoint - call code-server directly with args
sphinxcode Jan 29, 2026
8299614
Remove duplicate railway.json config
sphinxcode Jan 29, 2026
8077b23
Added deployment options
sphinxcode Jan 29, 2026
82ca428
Added clauder user and backward compatibility
sphinxcode Jan 29, 2026
19e5f26
Uploaded logo
sphinxcode Jan 29, 2026
1266e7d
Fixed clauder as default volume path
sphinxcode Jan 29, 2026
c2d4bff
Fixed railway setup
sphinxcode Jan 29, 2026
babd140
Fixed claude installation
sphinxcode Jan 29, 2026
2c056d2
Auto install claude
sphinxcode Jan 29, 2026
a62129a
Auto generate domain
sphinxcode Jan 29, 2026
b5d6416
Clauder now has sudo priveleges
sphinxcode Jan 29, 2026
d16badf
Python enabled
sphinxcode Jan 29, 2026
e5eeb81
Added sudo for clauder
sphinxcode Jan 29, 2026
b889cb6
Fixed global npm path installation
sphinxcode Jan 29, 2026
f2ea20c
Fixed node js installer
sphinxcode Jan 29, 2026
9fa73c5
feat: upgrade Node.js to 22 LTS
sphinxcode Jan 29, 2026
b0e845c
Uploaded iphone mockup
sphinxcode Jan 29, 2026
14e44df
Fixing README Location
sphinxcode Jan 29, 2026
d0c8f78
GitHub Actions workflow file
sphinxcode Jan 29, 2026
f148984
Added readme
sphinxcode Jan 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Ignore everything by default
**
!release-packages
!ci

# Include only what's needed for the Railway build
!Dockerfile
!railway-entrypoint.sh
!railway.json
46 changes: 46 additions & 0 deletions .github/workflows/deploy-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Builds and pushes the Docker image to GitHub Container Registry
name: Publish Docker Image

on:
push:
branches: [main]
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=sha,prefix=

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
116 changes: 116 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# ============================================================================
# Claude Code Server - Browser-based VS Code with AI Coding Assistants
# https://github.com/sphinxcode/claude-code-server
# ============================================================================

FROM codercom/code-server:4.108.0

USER root

# ============================================================================
# SYSTEM DEPENDENCIES
# Install gosu, Node.js 22, Python/uv, and essential tools
# Cache bust: 2026-01-30-v6
# ============================================================================

RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
gosu \
nodejs \
python3 \
python3-pip \
python3-venv \
pipx \
git \
curl \
wget \
unzip \
jq \
htop \
vim \
nano \
ripgrep \
&& npm install -g npm@latest \
&& pip3 install --break-system-packages uv \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# ============================================================================
# PERSISTENCE CONFIGURATION
# Default to /home/clauder for new deployments
# ============================================================================

ENV HOME=/home/clauder
ENV USER=clauder

# 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

# 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}"

# Custom startup scripts directory
ENV ENTRYPOINTD=/home/clauder/entrypoint.d

# ============================================================================
# USER SETUP
# Create clauder user (UID 1000) with passwordless sudo
# - Stays non-root for Claude YOLO mode compatibility
# - Can use sudo for package installs (apt, npm -g, pip, etc.)
# ============================================================================

# Install sudo if not present, then configure user
RUN apt-get update && apt-get install -y sudo \
&& rm -rf /var/lib/apt/lists/* \
&& (groupadd -g 1000 clauder 2>/dev/null || true) \
&& (useradd -m -s /bin/bash -u 1000 -g 1000 clauder 2>/dev/null || usermod -l clauder -d /home/clauder -m coder 2>/dev/null || true) \
&& (groupmod -n clauder coder 2>/dev/null || true) \
&& mkdir -p /etc/sudoers.d \
&& echo "clauder ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/clauder \
&& chmod 0440 /etc/sudoers.d/clauder \
&& chown root:root /etc/sudoers.d/clauder

# ============================================================================
# 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

# Copy our custom entrypoint (replaces base image's entrypoint)
COPY railway-entrypoint.sh /usr/bin/railway-entrypoint.sh
RUN chmod +x /usr/bin/railway-entrypoint.sh

# ============================================================================
# CLAUDE CODE CLI INSTALLATION
# Install globally via npm - this is the official package
# ============================================================================

RUN npm install -g @anthropic-ai/claude-code \
&& echo "Claude CLI installed: $(claude --version 2>/dev/null || echo 'checking...')"

# ============================================================================
# RUNTIME
# Stay as root - entrypoint handles user switching based on RUN_AS_USER
# ============================================================================

WORKDIR /home/clauder/workspace
EXPOSE 8080

# Use our entrypoint which calls code-server directly
ENTRYPOINT ["/usr/bin/railway-entrypoint.sh"]


222 changes: 222 additions & 0 deletions PROJECT_BRIEF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
# Project Brief: Code-Server Railway Template

**Project:** VSCode Cloud IDE with Claude Code Integration
**Repository:** `sphinxcode/code-server`
**Railway Service:** `code-ajna` (claude.sphinx.codes)
**Status:** In Progress

---

## Executive Summary

Create a production-ready, marketable Railway template that provides browser-based VS Code (code-server) with pre-installed Claude Code CLI, persistent extensions, and configurable user permissions.

---

## Original Problems

### 1. Root User Permission Issues
- **Symptom:** code-server displayed security warnings about running as root
- **Cause:** `RAILWAY_RUN_UID=0` was set, forcing container to run as root
- **Impact:** Couldn't bypass certain settings, security warnings in UI

### 2. Non-Persistent Tools
- **Symptom:** npm, npx, extensions disappeared after redeployment
- **Cause:** Container running as root with `HOME=/root` (ephemeral), while volume mounted at `/home/coder`
- **Impact:** Users lost installed tools and configurations on each deploy

### 3. Claude Code Not Pre-installed
- **Request:** Template users should have Claude Code CLI available out-of-the-box
- **Requirement:** Support for `claude --dangerously-skip-permissions` flag

---

## Solution Architecture

### Infrastructure
| Component | Value |
|-----------|-------|
| Base Image | `codercom/code-server:latest` |
| Volume Mount | `/home/coder` (Railway volume) |
| Service URL | `claude.sphinx.codes` |
| Project ID | `59ae99d7-dc99-4642-ae06-642cd8d8c83a` |
| Service ID | `34522d52-ba69-4fcf-83b7-210a765a0a76` |
| Environment ID | `a921a831-e480-451b-b9c7-04ce2f647c68` |

### Key Files Modified

#### [Dockerfile](file:///E:/AI-Terminal/sphinxcode/code-server/Dockerfile)
- Installs `gosu` for proper user switching
- Installs Node.js 20 LTS as fallback
- Installs Claude Code CLI to `/usr/local/bin/claude`
- Installs essential tools: ripgrep, jq, htop, vim, nano
- Sets up XDG directories for persistence
- PATH prioritizes volume paths over image paths

#### [railway-entrypoint.sh](file:///E:/AI-Terminal/sphinxcode/code-server/railway-entrypoint.sh)
- Configurable user via `RUN_AS_USER` variable
- Shell profile setup (`.bashrc`, `.profile`) with PATH
- Permission fixing via `chown` when switching users
- User switching via `gosu` when `RUN_AS_USER=coder`
- Root symlinks for persistence when staying as root
- First-run initialization with welcome README
- Environment verification logging

#### [README.md](file:///E:/AI-Terminal/sphinxcode/code-server/README.md)
- Documentation for all configuration variables
- Quick start guide for Claude Code
- Update behavior explanation
- Troubleshooting guide

---

## Configuration Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `PASSWORD` | Yes | - | code-server login password |
| `RUN_AS_USER` | No | `root` | Set to `coder` for non-root execution |
| `CODER_HOME` | No | `/home/coder` | Volume mount path |
| `CODER_UID` | No | `1000` | User ID when switching to coder |
| `CODER_GID` | No | `1000` | Group ID when switching to coder |
| `GIT_REPO` | No | - | Repository to auto-clone on startup |

---

## Persistence Strategy

### Volume-First PATH Priority
```
$HOME/.local/bin ← User-installed tools (Claude, etc.)
$HOME/.local/node/bin ← User-installed Node.js
$HOME/.claude/local ← Claude Code from volume
/usr/local/bin ← Image fallback (Claude)
/usr/bin ← Image fallback (Node.js)
```

### What Persists (on volume)
- Extensions: `~/.local/share/code-server/extensions/`
- Claude Code: `~/.local/bin/claude` or `~/.claude/`
- Claude auth: `~/.claude/` (API keys, settings)
- Node.js: `~/.local/node/` (if user installs)
- Shell config: `~/.bashrc`, `~/.profile`
- Workspace: `~/workspace/`

### What Auto-Updates (from image)
- Node.js fallback in `/usr/bin/node`
- Claude Code fallback in `/usr/local/bin/claude`
- System packages (git, curl, etc.)

---

## User Modes

### Root Mode (Default)
```
RUN_AS_USER=root (or not set)
```
- Stays as root user
- Creates symlinks from `/root/` → `/home/coder/` for persistence
- Compatible with existing volumes owned by root

### Coder Mode (Recommended for Claude)
```
RUN_AS_USER=coder
```
- Switches to coder user (UID 1000) via gosu
- Fixes volume permissions before switching
- No root warnings in code-server UI
- Required for `claude --dangerously-skip-permissions`

---

## Issues Encountered & Resolved

### 1. Railway Start Command Override
- **Problem:** Railway had a custom start command that bypassed our ENTRYPOINT
- **Solution:** Cleared the start command via `mcp_railway_service_update`

### 2. Docker Layer Caching
- **Problem:** Railway used cached layers, ignoring our changes
- **Solution:** Added cache-bust comments to force rebuild

### 3. Claude Installs to ~/.local/bin
- **Problem:** Assumed Claude installed to `~/.claude/local/`
- **Solution:** Updated PATH to include `$HOME/.local/bin` first

### 4. Shell Profile Not Configured
- **Problem:** New terminals didn't have PATH set
- **Solution:** Entrypoint now writes to `.bashrc` and `.profile`

---

## Current Status

### Completed ✅
- Dockerfile with gosu, Node.js, Claude Code
- Entrypoint with RUN_AS_USER variable
- Shell profile auto-configuration
- PATH priority for volume-installed tools
- README documentation
- Removed conflicting `railway.json`
- Cleared Railway start command override
- Set `RUN_AS_USER=coder` on Railway

### Pending Verification 🔄
- Confirm entrypoint output appears in Railway logs
- Verify user switches to `coder` (not `root@xxx`)
- Test `claude --dangerously-skip-permissions` works
- Confirm Claude authentication persists

---

## Expected Startup Logs

```
╔══════════════════════════════════════════════════════════════════════════╗
║ VSCode Cloud IDE - Claude Code & Node.js Ready ║
╚══════════════════════════════════════════════════════════════════════════╝

→ Initial user: root (UID: 0)
→ RUN_AS_USER: coder
→ HOME: /home/coder

→ Running setup as root...
→ Setting up shell profile...
✓ Shell profile configured
→ Fixing permissions for coder user (UID: 1000)...
✓ Permissions fixed
→ Switching to coder user via gosu...

→ Running as: coder (UID: 1000)

Environment:
→ Node.js: v20.x.x [volume/image]
→ npm: x.x.x
→ git: x.x.x
→ claude: x.x.x [volume/image]

════════════════════════════════════════════════════════════════════════
Starting code-server as coder...
════════════════════════════════════════════════════════════════════════
```

---

## Files Summary

| File | Location | Purpose |
|------|----------|---------|
| `Dockerfile` | sphinxcode/code-server | Image build configuration |
| `railway-entrypoint.sh` | sphinxcode/code-server | Container startup script |
| `README.md` | sphinxcode/code-server | User documentation |
| `railway.toml` | sphinxcode/code-server | Railway deployment config |

---

## Next Steps

1. **Verify Deployment** - Check if entrypoint runs and user switches properly
2. **Test Claude** - Authenticate and run `claude --dangerously-skip-permissions`
3. **Create Railway Template** - Make template public for others to deploy
4. **Update Template Docs** - Include volume attachment instructions
Loading