Skip to main content

Cloud Dev Stack

A complete, persistent cloud development environment with one shared workspace, two browser based views.

What You Get

  • Ubuntu desktop in your browser: full XFCE desktop from any device, with VS Code installed as a native desktop app
  • VS Code in your browser: same files, same tools, same environment available as both a standalone container and inside the desktop
  • SSH access: connect from local devices like PC, Mac, or iPhone
  • Persistent tmux sessions: your work survives disconnects and app switches, especially useful on mobile
  • Everything shared: both containers mount the same /config (home) and /projects. Install a package, set a git config, or save a file and it's visible everywhere instantly. Extensions and settings are shared across all VS Code instances

Architecture

Two containers, one environment. They share /config (home directory) and /projects. The vscode container is a browser based editor view into the same workspace:

How it works

compose.yaml init.sh /config (shared home)
(desktop service) → on boot → ├── .bashrc / .zshrc
├── .gitconfig
├── .nvm (Node LTS)
├── .npm-global (Claude Code)
└── .local/share/code-server

vscode container mounts
same /config same everything

Edit compose.yaml → recreate desktop → both containers see the change.

Shared environment

WhatWhereShared?
Shell config (PATH, aliases)/config/.bashrc✅ Both containers
Git identity + GitHub token/config/.gitconfig✅ Both containers
nvm + Node LTS/config/.nvm✅ Both containers
Claude Code/config/.npm-global✅ Both containers
code-server extensions & settings/shared/code-server/extensions + User/✅ All VS Code instances (code-server ×2 + desktop VS Code)
Your projects/projects✅ Both containers
Persistent sessions (tmux)Desktop onlyDesktop (via SSH)

Tools pre-installed

ToolInstalled byPersists?
nvm + Node LTSInit script/config/.nvm
Claude CodeInit script (npm global)/config/.npm-global
code-serverInit script✅ system install
VS Code (desktop app)Init script (apt)❌ Reinstalled each boot
build-essential (gcc, make)Init script (apt)❌ Reinstalled each boot
python3 + pipInit script (apt)❌ Reinstalled each boot
Docker CLIInit script (apt)❌ Reinstalled each boot
Git, curl, zsh, tmux, nanoInit script (apt)❌ Reinstalled each boot
The golden rule

If it lands in /config, it persists forever and appears in both containers. If it needs sudo or apt, add it to the init script.

Next steps