mirror of
https://github.com/coder/code-server.git
synced 2026-02-19 18:01:15 +08:00
Railway template
This commit is contained in:
parent
da6737c5ba
commit
f81bbd1e38
17
Dockerfile
17
Dockerfile
@ -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"]
|
||||
|
||||
|
||||
73
README.md
73
README.md
@ -4,62 +4,66 @@
|
||||
|
||||
[](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` |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -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 ""
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user