Dev Container Cheat Sheet
Overview
Dev Containers (Development Containers) provide a standardized specification for creating reproducible, containerized development environments. Using a devcontainer.json configuration file, teams define the tools, runtimes, extensions, and settings needed for a project, ensuring every developer works in an identical environment regardless of their host OS.
The specification is supported by VS Code, GitHub Codespaces, JetBrains IDEs, and the standalone Dev Container CLI. Dev Containers leverage Docker (or Podman) to run a complete development environment in a container while mounting source code from the host, giving developers the best of both local editing and containerized tooling.
Installation
VS Code Extension
# Install the Dev Containers extension
code --install-extension ms-vscode-remote.remote-containers
# Prerequisites: Docker Desktop or Docker Engine must be running
docker --version
Dev Container CLI
# Install via npm
npm install -g @devcontainers/cli
# Verify
devcontainer --version
# Build and start from CLI
devcontainer up --workspace-folder .
# Execute command inside container
devcontainer exec --workspace-folder . npm test
Core Configuration
Basic devcontainer.json
{
"name": "My Project Dev Container",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "20"
},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.12"
}
},
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
],
"settings": {
"editor.formatOnSave": true
}
}
},
"forwardPorts": [3000, 5432],
"postCreateCommand": "npm install",
"remoteUser": "vscode"
}
Using Dockerfile
{
"name": "Custom Dev Container",
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
"NODE_VERSION": "20"
}
},
"mounts": [
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,readonly"
],
"postCreateCommand": "bash .devcontainer/setup.sh"
}
# .devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu
ARG NODE_VERSION=20
RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g yarn
RUN apt-get update && apt-get install -y \
postgresql-client \
redis-tools \
&& rm -rf /var/lib/apt/lists/*
Using Docker Compose
{
"name": "Full Stack Dev",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"forwardPorts": [3000, 5432, 6379],
"postCreateCommand": "npm install && npm run db:migrate"
}
# .devcontainer/docker-compose.yml
version: '3.8'
services:
app:
build:
context: ..
dockerfile: .devcontainer/Dockerfile
volumes:
- ..:/workspace:cached
command: sleep infinity
depends_on:
- db
- redis
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpass
POSTGRES_DB: myapp_dev
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
pgdata:
Features
Common Dev Container Features
{
"features": {
"ghcr.io/devcontainers/features/node:1": { "version": "20" },
"ghcr.io/devcontainers/features/python:1": { "version": "3.12" },
"ghcr.io/devcontainers/features/go:1": { "version": "1.22" },
"ghcr.io/devcontainers/features/rust:1": { "version": "latest" },
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {},
"ghcr.io/devcontainers/features/aws-cli:1": {},
"ghcr.io/devcontainers/features/terraform:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": true,
"configureZshAsDefaultShell": true
}
}
}
Configuration
Lifecycle Commands
{
"initializeCommand": "echo 'Running on host before container starts'",
"onCreateCommand": "echo 'Container created for first time'",
"updateContentCommand": "echo 'Runs after repo clone/update'",
"postCreateCommand": "npm install && npm run build",
"postStartCommand": "echo 'Container started'",
"postAttachCommand": "echo 'Editor attached to container'"
}
Port Forwarding
{
"forwardPorts": [3000, 5432, 8080],
"portsAttributes": {
"3000": {
"label": "Frontend",
"onAutoForward": "openBrowser"
},
"5432": {
"label": "PostgreSQL",
"onAutoForward": "silent"
},
"8080": {
"label": "API",
"onAutoForward": "notify"
}
}
}
Environment Variables and Mounts
{
"containerEnv": {
"NODE_ENV": "development",
"DATABASE_URL": "postgres://postgres:devpass@db:5432/myapp_dev"
},
"remoteEnv": {
"LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
},
"mounts": [
"source=${localEnv:HOME}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,readonly",
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,readonly",
"source=myproject-node-modules,target=/workspace/node_modules,type=volume"
]
}
Advanced Usage
Multi-Root Workspaces
{
"name": "Monorepo Dev",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"postCreateCommand": "npm install --workspaces",
"customizations": {
"vscode": {
"extensions": ["dbaeumer.vscode-eslint"],
"settings": {
"eslint.workingDirectories": [
{ "directory": "packages/frontend" },
{ "directory": "packages/backend" }
]
}
}
}
}
GPU Support
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/nvidia-cuda:1": {
"cudaVersion": "12.2"
}
},
"hostRequirements": {
"gpu": "optional"
},
"runArgs": ["--gpus", "all"]
}
Dev Container CLI Commands
# Build the dev container
devcontainer build --workspace-folder .
# Start the container
devcontainer up --workspace-folder .
# Run a command inside
devcontainer exec --workspace-folder . bash
# Read configuration
devcontainer read-configuration --workspace-folder .
# Run lifecycle commands manually
devcontainer run-user-commands --workspace-folder .
Troubleshooting
| Issue | Solution |
|---|---|
| Container fails to start | Check Docker is running; inspect docker logs |
| Extensions not installing | Verify extension IDs in customizations.vscode.extensions |
| Volume mount permissions | Set remoteUser to match container user |
| Slow file I/O on macOS | Use named volumes for node_modules |
| Feature install fails | Check feature version and network connectivity |
| Port already in use | Change host port or stop conflicting service |
# Rebuild container from scratch
# VS Code: Ctrl+Shift+P > "Dev Containers: Rebuild Container"
# CLI rebuild
devcontainer up --workspace-folder . --remove-existing-container
# Check container logs
docker logs <container-id>
# Inspect running container
docker exec -it <container-id> bash
# Clear Dev Container cache
docker system prune -a