Replaces sequential installation with parallel step execution Introduces real-time progress dashboard with spinner and status Removes color variables to improve terminal compatibility Restructures logging with per-step files for better debugging Significantly reduces total setup time by running independent steps concurrently |
||
|---|---|---|
| .gitignore | ||
| CLAUDE.md | ||
| config.env.example | ||
| README.md | ||
| setup_env.sh | ||
OrbStack Development Sandbox
Disposable, isolated Linux VMs for running Claude Code with --dangerously-skip-permissions. One command creates a fully provisioned environment. Blow it away and recreate it in minutes.
The VM is a real Linux machine with its own filesystem, network, and process space — but you edit files from your Mac, access services on *.orb.local, and SSH in without any key setup. All the isolation of a container with none of the friction.
Why This Exists
Running claude --dangerously-skip-permissions on your host machine means Claude can execute arbitrary commands, install packages, modify system files, and access everything on your disk. That's powerful for autonomous coding but risky on a machine with your SSH keys, credentials, and personal files.
This script creates throwaway VMs where Claude can run unrestricted:
- Isolated filesystem — Claude can't touch your macOS files, keys, or configs
- Isolated network — services run on their own IP, no port conflicts with your host
- Disposable —
orb delete my-sandboxwipes everything; recreate in one command - Multiple VMs — run separate sandboxes per project with shared git credentials
- Full access from Mac — edit files in your editor, browse databases, view running apps
# Create a sandbox, SSH in, run Claude unrestricted
./setup_env.sh my-project
ssh my-project@orb
claude --dangerously-skip-permissions
If anything goes wrong: orb delete my-project && ./setup_env.sh my-project
Quick Start
# Create and provision a VM (one command from macOS)
./setup_env.sh my-sandbox
On first run, you'll be prompted for git name, email, and a VNC password. These are saved to config.env and reused for all future VMs. You'll also get an interactive checklist to select which components to install.
# Create additional VMs — reuses config.env, shows component picker
./setup_env.sh my-other-project
./setup_env.sh elixir-playground
When run manually inside a VM, you're prompted for each component individually:
# Inside a VM — interactive, prompts per component
./setup_env.sh
# Inside a VM — accept all without prompting
./setup_env.sh -y
./setup_env.sh --yes
Requirements
- macOS with Apple Silicon (ARM64)
- OrbStack installed (
brew install orbstack)
What Gets Installed
All components are optional — deselect what you don't need in the interactive picker.
| Tool | Version | Purpose |
|---|---|---|
| mise | latest | Version manager for runtimes |
| Node.js | LTS | JavaScript runtime |
| Erlang | 28.3.1 | BEAM VM |
| Elixir | 1.19.5-otp-28 | Elixir language |
| Chromium | system | Browser automation target |
| Playwright | latest | Browser testing framework |
| PostgreSQL | system default | Database |
| Ollama | latest | Local LLM inference |
| Claude Code | latest | AI coding assistant |
| TigerVNC + XFCE | system | VNC access for browser login flows |
Connecting from macOS
SSH
# Shell into the VM (no key setup required)
ssh my-sandbox@orb
# Run a command directly
ssh my-sandbox@orb -- ls ~/projects
# Run Claude unrestricted
ssh my-sandbox@orb -- claude --dangerously-skip-permissions
OrbStack handles SSH key configuration automatically.
Editing Files
Your editor connects to the VM over SSH. You edit files as if they were local — full LSP support, syntax highlighting, file tree, integrated terminal.
Zed:
Cmd+Shift+P-> "Open Remote Folder"- Enter:
my-sandbox@orb:~/projects
VS Code / Cursor:
- Install the "Remote - SSH" extension
Cmd+Shift+P-> "Remote-SSH: Connect to Host"- Enter:
my-sandbox@orb - Open folder:
~/projects
Finder (direct filesystem access):
/Volumes/OrbStack/my-sandbox/home/<user>/
Viewing Running Apps
Services running in the VM are accessible from your Mac via <vm-name>.orb.local:
# Phoenix/Rails/Next.js dev server running on port 4000 inside the VM
open http://my-sandbox.orb.local:4000
# Or use port forwarding if the app only binds to localhost
ssh -L 4000:localhost:4000 my-sandbox@orb
PostgreSQL, Redis, or any service listening on the VM's interfaces is reachable at my-sandbox.orb.local:<port> from your Mac — no extra configuration.
VNC (Browser Access)
For tasks requiring a visible browser (e.g., Claude Code OAuth login):
# Start VNC server inside the VM
ssh my-sandbox@orb -- vnc-start
# Connect from macOS (opens Screen Sharing.app)
open vnc://my-sandbox.orb.local:5901
# Stop when done (saves resources)
ssh my-sandbox@orb -- vnc-stop
macOS Screen Sharing (built-in)
open vnc://my-sandbox.orb.local:5901
Enter your VNC password when prompted.
RealVNC Viewer
- Download from https://www.realvnc.com/en/connect/download/viewer/
- Enter address:
my-sandbox.orb.local:5901 - When prompted for credentials, enter your VNC password (username can be left blank)
TigerVNC Viewer
# Install via Homebrew
brew install tiger-vnc
# Connect
vncviewer my-sandbox.orb.local:5901
Enter your VNC password when prompted.
Connection details for any VNC client
- Host:
my-sandbox.orb.local - Port:
5901(display:1) - Password: the VNC password from
config.env - Resolution: 1280x800 (configurable in
~/bin/vnc-start)
PostgreSQL
A superuser matching your Linux username and a dev database are created automatically.
Auth model:
- Local socket (
psql dev): peer auth (OS username must match PG role) - Localhost TCP (127.0.0.1): trust (passwordless)
- Host network (192.168.0.0/16, i.e., from macOS): scram-sha-256
From inside the VM
psql dev # Connect to dev database
psql -l # List databases
createdb myapp_dev # Create a new database
From macOS
# Direct (requires: brew install libpq)
psql -h my-sandbox.orb.local -U <user> -d dev
Connection strings
# Elixir/Phoenix
postgres://<user>@my-sandbox.orb.local/myapp_dev
# Generic
host=my-sandbox.orb.local port=5432 dbname=dev user=<user>
DataGrip
- New Data Source -> PostgreSQL
- SSH/SSL tab: Check "Use SSH tunnel", Host:
my-sandbox@orb, Auth: Key pair - General tab: Host:
localhost, Port:5432, User: your VM username, Database:dev, No password - Test Connection -> Apply
DBeaver
- New Database Connection -> PostgreSQL
- SSH tab: Check "Use SSH Tunnel", Host:
my-sandbox.orb.local, Port:22, Auth: Public Key - Main tab: Host:
localhost, Port:5432, Database:dev, Username: your VM username, no password - Test Connection -> Finish
Creating additional databases
# From inside the VM
createdb myapp_dev
createdb myapp_test
# From macOS
ssh my-sandbox@orb -- createdb myapp_dev
Claude Code Plugins
The script installs these plugins at user scope:
Anthropic marketplace (anthropics/claude-code):
- code-review, code-simplifier, feature-dev, pr-review-toolkit, security-guidance, frontend-design
Superpowers marketplace (obra/superpowers):
- double-shot-latte, elements-of-style, superpowers, superpowers-chrome, superpowers-lab
MCP Servers:
playwright- Browser automation and screenshotssuperpowers-chrome- Direct Chrome/Chromium control (headless)
Configuration
Edit the version variables at the top of setup_env.sh:
ERLANG_VERSION="28.3.1"
ELIXIR_VERSION="1.19.5-otp-28"
Shared credentials
Credentials are stored in config.env (gitignored). To reset:
rm config.env
./setup_env.sh my-sandbox # will prompt again
Or copy the example and edit:
cp config.env.example config.env
# Edit config.env with your values
Managing VMs
# List all VMs
orb list
# Delete a VM (instant cleanup)
orb delete my-sandbox
# Stop a VM (preserves state, frees resources)
orb stop my-sandbox
# Start a stopped VM
orb start my-sandbox
# Nuclear option — delete and recreate
orb delete my-sandbox && ./setup_env.sh my-sandbox
Idempotency
The VM provisioning script is safe to run multiple times. It checks for existing installations before re-installing and avoids appending duplicate configuration lines.
Logs
Each provisioning run creates a log file at /tmp/setup_env_<timestamp>.log inside the VM with detailed output from package installations and any errors.