Vibe Coding DevContainer
Personal Project | OSS
Overview
A VS Code Dev Container template that reproduces a unified Python / Node.js development environment on local Macs and remote SSH servers alike. Claude Code and the Google Gemini CLI are bundled by default, so AI-assisted development (Vibe Coding) is available in the terminal the moment the container opens. Published as open source on GitHub.
Architecture
Built on Ubuntu 24.04 (Noble). The official uv multi-stage image is used only to copy the uv binary in; Python runtime management is fully delegated to uv, leaving the system Python untouched. Node.js is downloaded from the official tarball with `dpkg --print-architecture` branching between `aarch64 / x86_64`, so Apple Silicon, Intel, and ARM servers all run the same image unchanged.
The container runs as the non-root user `devcontainer`; `/usr/local/share/npm-global` is pre-created and owned by that user and `NPM_CONFIG_PREFIX` is set, so global `npm install` works without sudo — sidestepping the usual trap between non-root safety and npm ergonomics.
`workspaceMount` is bind-mounted with `delegated` consistency to accelerate heavy macOS file I/O (`node_modules`, git, build output). `NODE_OPTIONS=--max-old-space-size=4096` is declared as a container env var so Next.js and large TypeScript builds do not run out of heap.
- AI CLIs: Claude Code (official installer) and Google Gemini CLI (`@google/gemini-cli`)
- Shell: Zsh + Oh My Zsh + `zsh-syntax-highlighting` + fzf + git-delta
- Languages / tools: Node.js 24.13.0, uv 0.9.28, GitHub CLI, tmux, jq, tree, emacs-nox
- 13 VS Code extensions auto-installed (Claude Code, Gemini Companion, Cursor Pyright, Prettier / ESLint / Black, GitLens, Markdown All in One, Mermaid Chart, etc.)
- History persistence: `zsh_history` is mounted on a named volume (`devcontainer-zsh-history-<id>`) so it survives rebuilds
Host Integration & Remote Deployment
Bind-mounts the host's `~/.claude`, `~/.claude.json`, and `~/.gemini` so AI tool credentials survive container rebuilds — no daily re-login. `.zshrc` is committed as a shared baseline; `.gitconfig` is gitignored and generated by the bundled `sync-devcontainer.sh` from the local `~/.gitconfig`, so personal info never leaks into the repo while the shared config stays versioned.
`scripts/sync-devcontainer.sh` rsyncs the Mac-side credential files to any remote SSH server. After a `git clone` the remote can immediately "Reopen in Container", so paired with VS Code Remote-SSH the workflow "drive a dev container on a GPU server from a laptop" just works.
Tool versions (`NODE_VERSION`, `UV_VERSION`, `GEMINI_CLI_VERSION`, `GIT_DELTA_VERSION`, `ZSH_IN_DOCKER_VERSION`) are externalized as build args, so updates are a single-line diff in `devcontainer.json`. The image itself is trimmed with `apt-get clean && rm -rf /var/lib/apt/lists/*` to keep pull time and storage footprint low.