Claude Code Plugins

Community-maintained marketplace

Feedback

setting-up-devcontainers

@taisukeoe/agentic-ai-skills-creator
0
0

Generate devcontainer configurations for Claude Code development environments. Use when setting up development containers with Claude Code and optional Codex CLI. Automatically detects marketplace.json for plugin marketplace configurations.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name setting-up-devcontainers
description Generate devcontainer configurations for Claude Code development environments. Use when setting up development containers with Claude Code and optional Codex CLI. Automatically detects marketplace.json for plugin marketplace configurations.
license Apache-2.0
metadata [object Object]

Setting Up Devcontainers for Claude Code

Generate complete .devcontainer/ configurations for Claude Code development environments with:

  • Pre-installed Claude Code (+ optional Codex CLI built into Docker image)
  • Persistent credentials and config via Docker volumes
  • Marketplace mode (if marketplace.json exists): Auto-enabled plugins and skills

Quick Start

User: Set up a devcontainer for this project
Agent: I'll check for marketplace.json and generate the devcontainer configuration.

Workflow

Step 1: Detect Mode

Check for .claude-plugin/marketplace.json:

ls .claude-plugin/marketplace.json

Mode determination:

  • Marketplace mode: If marketplace.json exists → full plugin/skill setup
  • Generic mode: If not found → Claude Code environment (+ optional Codex CLI)

For Marketplace mode, extract:

  • name - Marketplace name (used for volume naming)
  • plugins - Array of plugin definitions

For Generic mode, use:

  • Project directory name for volume naming

Step 2: Ask About Codex CLI Support (Optional)

Ask the user explicitly:

Do you want to add Codex CLI (OpenAI) support alongside Claude Code?

  • Yes: Adds Volta, Node.js, Codex CLI, and skill sync mechanism
  • No (default): Claude Code only

If yes:

  • Add Volta/Node.js/Codex CLI installation to Dockerfile (installed at build time)
  • Add ~/.codex/ volume mount for config persistence
  • Add sync-codex-skills.sh script (copies skills to ~/.codex/skills/) [Marketplace mode only]
  • Add Codex sync call to post-create.sh [Marketplace mode only]

Note: Both Claude Code and Codex CLI are installed at Docker build time for faster container startup.

Step 3: Discover Plugins and Skills [Marketplace Mode Only]

Skip this step in Generic mode.

For each plugin in marketplace.json:

  1. Read source path (e.g., "./plugins/plugin-name")
  2. Check for .claude-plugin/plugin.json in source directory
  3. Find skills path from plugin.json or use ./skills/ default
  4. List all SKILL.md files in skills directory
  5. Extract skill names from directory names

Build two lists:

  • enabledPlugins: {"plugin-name@marketplace-name": true, ...}
  • allowedSkills: ["Skill(skill-1)", "Skill(skill-2)", ...]

Step 4: Ask About Auto-Sync on Container Start [Marketplace Mode Only]

Skip this step in Generic mode.

Ask the user explicitly:

Do you want to automatically reinstall the marketplace on every container start?

  • Yes: Adds postStartCommand to run reinstall-marketplace.sh automatically
  • No (recommended for stable development): Run manually when needed

Note: This is a workaround for Claude Code not detecting local plugin changes. Running on every start adds ~5-10 seconds delay.

Step 5: Generate Files from Templates

Use the templates in templates/ directory, substituting placeholders:

Common Placeholders

Placeholder Value
{{PROJECT_NAME}} Marketplace name (if exists) or project directory name
{{PROJECT_DIR}} Project directory name
{{CODEX_VOLUME_MOUNT}} If Codex: ,\n "source=codex-config-{{PROJECT_NAME}},..." else: empty
{{VOLTA_ENV_BLOCK}} If Codex: ENV VOLTA_HOME=... ENV PATH=... else: empty
{{CODEX_INSTALL_BLOCK}} If Codex: Volta/Codex RUN command, else: empty
{{CODEX_DIR_LIST}} If Codex: "$HOME/.codex" else: empty
{{CODEX_ALIASES}} If Codex: Codex alias lines, else: empty
{{CODEX_ALIAS_ECHO}} If Codex: echo " codex-f - codex --full-auto" else: empty
{{DEVCONTAINER_READY_MESSAGE}} "Claude Code devcontainer ready!" or "Claude Code + Codex CLI devcontainer ready!"

Marketplace Mode Placeholders

