Skip to content

Build Environment

wody edited this page May 23, 2026 · 5 revisions

Build Environment

The slim Docker image intentionally ships without Android SDK / Gradle cache / MCP servers / Playwright. On first boot, the operator installs them once through the Build environment page; subsequent image upgrades preserve everything via the unified ./vibe-coder-data/dev-tools/ bind mount.

Web UI flow (recommended)

  1. Sign in → left nav → Build environment (/env-setup).
  2. The top "Install/update all" button covers JDK 17 (image-bundled), Node 20 + Claude CLI (image-bundled), Android SDK (volume), and base MCP prompt (you'll be redirected to the catalog).
  3. Per-card buttons let you install components individually.
  4. The progress page shows live install logs + elapsed time (no progress bar — install duration is unknowable in advance).

CLI equivalents

docker exec -it vibe-coder-server vibe-doctor                  # interactive
docker exec -it vibe-coder-server vibe-doctor check            # diagnostics only
docker exec    vibe-coder-server vibe-doctor install           # bulk non-interactive
docker exec -it vibe-coder-server vibe-doctor android          # SDK only
docker exec -it vibe-coder-server vibe-doctor claude           # Claude auth helper
docker exec -it vibe-coder-server vibe-doctor mcp              # MCP prompt

Component matrix

Component Auto-installable Size Path
JDK 17 (eclipse-temurin) image-bundled ~200 MB /opt/java/openjdk
Node 20 + npm image-bundled ~150 MB /usr/bin/{node,npm}
Claude Code CLI image-bundled bundled in Node global /usr/local/lib/node_modules/@anthropic-ai/claude-code
util-linux (script) image-bundled small apt
sudo NOPASSWD for vibe image-bundled n/a /etc/sudoers.d/vibe-nopasswd
Android SDK ✅ via doctor 3-4 GB /opt/android-sdk (bind mount → ./vibe-coder-data/dev-tools/android-sdk/)
Gradle (host binary, v0.12.3+) ✅ via doctor ~130 MB /home/vibe/.local/gradle/ (PATH: gradle) — wrapper bootstrap
Gradle dependency cache filled on first build 1-2 GB /home/vibe/.gradle (bind mount → ./vibe-coder-data/dev-tools/gradle/)
MCP servers (npm -g) ✅ via MCP catalog varies /home/vibe/.local (bind mount → ./vibe-coder-data/dev-tools/npm-global/)
Playwright browsers optional, via MCP ~300 MB /home/vibe/.cache/ms-playwright (bind mount)
Claude auth credentials ✅ via Claude auth UI a few KB /home/vibe/.claude (bind mount → ./vibe-coder-data/claude/)

Gradle wrapper alignment (v0.12.3+ / v0.14.1 policy)

When you install Gradle through the Build environment page, the binary lands at /home/vibe/.local/gradle/ and is exposed as gradle on PATH. The ClaudeMdTemplate (the CLAUDE.md placed in every new project) instructs Claude to use this binary for wrapper bootstrap and to align the project's gradle-wrapper.properties to the installed version, so a single host Gradle install is reused across all projects instead of every project downloading its own.

If you're seeing a project trigger a second Gradle download, check:

  1. gradle --version inside the container — confirms what's installed.
  2. The project's gradle/wrapper/gradle-wrapper.properties — what version the wrapper insists on.
  3. Edit the distributionUrl to match the installed version, or run gradle wrapper --gradle-version <installed> --distribution-type bin.

Existing projects (CLAUDE.md scaffolded before v0.14.1) won't have this guidance — the template is only applied to new projects via ProjectScaffolder.ensureClaudeFiles (which has a notExists() guard so it never overwrites). For existing projects, paste the "Installed Build Tools" section from the v0.14.1+ template by hand, or delete the project's CLAUDE.md and let the next prompt re-scaffold it.

Why v0.7.0 was the unification milestone

Pre-0.7.0:

  • Android SDK + Gradle cache were Docker named volumesvibe-android-sdk, vibe-gradle-cache. They survived docker compose up -d --force-recreate but vanished on docker compose down -v.
  • MCP servers (installed by vibe-doctor mcpnpm install -g) lived in the image's system directory /usr/local/lib/node_modules/. On docker compose pull && up -d, the new image had a fresh empty /usr/local/... and the MCPs vanished.
  • /home/vibe/.npm, /home/vibe/.cache, /home/vibe/.config had no mount at all.

v0.7.0 changes:

  • vibe user's npm prefix moved to /home/vibe/.local (via ~/.npmrc).
  • All persistent directories collapsed under ./vibe-coder-data/ (single host directory, no named volumes by default).
  • New volumes for npm-global, npm-cache, playwright, config.
  • Image upgrade → tools survive guaranteed.

Manual MCP installation (not in the catalog)

You can install any npm-distributed MCP that isn't in the curated catalog:

docker exec -it --user vibe vibe-coder-server bash

# Install your MCP (this goes to /home/vibe/.local — persistent!)
npm install -g some-mcp-server

# Register it in Claude
cat > ~/.claude/.mcp.json <<'JSON'
{
  "mcpServers": {
    "my-mcp": {
      "command": "npx",
      "args": ["-y", "some-mcp-server"],
      "env": { "SOME_TOKEN": "..." }
    }
  }
}
JSON

Since /home/vibe/.local and /home/vibe/.claude are both bind-mounted to ./vibe-coder-data/, your manual installations survive image upgrades.

Clone this wiki locally