Install
$ agentstack add skill-redhatproductsecurity-prodsec-skills-devcontainer-setup Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged2 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Destructive filesystem operation.
- high Pipes remote content directly into a shell (remote code execution).
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Devcontainer Setup Skill
Creates a pre-configured devcontainer with language-specific tooling.
When to Use
- User asks to "set up a devcontainer" or "add devcontainer support"
- 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 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 the upstream plugin resources/ directory. (see upstream Trail of Bits prodsec-skills for companion files) 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:
- 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 --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
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→pnpm install --frozen-lockfileyarn.lock→yarn install --frozen-lockfilepackage-lock.json→npm ci- No lockfile →
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:
cargo build --locked
If no lockfile, use standard build:
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:
go mod download
Adding Persistent Volumes
Pattern for new mounts in devcontainer.json:
"mounts": [
"source={{PROJECT_SLUG}}--${devcontainerId},target=,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 configuration.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
Inlined reference material (upstream)
Companion docs from the Trail of Bits prodsec-skills devcontainer-setup plugin.
Dockerfile best practices
Dockerfile Best Practices
Quick Reference
| Practice | Why | |----------|-----| | Order by change frequency | Rarely-changing layers first (base, system packages), frequently-changing last | | Combine related RUN commands | Reduces layers and ensures cache coherence | | Clean up in same layer | Don't leave apt cache in a layer | | Use multi-stage builds | Separate build dependencies from runtime, reduce final image size | | Pin versions with digests | Supply chain security: FROM alpine:3.21@sha256:abc123... | | Switch to non-root user last | Do root operations first, then USER vscode | | Use COPY over ADD | ADD has extra features you usually don't need | | Use .dockerignore | Exclude build-irrelevant files to reduce context size |
Base Image Selection
Choose minimal, trusted base images:
- Docker Official Images - curated, documented, regularly updated
- Alpine Linux - under 6 MB, tightly controlled
- Verified Publisher or Docker-Sponsored Open Source images
Pin images to specific digests for reproducible builds:
FROM alpine:3.21@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
Avoid latest tag - it can change unexpectedly and cause breaking builds.
apt-get Best Practices
Always combine update with install in the same RUN statement:
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
git \
vim \
&& rm -rf /var/lib/apt/lists/*
Why combine? Keeping them separate causes Docker to cache the update layer, potentially installing outdated packages on subsequent builds.
Best practices:
- Use
--no-install-recommendsto minimize installed packages - Sort packages alphabetically within each section for easier maintenance and PR reviews
- Clean up with
rm -rf /var/lib/apt/lists/*in the same layer
Pipe Safety
When using pipes, prepend set -o pipefail && to fail if any command fails:
RUN set -o pipefail && curl -fsSL https://example.com/install.sh | bash
Without this, a failed curl would be masked by a successful bash.
Environment Variables
Use ENV for paths, versions, and configuration:
ENV PYTHON_VERSION=3.13
ENV PATH=/home/vscode/.local/bin:$PATH
Note: ENV instructions add metadata, not filesystem layers like RUN. Multiple separate ENV lines are fine and often more readable than combining them.
WORKDIR
Always use absolute paths. Avoid RUN cd ... && command patterns:
# Good
WORKDIR /app
RUN make install
# Bad
RUN cd /app && make install
Architecture Support
The templates support both AMD64 and ARM64 (Apple Silicon) automatically. Use TARGETARCH build arg for architecture-specific downloads:
ARG TARGETARCH
RUN curl -fsSL "https://example.com/tool-${TARGETARCH}.tar.gz" | tar xz
Devcontainer-Specific Tips
Resource allocation: Docker Desktop has limited defaults. Increase CPU/Memory in Docker settings for resource-intensive builds. Windows/WSL2: Use Docker Desktop's WSL 2 backend for better file sharing performance.
Sources
Features vs Dockerfile
Features vs Dockerfile
Use devcontainer features when:
- Installing standard development tools (GitHub CLI, languages, etc.)
- The feature does what you need out of the box
- You want automatic updates with feature version bumps
Use Dockerfile when:
- Installing specific versions of tools
- Custom configuration is needed
- Combining multiple tools in optimized layers
- The feature doesn't exist or is poorly maintained
Example: Python
For Python, we use Dockerfile + uv instead of the Python feature because:
- uv installs Python binaries instantly (vs compiling from source)
- We get uv for dependency management
- More control over the installation
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: RedHatProductSecurity
- Source: RedHatProductSecurity/prodsec-skills
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.