Railway template

This commit is contained in:
SAGE 2026-01-29 17:00:28 +08:00
parent da6737c5ba
commit f81bbd1e38
3 changed files with 87 additions and 83 deletions

View File

@ -8,11 +8,11 @@ FROM codercom/code-server:latest
USER root
# Install FALLBACK Node.js and essential development tools
# Volume-installed versions take priority at runtime via PATH ordering
# Install gosu for proper user switching, Node.js, and essential tools
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
gosu \
nodejs \
git \
curl \
@ -29,7 +29,6 @@ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
# ============================================================================
# PERSISTENCE CONFIGURATION
# Default paths - can be overridden via CODER_HOME environment variable
# ============================================================================
ENV HOME=/home/coder
@ -41,14 +40,10 @@ ENV XDG_CONFIG_HOME=/home/coder/.config
ENV XDG_CACHE_HOME=/home/coder/.cache
ENV XDG_STATE_HOME=/home/coder/.local/state
# ============================================================================
# PATH PRIORITY ORDER (volume paths FIRST, image paths LAST)
# This ensures user-installed tools on the volume take precedence
# ============================================================================
# PATH: Volume paths FIRST (user installs), image paths LAST (fallbacks)
ENV PATH="/home/coder/.local/node/bin:/home/coder/.claude/local:/home/coder/.local/bin:/home/coder/node_modules/.bin:/usr/local/bin:/usr/bin:/usr/lib/code-server/lib/vscode/bin/remote-cli:${PATH}"
# Custom startup scripts directory (on volume)
# Custom startup scripts directory
ENV ENTRYPOINTD=/home/coder/entrypoint.d
# ============================================================================
@ -85,8 +80,7 @@ RUN curl -fsSL https://claude.ai/install.sh | bash \
# ============================================================================
# RUNTIME
# Note: We run as root for compatibility with existing volumes
# The entrypoint creates symlinks to ensure persistence
# Entrypoint handles permission fix and user switching via gosu
# ============================================================================
WORKDIR /home/coder/workspace
@ -94,4 +88,3 @@ EXPOSE 8080
ENTRYPOINT ["/usr/bin/railway-entrypoint.sh"]
CMD ["--bind-addr", "0.0.0.0:8080", "/home/coder/workspace"]

View File

@ -4,62 +4,66 @@
[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/template/TEMPLATE_ID)
Cloud IDE with persistent extensions, settings, and tools. Zero configuration.
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 `coder` user (UID 1000)
- Extensions persist across redeployments
- Volume-installed tools take priority (update when YOU want)
- Custom startup scripts supported
- Volume permissions auto-fixed on startup
---
## Quick Start
```bash
# Claude Code ready to use
# Claude Code with auto-accept (for automation)
claude --dangerously-skip-permissions
# Interactive mode
claude
# Node.js ready to use
# Node.js ready
node --version
npm --version
```
---
## How Updates Work
| Component | Behavior |
|-----------|----------|
| **Volume tools** | YOU control updates. Install to `~/.local/node/` or `~/.claude/local/` |
| **Image tools** | Auto-update on redeploy (fallback if no volume version) |
| **Extensions** | Never reset (persisted on volume) |
The startup logs show `[volume]` or `[image]` next to each tool.
---
## Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `PASSWORD` | Yes | - | Login password |
| `CODER_HOME` | No | `/home/coder` | Volume mount path |
| `CODER_UID` | No | `1000` | User ID for coder |
| `CODER_GID` | No | `1000` | Group ID for coder |
---
## Custom Volume Path
## How It Works
If you change the volume mount location:
1. **Starts as root** - fixes volume permissions
2. **Switches to coder** - uses `gosu` for clean handoff
3. **Runs code-server** - as non-root user
```
CODER_HOME=/your/volume/path
```
This means:
- ✅ No root permission warnings in code-server
- ✅ Existing volumes with root-owned files work fine
- ✅ Claude `--dangerously-skip-permissions` works
Everything adapts automatically.
---
## 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)
---
@ -76,13 +80,26 @@ Make executable: `chmod +x script.sh`
---
## Update Behavior
| Component | Behavior |
|-----------|----------|
| **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 |
Logs show `[volume]` or `[image]` next to each tool.
---
## Troubleshooting
| Issue | Check |
|-------|-------|
| Wrong Node version | Look for `[volume]` vs `[image]` in logs |
| Extensions missing | Verify volume at `CODER_HOME` |
| Claude not found | Run `which claude` to verify PATH |
| Issue | Solution |
|-------|----------|
| Permission denied | Check `CODER_UID` matches your volume owner |
| Claude not found | Run `which claude` to check PATH |
| Extensions missing | Verify volume mounted at `CODER_HOME` |
---

View File

