A container-first development environment with AI coding tools pre-configured.
┌────────────────────────────────────────────────────────────────────────┐
│ YOUR LOCAL MACHINE (Windows/macOS) │
│ │
│ VS Code + Remote-SSH + Dev Containers extensions │
│ (Install these yourself) │
│ │
└────────────────────────┬───────────────────────────────────────────────┘
│ SSH or local Docker
▼
┌────────────────────────────────────────────────────────────────────────┐
│ HOST MACHINE (Linux server, macOS, or WSL) │
│ │
│ Docker + GitHub CLI + cb commands ← Installed by host-setup.sh │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ DOCKER CONTAINER │ │
│ │ │ │
│ │ AI Tools: Claude Code, Codex CLI, Gemini CLI │ │
│ │ MCP Servers: filesystem, memory, fetch, git, github, etc. │ │
│ │ Dev Tools: Node.js 20, Python 3.12, uv, Spec Kit CLI │ │
│ │ │ │
│ │ /workspaces/projects/ ← Docker volume (persists rebuilds) │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────┘
curl -fsSL https://raw.githubusercontent.com/sethdf/codebootstrap/main/host-setup.sh | bashWhat it installs:
- Docker (or prompts for Docker Desktop on macOS/Windows)
- GitHub CLI (
gh) - CLI shortcuts (
cb,cb-start,cb-stop,cb-status) - Clones CodeBootstrap to
~/codebootstrap
After the script:
# Log out and back in (for docker group), then:
cb # Starts container and enters tmux sessionInstall these yourself:
- VS Code from https://code.visualstudio.com/
- Remote-SSH extension (for remote servers)
- Dev Containers extension (for container access)
- Authenticate AI tools (one-time):
claude # Opens browser for Anthropic OAuth codex auth # Opens browser for OpenAI OAuth gemini auth # Opens browser for Google OAuth
- Start working!
new-project my-app # Create a new project # OR clone-project # Clone from your GitHub repos
curl -fsSL https://raw.githubusercontent.com/sethdf/codebootstrap/main/host-setup.sh | bash| What Gets Installed | Where | Why |
|---|---|---|
| Docker | Host machine | Runs the dev container |
| GitHub CLI | Host machine | Authentication with GitHub |
| cb commands | Host ~/.bashrc | Quick container access |
| CodeBootstrap repo | ~/codebootstrap | The container definition |
Option A: CLI (SSH, mobile, terminal)
cb # Starts container if needed, enters tmux sessionOption B: VS Code (from your local Windows/Mac)
- Connect via Remote-SSH to your host machine
- Open
~/codebootstrap - Click "Reopen in Container"
What happens on first run:
- Docker builds the container image (~2-5 min first time)
- Mounts code and projects volume
- Runs
post-create.sh- configures MCP servers, shell helpers - You're inside the container with all tools ready
Each AI tool needs OAuth authentication the first time:
# Run each once - browser will open for OAuth
claude
codex auth
gemini authTroubleshooting OAuth: If the OAuth callback fails ("site can't be reached localhost:XXXXX"):
- Look at the URL in the error - note the port number
- In VS Code, go to the Ports tab (bottom panel)
- Forward that port
- Retry the auth command
Option A: New project with Spec Kit
new-project my-appCreates: /workspaces/projects/my-app/ with Spec Kit structure
Option B: Minimal project (no Spec Kit)
quick-project scratchOption C: Clone from GitHub
clone-projectShows an interactive list of your GitHub repos to choose from.
# Switch to your project
p my-app
# Start an AI assistant
c # Claude Code (YOLO mode)
codex # OpenAI Codex CLI
gemini # Google Gemini CLI
# Resume a Claude session
cr- Open VS Code
- Recent folder:
~/codebootstrap - If not in container: "Reopen in Container"
p my-projectto jump to your projectcto start Claude
- Run the one-liner:
curl -fsSL ... | bash - Open in container
- Authenticate AI tools
clone-projectto clone your existing repos- Projects are now in
/workspaces/projects/
Sometimes you need to rebuild the container:
- VS Code:
Cmd/Ctrl+Shift+P→ "Dev Containers: Rebuild Container"
Your projects are safe! They're stored in a Docker volume that persists across rebuilds.
# Install devcontainer CLI
npm install -g @devcontainers/cli
# Start container
cd ~/codebootstrap
devcontainer up --workspace-folder .
# Enter the container
devcontainer exec --workspace-folder . bash- Go to https://github.com/sethdf/codebootstrap
- Click Code → Codespaces → Create codespace on main
- Wait for build (~2-5 min)
- Authenticate AI tools
- Everything else works the same
When authenticating AI tools, if you see "site can't be reached":
http://localhost:46437/callback?code=...
↑
Note this port
Fix:
- VS Code bottom panel → Ports tab
- Click Forward a Port
- Enter the port number (e.g.,
46437) - Retry the auth command
Projects should persist in the Docker volume. If they disappeared:
# Check the volume
docker volume ls | grep codebootstrap
# Projects should be in
ls /workspaces/projects/If the volume was accidentally deleted, you'll need to re-clone your projects.
| Command | Description |
|---|---|
c |
Start Claude Code |
cr |
Resume last Claude session |
codex |
Start OpenAI Codex CLI |
gemini |
Start Google Gemini CLI |
| Command | Description |
|---|---|
new-project <name> |
Create project with Spec Kit + devcontainer |
quick-project <name> |
Create minimal project |
clone-project [repo] |
Clone from GitHub (interactive if no repo given) |
p [name] |
List projects or jump to one |
projects |
List all projects with git status |
| Command | Description |
|---|---|
todos |
Show project todos from tasks.md |
wip |
Mark task in progress |
unwip |
Mark task completed |
spec-init |
Initialize Spec Kit in existing project |
| Command | Description |
|---|---|
codebootstrap-status |
Health check all tools |
codebootstrap-update |
Update MCP servers |
backup |
Show backup paths |
today |
Git activity today |
ports |
List forwarded ports |
tree [depth] |
Project structure (default depth 2) |
| Command | Description |
|---|---|
gs |
git status |
gd |
git diff |
gl |
git log --oneline -20 |
gp |
git pull |
gpu |
git push |
gcm "msg" |
git commit -m |
| Command | Description |
|---|---|
save |
Commit all + push (auto-generates message) |
save "msg" |
Commit all + push with message |
sync |
Pull latest, push local (handles stash) |
push |
Push to remote |
wip |
Quick "WIP" commit + push |
CodeBootstrap enforces automatic saving to GitHub through AI instructions and convenience commands.
┌─────────────────────────────────────────────────────────────┐
│ AI CODING SESSION │
│ │
│ You: "Add a login feature" │
│ │
│ AI: [implements feature] │
│ [commits: "feat: add login feature"] │
│ [pushes to GitHub] │
│ │
│ You: "Now add password reset" │
│ │
│ AI: [implements feature] │
│ [commits: "feat: add password reset"] │
│ [pushes to GitHub] │
│ │
└─────────────────────────────────────────────────────────────┘
When you create a project with new-project, these rules are added to CLAUDE.md, AGENTS.md (Codex), and GEMINI.md:
- Commit at logical points - After completing features, fixes, or related changes
- Always push - Changes must be pushed to GitHub after committing
- Use conventional commits -
feat:,fix:,docs:, etc. - Descriptive messages - Explain why, not just what
If you want to force a save at any point:
save "checkpoint before refactor"Or for quick work-in-progress:
wip # commits "WIP" and pushes- Mobile access - Changes on desktop are immediately available on iPhone
- No lost work - Disconnect from phone? Work is already saved
- Multi-device - Seamlessly switch between machines
- History - Every change tracked in git
Pre-configured for all three AI tools:
| Server | Purpose | Example Use |
|---|---|---|
| filesystem | Read/write files | Editing code |
| memory | Persistent knowledge graph | Remember context across sessions |
| fetch | Retrieve web content | Get documentation |
| sequential-thinking | Multi-step reasoning | Complex problem solving |
| context7 | Library documentation | Look up API docs |
| git | Repository operations | Inspect git history |
| github | GitHub API | Create PRs, issues |
Create .claude/mcp-servers.json in your project:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": { "DATABASE_URL": "${DATABASE_URL}" }
}
}
}~/codebootstrap/ ← Cloned to your home directory
├── .devcontainer/
│ ├── devcontainer.json # Container config + volume mount
│ ├── Dockerfile # Image with all tools
│ ├── post-create.sh # MCP + shell setup (runs once)
│ └── post-start.sh # Startup tasks (runs each start)
├── templates/
│ ├── bashrc.d/ # Shell helpers (aliases, functions)
│ └── codebootstrap-additions/ # Template for new projects
├── host-setup.sh # Host machine setup script
└── README.md # This file
/workspaces/projects/ ← Docker volume (persists!)
├── my-app/ # Your projects live here
├── another-project/
└── ...
- Docker Engine (Linux) or Docker Desktop (macOS/Windows)
- GitHub account
- VS Code with Remote-SSH and Dev Containers extensions
- Or just an SSH client for CLI-only access (mobile)
- Claude: Anthropic account (Claude Pro or Team recommended)
- Codex: OpenAI/ChatGPT account
- Gemini: Google account (free tier available)
Tailscale creates a secure mesh VPN between your devices, making it easy to code on remote machines from anywhere.
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ YOUR LOCAL MACHINE │ │ REMOTE DEV MACHINE │
│ (laptop/desktop) │ │ (home server, cloud VM) │
│ │ │ │
│ ┌───────────────────────────┐ │ │ ┌───────────────────────────┐ │
│ │ VS Code │ │ │ │ Docker + CodeBootstrap │ │
│ │ + Remote-SSH extension │ │ SSH │ │ (devcontainer running) │ │
│ │ │─┼─────────┼─│ │ │
│ └───────────────────────────┘ │ over │ │ Claude, Codex, Gemini │ │
│ │Tailscale│ │ MCP servers, projects │ │
│ ┌───────────────────────────┐ │ │ └───────────────────────────┘ │
│ │ Tailscale client │ │ │ │
│ │ (100.x.x.x) │ │ │ ┌───────────────────────────┐ │
│ └───────────────────────────┘ │ │ │ Tailscale client │ │
│ │ │ │ (100.x.x.x) │ │
└─────────────────────────────────┘ │ │ + Tailscale SSH enabled │ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘
On your local machine (where you'll code from):
# macOS
brew install tailscale
# Then open Tailscale from Applications
# Ubuntu/Debian
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
# Windows
# Download from https://tailscale.com/download/windowsOn your remote machine (where CodeBootstrap will run):
# Ubuntu/Debian (most common for servers)
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --ssh
# ↑
# Enables Tailscale SSH!Tailscale SSH lets you SSH without managing keys - it uses your Tailscale identity.
# On the REMOTE machine, ensure SSH is enabled
sudo tailscale up --ssh
# Verify it's working
tailscale statusYou should see your machines listed with their Tailscale IPs (100.x.x.x).
- Go to https://login.tailscale.com/admin/machines
- Find your remote machine
- Click the ... menu → Edit ACLs or check SSH settings
- Ensure SSH is allowed for your user
Optional: Enable MagicDNS (recommended)
- Go to DNS tab in admin console
- Enable MagicDNS
- Now you can use hostnames instead of IPs:
ssh remote-serverinstead ofssh 100.x.x.x
From your local machine:
# Using Tailscale IP
ssh user@100.x.x.x
# Or with MagicDNS enabled (use machine name)
ssh user@remote-server
# Tailscale SSH (no keys needed!)
ssh user@remote-serverSSH into your remote machine and run the setup:
# Connect to remote machine
ssh user@remote-server
# Run CodeBootstrap setup
curl -fsSL https://raw.githubusercontent.com/sethdf/codebootstrap/main/host-setup.sh | bashInstall Remote-SSH extension (on your local VS Code):
- Open VS Code
- Install extension:
ms-vscode-remote.remote-ssh
Connect to remote machine:
Cmd/Ctrl+Shift+P→ "Remote-SSH: Connect to Host..."- Enter:
user@remote-server(oruser@100.x.x.x) - VS Code opens connected to remote machine
- Open folder:
~/codebootstrap - Click "Reopen in Container"
Now you're running VS Code locally, connected to a devcontainer on your remote machine!
Local Machine Remote Machine
───────────── ──────────────
VS Code ──SSH──► CodeBootstrap container
(thin client) Tailscale - Claude Code
- All AI tools
- Your projects
Daily workflow:
- Open VS Code locally
Cmd/Ctrl+Shift+P→ "Remote-SSH: Connect to Host..." →remote-server- Open
~/codebootstrap - "Reopen in Container"
p my-projectand start coding
Add to ~/.ssh/config on your local machine:
Host dev
HostName remote-server # Or 100.x.x.x
User your-username
ForwardAgent yes
Now connect with just:
ssh dev
# Or in VS Code: connect to "dev"If you don't want to manage a remote server, you can also:
- Use GitHub Codespaces (cloud-hosted devcontainer)
- Install Tailscale in the Codespace for accessing other Tailscale resources
Can't connect via Tailscale SSH:
# Check Tailscale status on remote
tailscale status
# Ensure SSH is enabled
sudo tailscale up --ssh
# Check if tailscaled is running
sudo systemctl status tailscaledMagicDNS not resolving:
- Ensure MagicDNS is enabled in admin console
- Try flushing DNS:
sudo systemd-resolve --flush-caches - Fall back to IP:
ssh user@100.x.x.x
Permission denied:
- Check Tailscale ACLs in admin console
- Ensure your user has SSH access in ACL policy
VS Code Remote-SSH slow:
- Tailscale uses direct connections when possible
- If going through relay (DERP), check firewall/NAT settings
- Run
tailscale netcheckto diagnose
Access CodeBootstrap from your iPhone using an SSH app + Tailscale.
┌──────────────────────────────────────────────────────────┐
│ iPhone │
│ ┌────────────────────┐ ┌─────────────────────────┐ │
│ │ Tailscale app │ │ Termius / Blink Shell │ │
│ │ (VPN connection) │────▶│ ssh user@dev-server │ │
│ └────────────────────┘ │ $ cb │ │
│ │ $ c ← Claude Code │ │
│ └─────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
- Tailscale - App Store
- SSH App - Choose one:
- Open Tailscale app
- Sign in with same account as your remote machine
- Toggle VPN on
- Your devices are now connected
In your SSH app:
# Connect to your remote machine
ssh user@dev-server # or ssh user@100.x.x.x
# Enter the CodeBootstrap container (one command!)
cb
# You're now in the container - start coding
c # Start Claude Code
p my-project # Switch to a projectThese commands are installed on your host machine by host-setup.sh:
| Command | Description |
|---|---|
cb |
Enter container with persistent tmux session |
cb-raw |
Enter container without tmux (debugging) |
cb-start |
Start container in background |
cb-stop |
Stop the container |
cb-status |
Check if container is running |
Persistent sessions: cb automatically uses tmux. If you disconnect (close app, lose signal), your session continues running. Just cb again to reconnect exactly where you left off.
When you enter via cb, you'll see a quick reference:
┌─────────────────────────────────────────┐
│ CodeBootstrap Container │
└─────────────────────────────────────────┘
AI Tools c = Claude codex gemini
Projects p = list/switch new-project <name>
Status codebootstrap-status
For a remote dev server, you may want the container to start automatically when the machine boots.
Option A: Systemd Service (Recommended)
Create /etc/systemd/system/codebootstrap.service:
[Unit]
Description=CodeBootstrap Dev Container
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
User=your-username
WorkingDirectory=/home/your-username/codebootstrap
ExecStart=/usr/local/bin/devcontainer up --workspace-folder .
ExecStop=/usr/bin/docker stop $(docker ps -qf "name=codebootstrap")
[Install]
WantedBy=multi-user.targetEnable it:
sudo systemctl enable codebootstrap
sudo systemctl start codebootstrapOption B: Cron @reboot
crontab -e
# Add this line:
@reboot cd ~/codebootstrap && devcontainer up --workspace-folder . > /tmp/cb-start.log 2>&1Typing efficiency:
- Use short aliases:
c,p,gs,gd - Set up SSH key in your iOS app to avoid typing passwords
- Use Tailscale MagicDNS for short hostnames
Session persistence (automatic!):
cbuses tmux automatically - no setup needed- If you disconnect, everything keeps running
- Just run
cbagain to reconnect instantly - Your Claude session, open files, running processes - all preserved
Quick project access:
cb # Enter container
p my-project # Jump to project
c # Start ClaudePrefix key is Ctrl+a (easier on mobile than default Ctrl+b).
| Keys | Action |
|---|---|
Ctrl+a then | |
Split vertically |
Ctrl+a then - |
Split horizontally |
Ctrl+a then h/j/k/l |
Navigate panes (vim-style) |
Alt+Arrow |
Navigate panes (no prefix needed) |
Ctrl+a then d |
Detach (exit but keep running) |
Ctrl+a then c |
New window |
Ctrl+a then n/p |
Next/previous window |
Ctrl+a then x |
Kill pane |
Mouse is enabled - click to select panes, scroll to see history.
- Ensure Dev Containers extension is installed
- Try:
Cmd/Ctrl+Shift+P→ "Dev Containers: Reopen in Container"
- macOS/Windows: Start Docker Desktop
- Linux:
sudo systemctl start docker
- Run the auth command:
claude,codex auth, orgemini auth - If OAuth callback fails, forward the port in VS Code
- Ensure the volume mount exists in devcontainer.json
- Check:
docker volume ls | grep codebootstrap
- Run:
sudo chown -R vscode:vscode /workspaces/projects
- Try: "Dev Containers: Rebuild Container Without Cache"
- Check Docker has enough disk space
MIT