3.5 KiB
code-server — VS Code in the browser
Full VS Code served from the box at http://framework:8443. The reason it exists in this stack: Claude Code runs inside the container, so long agent tasks execute on the Framework Desktop and survive the laptop sleeping, the browser tab closing, or you walking away with the phone. Any device on the tailnet gets the same editor with the same state.
Bring-up
cd /srv/docker/code-server && docker compose up -d
First start pulls the image and runs the universal-package-install mod (installs tmux), so give it a minute before the UI answers on :8443.
HTTPS is required for extension panels. VS Code webviews (the Claude Code panel included) need a secure context; over plain
http://framework:8443they render blank. Serve it via Tailscale:sudo tailscale serve --bg --https=8443 8443→https://framework.<tailnet>.ts.net:8443. Localhost also counts as secure (ssh -L 8443:localhost:8443 framework).
One-time setup (in the code-server UI)
-
Install the Claude Code extension. Extensions panel → search "Claude Code". code-server uses the Open VSX registry, where Anthropic publishes the official extension (https://open-vsx.org/extension/Anthropic/claude-code).
-
Sign in. The OAuth flow in a browser context is a copy/paste dance: the extension shows a URL → open it in another tab → approve → paste the code back. Credentials land in
/config/.claude/and persist across container recreates. -
(Optional) CLI in the terminal. The extension bundles its own CLI, but for tmux-based long runs install it explicitly:
curl -fsSL https://claude.ai/install.sh | bashLands in
~/.local/bin(=/config/.local/bin, persisted).
Long-running tasks
The Claude process is a child of the container, not of your browser tab — closing the tab does nothing to it. Reattach from any device and the session is where you left it. For multi-hour unattended runs, prefer a tmux pane in the integrated terminal:
tmux new -s longtask
claude # kick off the task, detach with C-b d
If you want to steer from a phone or claude.ai/code instead of this UI,
use claude remote-control (see the framework README's
"Claude Code on the box" section) — that works in the host's tmux too,
no container needed.
Scope and security
- No password is set — same trust model as every other service on
this Tailscale-only box. If the host ever sees LAN/internet traffic,
set
HASHED_PASSWORDin the compose env and bind to localhost; a browser terminal is a shell. - The workspace is container-scoped on purpose: Claude Code in here
sees
/workspaceand/config, not the host filesystem or the docker socket. Bind-mount specific repos into/workspace/<name>when you want them editable (host UID 1000 == container PUID 1000, so ownership just works). host.docker.internalreaches the sibling services — handy for pointing scripts at Ollama (:11434) or LiteLLM (:4000) from the integrated terminal.
State layout
| Path (host) | What lives there |
|---|---|
/srv/docker/code-server/config |
$HOME: extensions, settings, ~/.claude, CLIs |
/srv/docker/code-server/workspace |
default project area (DEFAULT_WORKSPACE) |
Back up config if you care about extension state and Claude session
history; everything else is reproducible from the repo.