@ -3,7 +3,7 @@ set -e
# ============================================================================
# VSCode Cloud IDE - Railway Entrypoint
# Robust entrypoint with volume-first tool priority
# Handles permission fix and user switching for non-root execution
# ============================================================================
echo "╔══════════════════════════════════════════════════════════════════════╗"
@ -13,10 +13,11 @@ echo ""
# ============================================================================
# CONFIGURABLE PATHS
# Users can override CODER_HOME to change the volume mount point
# ============================================================================
CODER_HOME="${CODER_HOME:-/home/coder}"
CODER_UID="${CODER_UID:-1000}"
CODER_GID="${CODER_GID:-1000}"
export HOME="$CODER_HOME"
export XDG_DATA_HOME="$CODER_HOME/.local/share"
@ -27,14 +28,14 @@ export XDG_STATE_HOME="$CODER_HOME/.local/state"
# PATH: Volume paths FIRST (user installs), image paths LAST (fallbacks)
export PATH="$CODER_HOME/.local/node/bin:$CODER_HOME/.claude/local:$CODER_HOME/.local/bin:$CODER_HOME/node_modules/.bin:/usr/local/bin:/usr/bin:/usr/lib/code-server/lib/vscode/bin/remote-cli:$PATH"
echo "→ User: $(whoami) (UID: $(id -u))"
echo "→ HOME: $HOME"
# ============================================================================
# DIRECTORY CREATION
# PERMISSION FIX (runs as root, then switches to coder)
# ============================================================================
create_dirs() {
if [ "$(id -u)" = "0" ]; then
echo "→ Running initial setup as root..."
# Create directories if they don't exist
mkdir -p "$XDG_DATA_HOME" \
"$XDG_CONFIG_HOME" \
"$XDG_CACHE_HOME" \
@ -46,33 +47,26 @@ create_dirs() {
"$HOME/workspace" \
"$XDG_DATA_HOME/code-server/extensions" \
"$XDG_CONFIG_HOME/code-server" 2>/dev/null || true
}
create_dirs
# ============================================================================
# ROOT USER SYMLINKS
# When running as root, symlink /root directories to the volume
# ============================================================================
if [ "$(id -u)" = "0" ]; then
echo "→ Running as root - creating persistence symlinks..."
mkdir -p /root/.local 2>/dev/null || true
for dir in ".local/share" ".local/node" ".config" ".cache" ".claude"; do
target="$CODER_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 $CODER_HOME"
# Fix ownership on the entire home directory
echo "→ Fixing permissions for coder user (UID: $CODER_UID)..."
chown -R "$CODER_UID:$CODER_GID" "$CODER_HOME" 2>/dev/null || true
echo " ✓ Permissions fixed"
echo ""
# Re-exec this script as coder user using gosu
echo "→ Switching to coder user..."
exec gosu "$CODER_UID:$CODER_GID" "$0" "$@"
fi
# ============================================================================
# RUNNING AS CODER USER FROM HERE
# ============================================================================
echo "→ User: $(whoami) (UID: $(id -u))"
echo "→ HOME: $HOME"
# ============================================================================
# FIRST RUN SETUP
# ============================================================================
@ -82,10 +76,8 @@ FIRST_RUN_MARKER="$XDG_DATA_HOME/.vscode-cloud-initialized"
if [ ! -f "$FIRST_RUN_MARKER" ]; then
echo "→ First run detected - initializing..."
mkdir -p "$XDG_CONFIG_HOME/code-server" 2>/dev/null || true
if [ ! -f "$HOME/workspace/README.md" ]; then
cat > "$HOME/workspace/README.md" << 'WELCOME' 2>/dev/null || true
cat > "$HOME/workspace/README.md" << 'WELCOME'
# Welcome to VSCode Cloud IDE
Your cloud development environment is ready!
@ -99,18 +91,21 @@ Your cloud development environment is ready!
## Quick Start
1. Open the Extensions panel (Ctrl+Shift+X)
2. Install your favorite extensions (they persist!)
3. Start coding in this workspace
## Using Claude Code
```bash
# Start Claude Code (with auto-accept for automation)
claude --dangerously-skip-permissions
# Or interactive mode
claude
```
You'll need to authenticate with your Anthropic API key on first use.
## Persist Claude Authentication
Your Claude config at `~/.claude/` persists across redeployments.
After authenticating once, you won't need to re-authenticate.
Happy coding! 🚀
WELCOME
fi
@ -121,7 +116,6 @@ fi
# ============================================================================
# ENVIRONMENT VERIFICATION
# Shows which version is being used (volume vs image)
# ============================================================================
echo ""
@ -178,7 +172,7 @@ fi
echo ""
echo "════════════════════════════════════════════════════════════════════════"
echo "Starting code-server..."
echo "Starting code-server as $(whoami)..."
echo "════════════════════════════════════════════════════════════════════════"
echo ""