Devcontainer Setup Skill
Creates a pre-configured devcontainer with Claude Code and language-specific tooling.
When to Use
- •User asks to "set up a devcontainer" or "add devcontainer support"
- •User wants a sandboxed Claude Code development environment
- •User needs isolated development environments with persistent configuration
When NOT to Use
- •User already has a devcontainer configuration and just needs modifications
- •User is asking about general Docker or container questions
- •User wants to deploy production containers (this is for development only)
Workflow
flowchart TB
start([User requests devcontainer])
recon[1. Project Reconnaissance]
detect[2. Detect Languages]
generate[3. Generate Configuration]
write[4. Write files to .devcontainer/]
done([Done])
start --> recon
recon --> detect
detect --> generate
generate --> write
write --> done
Phase 1: Project Reconnaissance
Infer Project Name
Check in order (use first match):
- •
package.json→namefield - •
pyproject.toml→project.name - •
Cargo.toml→package.name - •
go.mod→ module path (last segment after/) - •Directory name as fallback
Convert to slug: lowercase, replace spaces/underscores with hyphens.
Detect Language Stack
| Language | Detection Files |
|---|---|
| Python | pyproject.toml, *.py |
| Node/TypeScript | package.json, tsconfig.json |
| Rust | Cargo.toml |
| Go | go.mod, go.sum |
Multi-Language Projects
If multiple languages are detected, configure all of them in the following priority order:
- •Python - Primary language, uses Dockerfile for uv + Python installation
- •Node/TypeScript - Uses devcontainer feature
- •Rust - Uses devcontainer feature
- •Go - Uses devcontainer feature
For multi-language postCreateCommand, chain all setup commands:
uv run /opt/post_install.py && uv sync && npm ci
Extensions and settings from all detected languages should be merged into the configuration.
Phase 2: Generate Configuration
Start with base templates from resources/ directory. Substitute:
- •
{{PROJECT_NAME}}→ Human-readable name (e.g., "My Project") - •
{{PROJECT_SLUG}}→ Slug for volumes (e.g., "my-project")
Then apply language-specific modifications below.
Base Template Features
The base template includes:
- •Claude Code with marketplace plugins (anthropics/skills, trailofbits/skills, trailofbits/skills-curated)
- •Python 3.13 via uv (fast binary download)
- •Node 22 via fnm (Fast Node Manager)
- •ast-grep for AST-based code search
- •Network isolation tools (iptables, ipset) with NET_ADMIN capability
- •Modern CLI tools: ripgrep, fd, fzf, tmux, git-delta
Language-Specific Sections
Python Projects
Detection: pyproject.toml, requirements.txt, setup.py, or *.py files
Dockerfile additions:
The base Dockerfile already includes Python 3.13 via uv. If a different version is required (detected from pyproject.toml), modify the Python installation:
# Install Python via uv (fast binary download, not source compilation) RUN uv python install <version> --default
devcontainer.json extensions:
Add to customizations.vscode.extensions:
"ms-python.python", "ms-python.vscode-pylance", "charliermarsh.ruff"
Add to customizations.vscode.settings:
"python.defaultInterpreterPath": ".venv/bin/python",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
}
postCreateCommand:
If pyproject.toml exists, chain commands:
rm -rf .venv && uv sync && uv run /opt/post_install.py
Node/TypeScript Projects
Detection: package.json or tsconfig.json
No Dockerfile additions needed: The base template includes Node 22 via fnm (Fast Node Manager).
devcontainer.json extensions:
Add to customizations.vscode.extensions:
"dbaeumer.vscode-eslint", "esbenp.prettier-vscode"
Add to customizations.vscode.settings:
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
postCreateCommand: Detect package manager from lockfile and chain with base command:
- •
pnpm-lock.yaml→uv run /opt/post_install.py && pnpm install --frozen-lockfile - •
yarn.lock→uv run /opt/post_install.py && yarn install --frozen-lockfile - •
package-lock.json→uv run /opt/post_install.py && npm ci - •No lockfile →
uv run /opt/post_install.py && npm install
Rust Projects
Detection: Cargo.toml
Features to add:
"ghcr.io/devcontainers/features/rust:1": {}
devcontainer.json extensions:
Add to customizations.vscode.extensions:
"rust-lang.rust-analyzer", "tamasfe.even-better-toml"
Add to customizations.vscode.settings:
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
postCreateCommand:
If Cargo.lock exists, use locked builds:
uv run /opt/post_install.py && cargo build --locked
If no lockfile, use standard build:
uv run /opt/post_install.py && cargo build
Go Projects
Detection: go.mod
Features to add:
"ghcr.io/devcontainers/features/go:1": {
"version": "latest"
}
devcontainer.json extensions:
Add to customizations.vscode.extensions:
"golang.go"
Add to customizations.vscode.settings:
"[go]": {
"editor.defaultFormatter": "golang.go"
},
"go.useLanguageServer": true
postCreateCommand:
uv run /opt/post_install.py && go mod download
Reference Material
For additional guidance, see:
- •
references/dockerfile-best-practices.md- Layer optimization, multi-stage builds, architecture support - •
references/features-vs-dockerfile.md- When to use devcontainer features vs custom Dockerfile
Adding Persistent Volumes
Pattern for new mounts in devcontainer.json:
"mounts": [
"source={{PROJECT_SLUG}}-<purpose>-${devcontainerId},target=<container-path>,type=volume"
]
Common additions:
- •
source={{PROJECT_SLUG}}-cargo-${devcontainerId},target=/home/vscode/.cargo,type=volume(Rust) - •
source={{PROJECT_SLUG}}-go-${devcontainerId},target=/home/vscode/go,type=volume(Go)
Output Files
Generate these files in the project's .devcontainer/ directory:
- •
Dockerfile- Container build instructions - •
devcontainer.json- VS Code/devcontainer configuration - •
post_install.py- Post-creation setup script - •
.zshrc- Shell configuration - •
install.sh- CLI helper for managing the devcontainer (devccommand)
Validation Checklist
Before presenting files to the user, verify:
- •All
{{PROJECT_NAME}}placeholders are replaced with the human-readable name - •All
{{PROJECT_SLUG}}placeholders are replaced with the slugified name - •JSON syntax is valid in
devcontainer.json(no trailing commas, proper nesting) - •Language-specific extensions are added for all detected languages
- •
postCreateCommandincludes all required setup commands (chained with&&)
User Instructions
After generating, inform the user:
- •How to start: "Open in VS Code and select 'Reopen in Container'"
- •Alternative:
devcontainer up --workspace-folder . - •CLI helper: Run
.devcontainer/install.sh self-installto add thedevccommand to PATH