devcontainer-setup
- Use it when:
- You want Claude Code to work in an isolated container instead of directly on your machine.
- It does:
- Reads the project name and languages from package.json, pyproject.toml, Cargo.toml or go.mod, then fills its templates with matching extensions, settings and setup commands.
- You get:
- A Dockerfile, devcontainer.json, post_install.py, .zshrc and an install.sh that adds a devc command, all in .devcontainer/.
- Inside:
- Claude Code without permission prompts, Python 3.13 via uv, Node 22, ripgrep, fd, fzf, tmux, ast-grep, bubblewrap, and iptables for network rules.
- Starts with:
- VS Code's Reopen in Container, or devcontainer up from the command line.
The container runs Claude Code in bypassPermissions mode, forwards your CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY, and adds the anthropics/skills, trailofbits/skills and trailofbits/skills-curated marketplaces.
TL;DR
From Trail of Bits. The project name comes from the first of package.json, pyproject.toml, Cargo.toml or go.mod that has one, falling back to the directory name, and its slug names persistent volumes that keep shell history, Claude's config and GitHub CLI auth across rebuilds. Python projects get the Python, Pylance and Ruff extensions and uv sync; Node projects get ESLint and Prettier and an install command matched to the lockfile; Rust and Go add their devcontainer features. Several languages are merged into one configuration. Inside the container, .devcontainer/ and your ~/.gitconfig are mounted read-only, the NET_ADMIN capability lets you restrict outbound traffic with iptables, npm install scripts are off and packages must be a day old before npm installs them. Claude Code is set to bypassPermissions, so it acts without asking inside the container, and your CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY is forwarded in from your machine. Its image also adds the anthropics/skills, trailofbits/skills and trailofbits/skills-curated plugin marketplaces. It is for development environments, not production containers, and not for changing a devcontainer you already have.
Summarizes the skill at e4dd0bb.
npx skills add https://github.com/trailofbits/skills --skill devcontainer-setup skills.sh pageSource on GitHubAll skills from trailofbits/skills
- Total Downloads
- 5,600 on skills.sh, Nov 9, 2026
- Repo stars
- 8,081 trailofbits/skills
- First seen
- Feb 10, 2026 on skills.sh
Weekly values
| Week to | Installs |
|---|---|
| Sep 21 | 109 |
| Sep 28 | 113 |
| Oct 5 | 112 |
| Oct 12 | 141 |
| Oct 19 | 130 |
| Oct 26 | 154 |
| Nov 2 | 170 |
| Nov 9 | 181 |
| Category |
Test-first work, implementation from specs, git hygiene and scope control. Compliance, guardrails, skill vetting and browser fingerprinting. Everything for building software: planning, coding, debugging, design, frameworks, cloud, agents and skills. |
|---|---|
| Type |
One-time configuration or scaffolding of a project, account or tool. |
| Effect |
Its own steps create or change files, git state or local tools. |
| Needs |
A specific command-line tool or desktop app must be installed, such as gh, agent-browser, LibreOffice, Obsidian or a vendor CLI. |
| Publisher |
A verified publisher on skills.sh, or the company or maintainer behind the product the skill operates. |
| Topics | |
| Stack |
SKILL.md
From trailofbits/skills at e4dd0bb. Checked daily, last changed Nov 6, 2026.
Frontmatter
name: devcontainer-setup
description: Creates devcontainers with Claude Code, language-specific tooling (Python/Node/Rust/Go), and persistent volumes. Use when adding devcontainer support to a project, setting up isolated development environments, or configuring sandboxed Claude Code workspaces.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→namefieldpyproject.toml→project.nameCargo.toml→package.namego.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)
- Sandboxing via bubblewrap and socat
- 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
- Security mounts:
.devcontainer/mounted read-only to prevent container escape - Token forwarding:
CLAUDE_CODE_OAUTH_TOKENandANTHROPIC_API_KEYviaremoteEnv - 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-lockfileyarn.lock→uv run /opt/post_install.py && yarn install --frozen-lockfilepackage-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 supportreferences/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 instructionsdevcontainer.json- VS Code/devcontainer configurationpost_install.py- Post-creation setup script.zshrc- Shell configurationinstall.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