Placeholder Value
{{ENABLED_PLUGINS}} Object entries like "plugin@market": true
{{ALLOWED_SKILLS}} Array entries like "Skill(name)"
{{PLUGIN_INSTALL_COMMANDS}} Plugin install commands (with `
{{CODEX_SETUP_BLOCK}} If Codex and Marketplace mode: Codex skill sync in post-create.sh, else: empty
{{CODEX_SYNC_BLOCK}} If Codex: Codex sync in reinstall-marketplace.sh, else: empty
{{POST_START_COMMAND}} If auto-sync: ,\n "postStartCommand": "bash .devcontainer/reinstall-marketplace.sh" else: empty
{{SETTINGS_BLOCK}} Shell commands to create settings.json with enabledPlugins/allowedSkills
{{MARKETPLACE_REGISTER_BLOCK}} Marketplace registration and plugin install commands
{{MARKETPLACE_SYNC_HINT}} echo "To sync marketplace: bash .devcontainer/reinstall-marketplace.sh"

Generic Mode Placeholders

Placeholder Value
{{POST_START_COMMAND}} empty (no postStartCommand)
{{SETTINGS_BLOCK}} empty (no plugin settings needed)
{{MARKETPLACE_REGISTER_BLOCK}} empty (no marketplace registration)
{{CODEX_SETUP_BLOCK}} empty (no skill sync needed)
{{MARKETPLACE_SYNC_HINT}} empty

Templates:

Conditional logic:

  • Generic mode: Omit reinstall-marketplace.sh and sync-codex-skills.sh
  • If user chose no auto-sync: Remove postStartCommand from devcontainer.json
  • If user chose no Codex: Omit Volta/Codex sections

Step 6: Write Files and Set Permissions

  1. Create .devcontainer/ directory if not exists
  2. Write all generated files (without .template suffix)
  3. Make shell scripts executable: chmod +x .devcontainer/*.sh

Step 7: Provide Usage Instructions

Generic mode:

Devcontainer files created in .devcontainer/

To use:
1. Open project in VS Code
2. Click "Reopen in Container" when prompted
   (or use Command Palette: "Dev Containers: Reopen in Container")
3. Run 'claude' on first use to complete initial setup

Your credentials persist in Docker volumes.

Marketplace mode:

Devcontainer files created in .devcontainer/

To use:
1. Open project in VS Code
2. Click "Reopen in Container" when prompted
   (or use Command Palette: "Dev Containers: Reopen in Container")
3. Run 'claude' on first use to complete initial setup

Your credentials persist in Docker volumes.

To manually sync marketplace changes:
  bash .devcontainer/reinstall-marketplace.sh

Generated File Locations

Generic mode:

.devcontainer/
├── devcontainer.json         # Container configuration
├── Dockerfile                # Ubuntu + Claude Code (+ Volta/Codex if enabled)
└── post-create.sh            # Initial setup (config, aliases)

Marketplace mode:

.devcontainer/
├── devcontainer.json         # Container configuration
├── Dockerfile                # Ubuntu + Claude Code (+ Volta/Codex if enabled)
├── post-create.sh            # Initial setup (config, marketplace, Codex sync)
├── reinstall-marketplace.sh  # Marketplace sync script (+ Codex sync if enabled)
└── sync-codex-skills.sh      # Codex skill sync (only if Codex enabled)

Key Configuration Details

Volume Strategy

Uses named Docker volumes plus a symlink for complete persistence:

Docker Image (built once):
├── ~/.local/bin/claude      # Claude Code binary
└── ~/.volta/                # Volta + Node.js + Codex CLI (if enabled)

Volume 1: claude-config-${PROJECT_NAME} → ~/.claude/
├── .home-claude.json        # Setup state (symlink target)
├── .credentials.json        # Auth tokens
├── settings.json            # User settings
└── plugins/                 # Plugin data (Marketplace mode)

Volume 2: claude-data-${PROJECT_NAME} → ~/.local/share/claude/
└── (Claude Code data)       # Session data, etc.

Volume 3 (if Codex enabled): codex-config-${PROJECT_NAME} → ~/.codex/
├── config.toml              # Codex CLI configuration
├── sessions/                # Session data
└── skills/                  # Synced skills from marketplace (Marketplace mode)

Symlink (created by post-create.sh):
~/.claude.json → ~/.claude/.home-claude.json

Why this architecture?

Location Purpose Persistence Method
~/.local/bin/claude Claude Code binary Docker image (fast startup)
~/.volta/ Codex CLI binary Docker image (fast startup)
~/.claude/ Config, credentials, settings Volume mount
~/.local/share/claude/ Claude session data Volume mount
~/.claude.json Initial setup state Symlink to volume
~/.codex/ (optional) Codex config, sessions, skills Volume mount

Important: ~/.claude.json cannot be directly mounted as a volume (Docker creates a directory instead of a file). The symlink approach allows the file to persist inside the ~/.claude/ volume.

Shell Alias

The setup creates a persistent alias file in the volume:

  • post-create.sh creates ~/.claude/.shell-aliases (persists in volume)
  • post-create.sh adds source line to .zshrc (both modes, with duplicate protection)
  • reinstall-marketplace.sh also adds source line to .zshrc on every start (Marketplace mode only)
# ~/.claude/.shell-aliases (persisted)
alias claude-y='claude --dangerously-skip-permissions'

# If Codex enabled:
alias codex-f='codex --full-auto'

This survives container rebuilds because the alias file is stored in the volume.

Plugin Format [Marketplace Mode Only]

enabledPlugins must be object format (not array):

{
  "enabledPlugins": {
    "plugin-a@marketplace": true,
    "plugin-b@marketplace": true
  }
}

Marketplace Sync (Workaround) [Marketplace Mode Only]

reinstall-marketplace.sh is a workaround for Claude Code not automatically detecting local plugin/skill changes.

What it does:

  • Removes and re-adds the marketplace
  • Reinstalls all enabled plugins

When to run:

  • Manually after editing SKILL.md files: bash .devcontainer/reinstall-marketplace.sh
  • Or automatically via postStartCommand (if user opted in)

Error Handling

Error Cause Solution
No plugins found Empty plugins array Warn user, generate minimal config
Source path invalid Plugin source doesn't exist Report error, skip invalid plugins
Existing .devcontainer/ Files already present Ask before overwriting
GID/UID 1000 already exists Ubuntu base image has existing user Use getent to detect and rename existing user
Permission denied on config Volume owned by root Use sudo chown in post-create.sh
claude: command not found PATH not set Export PATH="$HOME/.local/bin:$PATH" in scripts
EISDIR on ~/.claude.json Volume mounted as directory Remove directory, use symlink instead
JSON Parse error: Unexpected EOF Empty ~/.claude.json file Initialize with {} not empty file
Raw mode not supported Plugin commands in non-interactive shell Only run plugin commands if setup complete
Login required after rebuild ~/.claude.json not persisted Symlink to file inside volume

References