Merge f148984d6d34947ccd44ab000c27ebeea992ca56 into 9184b645cc7aa41b750e2f2ef956f2896512dd84

This commit is contained in:
Sphinx Code 2026-02-12 20:07:14 -07:00 committed by GitHub
commit 4f2bdbb2ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 776 additions and 2 deletions

View File

@ -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
.github/workflows/deploy-image.yml vendored Normal file
View File

@ -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
Dockerfile Normal file
View File

@ -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
PROJECT_BRIEF.md Normal file
View File

@ -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

82
README.md Normal file
View File

@ -0,0 +1,82 @@
# Claude Code Server
![Claude Code Server Logo](https://raw.githubusercontent.com/sphinxcode/claude-code-server/refs/heads/main/public/claude-code-server-logo.png)
**Browser-based VS Code with Claude Code CLI pre-installed**
[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/template/claude-code-server)
![Mobile Mockup](https://raw.githubusercontent.com/sphinxcode/claude-code-server/refs/heads/main/public/iphone_mockup.png)
Deploy a full VS Code development environment in the cloud with Claude Code CLI ready to go. Access it from any browser, on any device. Code with AI assistance anywhere.
---
## Features
- **Claude Code CLI Pre-installed** Start AI-assisted coding immediately with `claude` or `claude-auto` (YOLO mode)
- **Browser-Based VS Code** Full IDE experience accessible from any device
- **Persistent Storage** Your extensions, settings, and projects survive redeploys
- **Non-Root Security** Runs as the `clauder` user with optional sudo access
- **One-Click Deploy** Deploy to Railway in 60 seconds
---
## Quick Start
### Deploy to Railway
Click the button above, or:
1. Go to [Railway Templates](https://railway.com/templates)
2. Search for "Claude Code Server"
3. Click **Deploy** and set your `PASSWORD`
4. Attach a volume to `/home/clauder`
5. Open the generated domain in your browser
### First Login
1. Enter the password you set
2. Open the terminal in VS Code
3. Run `claude` to start coding with AI
---
## Configuration
### Required Variables
| Variable | Description |
|------------|------------------------------------|
| `PASSWORD` | Login password for the web IDE |
### Optional Variables
| Variable | Default | Description |
|----------------|--------------------------------|------------------------------------------|
| `CLAUDER_HOME` | `/home/clauder` | Volume mount path |
| `RUN_AS_USER` | `clauder` | Set to `root` if you need root access |
| `APP_NAME` | `Claude Code Server` | Login page title |
| `WELCOME_TEXT` | `Welcome to Claude Code Server`| Login page message |
### Volume Configuration
> ⚠️ **CRITICAL**: Without a volume, ALL data is lost on every redeploy!
| Setting | Value |
|----------------|------------------|
| **Mount Path** | `/home/clauder` |
| **Size** | 5GB+ recommended |
---
## Built With
- [code-server](https://github.com/coder/code-server) VS Code in the browser
- [Claude Code CLI](https://claude.ai/code) AI coding assistant by Anthropic
---
## License
MIT

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="orangeGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ff7b5c"/>
<stop offset="100%" stop-color="#e05a3a"/>
</linearGradient>
<linearGradient id="blueGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#5b9fff"/>
<stop offset="100%" stop-color="#3d7ed8"/>
</linearGradient>
</defs>
<!-- Outer C shape -->
<path d="M380 120 C320 60 200 60 140 120 C80 180 80 332 140 392 C200 452 320 452 380 392 L340 352 C300 392 212 392 172 352 C132 312 132 200 172 160 C212 120 300 120 340 160 Z" fill="url(#orangeGrad)"/>
<!-- Inner code bracket < -->
<path d="M320 180 L220 256 L320 332 L280 372 L140 256 L280 140 Z" fill="url(#blueGrad)"/>
</svg>

After

Width:  |  Height:  |  Size: 948 B

BIN
public/iphone_mockup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

BIN
public/social-preview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

267
railway-entrypoint.sh Normal file
View File

@ -0,0 +1,267 @@
#!/bin/bash
set -e
# ============================================================================
# VSCode Cloud IDE - Railway Entrypoint
# Handles permission fix and optional user switching
# ============================================================================
echo "╔══════════════════════════════════════════════════════════════════════╗"
echo "║ VSCode Cloud IDE - Claude Code & Node.js Ready ║"
echo "╚══════════════════════════════════════════════════════════════════════╝"
echo ""
# ============================================================================
# CONFIGURABLE PATHS AND USER
# ============================================================================
CLAUDER_HOME="${CLAUDER_HOME:-/home/clauder}"
CLAUDER_UID="${CLAUDER_UID:-1000}"
CLAUDER_GID="${CLAUDER_GID:-1000}"
# RUN_AS_USER: Defaults to "clauder" for non-root. Set to "root" if needed.
RUN_AS_USER="${RUN_AS_USER:-clauder}"
export HOME="$CLAUDER_HOME"
export XDG_DATA_HOME="$CLAUDER_HOME/.local/share"
export XDG_CONFIG_HOME="$CLAUDER_HOME/.config"
export XDG_CACHE_HOME="$CLAUDER_HOME/.cache"
export XDG_STATE_HOME="$CLAUDER_HOME/.local/state"
# PATH: Include all possible locations for installed tools
# - ~/.local/bin: pip user installs, pipx, local scripts
# - ~/.npm-global/bin: npm global installs (non-root)
# - /usr/local/bin: system-wide installs
# - /usr/lib/node_modules/.bin: npm global installs (root/sudo)
export PATH="$CLAUDER_HOME/.local/bin:$CLAUDER_HOME/.npm-global/bin:$CLAUDER_HOME/.local/node/bin:$CLAUDER_HOME/.claude/local:$CLAUDER_HOME/node_modules/.bin:/usr/local/bin:/usr/bin:/usr/lib/node_modules/.bin:/usr/lib/code-server/lib/vscode/bin/remote-cli:$PATH"
echo "→ Initial user: $(whoami) (UID: $(id -u))"
echo "→ RUN_AS_USER: $RUN_AS_USER"
echo "→ HOME: $HOME"
# ============================================================================
# DIRECTORY CREATION AND PERMISSION FIX
# ============================================================================
if [ "$(id -u)" = "0" ]; then
echo ""
echo "→ Running setup as root..."
# Create directories if they don't exist
mkdir -p "$XDG_DATA_HOME" \
"$XDG_CONFIG_HOME" \
"$XDG_CACHE_HOME" \
"$XDG_STATE_HOME" \
"$HOME/.local/bin" \
"$HOME/.local/node" \
"$HOME/.claude" \
"$HOME/entrypoint.d" \
"$HOME/workspace" \
"$XDG_DATA_HOME/code-server/extensions" \
"$XDG_CONFIG_HOME/code-server" 2>/dev/null || true
# ========================================================================
# SHELL PROFILE SETUP
# ========================================================================
PROFILE_FILE="$HOME/.bashrc"
if [ ! -f "$PROFILE_FILE" ] || ! grep -q '.npm-global' "$PROFILE_FILE" 2>/dev/null; then
echo "→ Setting up shell profile..."
cat >> "$PROFILE_FILE" << 'PROFILE'
# ============================================================================
# VSCode Cloud IDE - PATH Configuration
# ============================================================================
export PATH="$HOME/.local/bin:$HOME/.npm-global/bin:$HOME/.local/node/bin:$HOME/.claude/local:$PATH"
# npm global prefix for non-root installs
export NPM_CONFIG_PREFIX="$HOME/.npm-global"
# Claude Code alias with --dangerously-skip-permissions
alias claude-auto='claude --dangerously-skip-permissions'
PROFILE
# Create npm global directory
mkdir -p "$HOME/.npm-global/bin" 2>/dev/null || true
echo " ✓ Shell profile configured"
fi
# Also set up .profile for login shells
if [ ! -f "$HOME/.profile" ] || ! grep -q '.local/bin' "$HOME/.profile" 2>/dev/null; then
cat >> "$HOME/.profile" << 'PROFILE'
# Load .bashrc for interactive shells
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
PROFILE
fi
# ========================================================================
# USER SWITCHING (if RUN_AS_USER=clauder)
# ========================================================================
if [ "$RUN_AS_USER" = "clauder" ]; then
echo "→ Fixing permissions for clauder user (UID: $CLAUDER_UID)..."
chown -R "$CLAUDER_UID:$CLAUDER_GID" "$CLAUDER_HOME" 2>/dev/null || true
echo " ✓ Permissions fixed"
# Check if gosu is available
if command -v gosu &>/dev/null; then
echo "→ Switching to clauder user via gosu..."
exec gosu "$CLAUDER_UID:$CLAUDER_GID" "$0" "$@"
else
echo " ⚠ gosu not found, staying as root"
fi
else
echo "→ Staying as root (set RUN_AS_USER=clauder to switch)"
# Create symlinks from /root to volume for persistence
mkdir -p /root/.local 2>/dev/null || true
for dir in ".local/share" ".local/bin" ".local/node" ".config" ".cache" ".claude"; do
target="$CLAUDER_HOME/$dir"
link="/root/$dir"
if [ -d "$target" ] && [ ! -L "$link" ]; then
rm -rf "$link" 2>/dev/null || true
mkdir -p "$(dirname "$link")" 2>/dev/null || true
ln -sf "$target" "$link" 2>/dev/null || true
fi
done
echo " ✓ Root directories symlinked to $CLAUDER_HOME"
fi
fi
# ============================================================================
# RUNNING AS FINAL USER
# ============================================================================
echo ""
echo "→ Running as: $(whoami) (UID: $(id -u))"
# ============================================================================
# FIRST RUN SETUP
# ============================================================================
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 VSCode Cloud IDE
Your cloud development environment is ready!
## Features
- **Claude Code CLI** - Pre-installed and ready to use
- **Node.js 20 LTS** - Pre-installed and ready to use
- **Persistent Extensions** - Install once, keep forever
- **Full Terminal** - npm, git, and more
## Quick Start
```bash
# Start Claude Code (with auto-accept for automation)
claude --dangerously-skip-permissions
# Or use the alias
claude-auto
# Interactive mode
claude
```
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 for Claude)
- `RUN_AS_USER=root` - Stay as root
Happy coding! 🚀
WELCOME
fi
touch "$FIRST_RUN_MARKER" 2>/dev/null || true
echo " ✓ Initialization complete"
fi
# ============================================================================
# ENVIRONMENT VERIFICATION
# ============================================================================
echo ""
echo "Environment:"
# Node.js - show source
if [ -x "$CLAUDER_HOME/.local/node/bin/node" ]; then
echo " → Node.js: $(node --version 2>/dev/null) [volume]"
else
echo " → Node.js: $(node --version 2>/dev/null || echo 'not found') [image]"
fi
# npm
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
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
echo " → claude: $(claude --version 2>/dev/null || echo 'installed') [volume ~/.claude/local]"
elif command -v claude &>/dev/null; then
echo " → claude: $(claude --version 2>/dev/null || echo 'installed') [image]"
else
echo " → claude: not installed"
fi
# 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)
EXT_COUNT=$((EXT_COUNT - 1))
if [ $EXT_COUNT -gt 0 ]; then
echo " → Extensions: $EXT_COUNT installed"
fi
fi
# ============================================================================
# CUSTOM STARTUP SCRIPTS
# ============================================================================
if [ -d "$HOME/entrypoint.d" ]; then
for script in "$HOME/entrypoint.d"/*.sh; do
if [ -f "$script" ] && [ -x "$script" ]; then
echo ""
echo "Running: $(basename "$script")"
"$script" || echo " ⚠ Script exited with code $?"
fi
done
fi
# ============================================================================
# START CODE-SERVER
# ============================================================================
# Branding customization
APP_NAME="${APP_NAME:-Claude Code Server}"
WELCOME_TEXT="${WELCOME_TEXT:-Welcome to Claude Code Server}"
echo ""
echo "════════════════════════════════════════════════════════════════════════"
echo "Starting $APP_NAME as $(whoami)..."
echo "════════════════════════════════════════════════════════════════════════"
echo ""
exec dumb-init /usr/bin/code-server \
--bind-addr 0.0.0.0:8080 \
--app-name "$APP_NAME" \
--welcome-text "$WELCOME_TEXT" \
"$CLAUDER_HOME/workspace"

18
railway.toml Normal file
View File

@ -0,0 +1,18 @@
# ============================================================================
# Claude Code Server - Railway Configuration
# https://github.com/sphinxcode/claude-code-server
# ============================================================================
[build]
builder = "DOCKERFILE"
dockerfilePath = "Dockerfile"
[deploy]
healthcheckPath = "/healthz"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
# Auto-generate a Railway domain on deployment
[[services.networking.external]]
port = 8080