Skills trailofbits skills

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
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 Downloads
181
+66% over the 8 weeks to Nov 9
Weekly values
Week toInstalls
Sep 21109
Sep 28113
Oct 5112
Oct 12141
Oct 19130
Oct 26154
Nov 2170
Nov 9181
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):

  1. package.json → name field
  2. pyproject.toml → project.name
  3. Cargo.toml → package.name
  4. go.mod → module path (last segment after /)
  5. 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:

  1. Python - Primary language, uses Dockerfile for uv + Python installation
  2. Node/TypeScript - Uses devcontainer feature
  3. Rust - Uses devcontainer feature
  4. 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_TOKEN and ANTHROPIC_API_KEY via remoteEnv
  • 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:

  1. Dockerfile - Container build instructions
  2. devcontainer.json - VS Code/devcontainer configuration
  3. post_install.py - Post-creation setup script
  4. .zshrc - Shell configuration
  5. install.sh - CLI helper for managing the devcontainer (devc command)

Validation Checklist

Before presenting files to the user, verify:

  1. All {{PROJECT_NAME}} placeholders are replaced with the human-readable name
  2. All {{PROJECT_SLUG}} placeholders are replaced with the slugified name
  3. JSON syntax is valid in devcontainer.json (no trailing commas, proper nesting)
  4. Language-specific extensions are added for all detected languages
  5. postCreateCommand includes all required setup commands (chained with &&)

User Instructions

After generating, inform the user:

  1. How to start: "Open in VS Code and select 'Reopen in Container'"
  2. Alternative: devcontainer up --workspace-folder .
  3. CLI helper: Run .devcontainer/install.sh self-install to add the devc command to PATH