#!/bin/bash # ───────────────────────────────────────────────────────────────── # Code Server · Startup Script # Runs as: root | Port: 7860 | Extensions: image-local # Persisted to /data: workspace + User settings only # ───────────────────────────────────────────────────────────────── set -euo pipefail # ── Storage paths ──────────────────────────────────────────────── if [ -d "/data" ]; then DATA_DIR="/data" echo "✅ /data storage bucket mounted" else DATA_DIR="/root/.local/codeserver-data" echo "⚠️ /data not found — using local storage (not persistent)" fi WORKSPACE="${DATA_DIR}/workspace" CS_USER_DATA="${DATA_DIR}/vscode-user-data" CS_LOGS="${DATA_DIR}/logs" # Extensions stay LOCAL — never on the bucket (S3 FUSE can't atomic-rename) CS_EXTENSIONS_DIR="/root/.local/share/code-server/extensions" # ── Create directories safely ──────────────────────────────────── mkdir -p \ "$WORKSPACE" \ "$CS_USER_DATA/User" \ "$CS_LOGS" \ "$CS_EXTENSIONS_DIR" # ── VS Code settings (written once; user can edit inside editor) ─ SETTINGS_FILE="$CS_USER_DATA/User/settings.json" if [ ! -f "$SETTINGS_FILE" ]; then cat > "$SETTINGS_FILE" << 'SETTINGS' { "workbench.colorTheme": "Default Dark+", "workbench.iconTheme": "vs-seti", "editor.fontSize": 14, "editor.fontFamily": "monospace", "editor.tabSize": 2, "editor.formatOnSave": true, "editor.wordWrap": "on", "editor.minimap.enabled": true, "editor.bracketPairColorization.enabled": true, "editor.guides.bracketPairs": true, "editor.smoothScrolling": true, "editor.cursorBlinking": "smooth", "terminal.integrated.fontSize": 13, "terminal.integrated.scrollback": 5000, "terminal.integrated.defaultProfile.linux": "bash", "files.autoSave": "afterDelay", "files.autoSaveDelay": 1000, "files.trimTrailingWhitespace": true, "workbench.startupEditor": "none", "git.autofetch": true, "git.confirmSync": false, "extensions.autoUpdate": false, "telemetry.telemetryLevel": "off", "update.mode": "none" } SETTINGS echo "✅ VS Code settings written" fi # ── code-server config ─────────────────────────────────────────── mkdir -p /root/.config/code-server cat > /root/.config/code-server/config.yaml << CSCONFIG bind-addr: 0.0.0.0:7860 auth: password password: ${PASSWORD:-codeserver123} cert: false user-data-dir: ${CS_USER_DATA} extensions-dir: ${CS_EXTENSIONS_DIR} CSCONFIG # ── Git config ─────────────────────────────────────────────────── git config --global init.defaultBranch main git config --global pull.rebase false git config --global core.editor "code --wait" [ -n "${GIT_USER_NAME:-}" ] && git config --global user.name "$GIT_USER_NAME" [ -n "${GIT_USER_EMAIL:-}" ] && git config --global user.email "$GIT_USER_EMAIL" if [ -n "${GITHUB_TOKEN:-}" ]; then git config --global \ url."https://${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/" echo "✅ GitHub token configured" fi # ── HuggingFace login ──────────────────────────────────────────── if [ -n "${HF_TOKEN:-}" ]; then huggingface-cli login --token "$HF_TOKEN" --add-to-git-credential 2>/dev/null || true echo "✅ HuggingFace token configured" fi # ── Welcome README (only on first boot) ───────────────────────── README_FILE="$WORKSPACE/README.md" if [ ! -f "$README_FILE" ]; then # Write via tee to avoid heredoc redirect issues on FUSE mounts tee "$README_FILE" > /dev/null << 'WSREADME' # 🚀 Code Server — Cloud Dev Environment Your persistent workspace is backed by HF Storage Bucket at `/data`. ## 📁 Paths | Path | Purpose | |------|---------| | `/data/workspace` | Your code (this folder) | | `/data/vscode-user-data` | Settings & keybindings | | `/root/.local/share/code-server/extensions` | Extensions (image-local) | ## 🔌 Port Proxy Access any running server: https://-.hf.space/proxy/PORT/ Example: app on port 3000 → `/proxy/3000/` ## 🔐 Secrets (Space Settings → Repository secrets) | Secret | Purpose | |--------|---------| | `PASSWORD` | code-server login password | | `GITHUB_TOKEN` | Private GitHub repo auth | | `HF_TOKEN` | HuggingFace CLI auth | | `GIT_USER_NAME` | Git commit name | | `GIT_USER_EMAIL` | Git commit email | ## 🛠️ Pre-installed - Python 3, pip, venv, numpy, pandas, black - Node.js 20, npm, yarn, pnpm - Git, GitHub CLI (gh) - build-essential, cmake, curl, wget, jq, ripgrep - Extensions: Python, Jupyter, Prettier, GitLens, Material Icons WSREADME echo "✅ Workspace README created" fi # ── Launch ─────────────────────────────────────────────────────── echo "" echo "╔══════════════════════════════════════════════════╗" echo "║ 🖥️ Code Server starting... ║" echo "╠══════════════════════════════════════════════════╣" echo "║ Workspace : $WORKSPACE" echo "║ Extensions : $CS_EXTENSIONS_DIR" echo "║ Port : 7860" echo "╚══════════════════════════════════════════════════╝" echo "" exec code-server \ --config /root/.config/code-server/config.yaml \ --disable-telemetry \ --disable-update-check \ "$WORKSPACE" \ 2>&1 | tee -a "$CS_LOGS/code-server.log"