TL;DR — Quick Summary
Dev Containers let you define reproducible development environments using Docker. Learn setup, configuration, multi-service stacks and team standardization.
Dev Containers eliminate the classic “works on my machine” problem by defining your entire development environment as code. Using a devcontainer.json file committed to your repository, every developer gets an identical setup — same runtime versions, same tools, same extensions, same environment variables — regardless of their host operating system. This guide covers everything from basic setup to advanced multi-service configurations.
Prerequisites
- VS Code with the Dev Containers extension installed
- Docker Desktop (macOS/Windows) or Docker Engine (Linux)
- Basic familiarity with Docker concepts (images, containers, volumes)
Quick Start
Step 1: Create the Configuration
Create .devcontainer/devcontainer.json in your project root:
{
"name": "My Project",
"image": "mcr.microsoft.com/devcontainers/typescript-node:22",
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
},
"customizations": {
"vscode": {
"extensions": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ms-azuretools.vscode-docker"
],
"settings": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
},
"forwardPorts": [3000, 5432],
"postCreateCommand": "npm install",
"remoteUser": "node"
}
Step 2: Open in Container
- Open your project in VS Code
- Press
Ctrl+Shift+P→ Dev Containers: Reopen in Container - VS Code builds the image (first time takes 1-3 minutes) and reconnects inside the container
Your terminal, file explorer, and extensions now run inside the container with all tools pre-configured.
Key Configuration Options
| Property | Purpose | Example |
|---|---|---|
image | Base Docker image | mcr.microsoft.com/devcontainers/python:3.12 |
build.dockerfile | Custom Dockerfile path | Dockerfile.dev |
features | Add-on tools (Git, Docker, AWS CLI) | ghcr.io/devcontainers/features/aws-cli:1 |
forwardPorts | Ports to forward to host | [3000, 8080, 5432] |
postCreateCommand | Run after container creation | npm install && npm run build |
postStartCommand | Run on every container start | npm run dev |
mounts | Additional volume mounts | SSH keys, cloud credentials |
remoteUser | Non-root user inside container | node, vscode |
Multi-Service Environment with Docker Compose
For projects that need a database, Redis, or other services:
{
"name": "Full Stack App",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"forwardPorts": [3000, 5432, 6379],
"customizations": {
"vscode": {
"extensions": [
"esbenp.prettier-vscode",
"ms-azuretools.vscode-docker"
]
}
}
}
With a companion docker-compose.yml:
services:
app:
build:
context: ..
dockerfile: .devcontainer/Dockerfile
volumes:
- ..:/workspace:cached
command: sleep infinity
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpass
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
pgdata:
Dev Container Features
Features are modular tools you can add to any base image:
{
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/aws-cli:1": {},
"ghcr.io/devcontainers/features/terraform:1": {},
"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {}
}
}
Browse available features at containers.dev/features.
Comparison
| Feature | Dev Containers | Docker Compose (manual) | Vagrant | Nix |
|---|---|---|---|---|
| IDE integration | Native VS Code | Manual | Plugin | Plugin |
| Setup time | Minutes | Hours | Hours | Hours |
| Reproducibility | Excellent | Good | Good | Excellent |
| Performance | Near-native | Native | VM overhead | Native |
| Team adoption | Low friction | Medium | High | Very high |
| Cloud option | GitHub Codespaces | No | No | No |
Real-World Scenario
Your team has 8 developers across macOS, Windows, and Linux. A new hire spent 2 days configuring their environment manually and still had test failures due to a Node.js version mismatch. After adding a devcontainer.json, new developers open the project in VS Code, click “Reopen in Container,” wait 2 minutes, and have a fully working environment — identical to every other team member. Onboarding time drops from 2 days to 10 minutes.
Gotchas and Tips
- Performance on macOS: Use the
cachedmount option for volumes to improve file I/O performance - Git credentials: Dev Containers automatically forward your host’s Git credentials and SSH agent — no manual configuration needed
- Rebuild vs. recreate: Use “Dev Containers: Rebuild Container” after changing
devcontainer.jsonor the Dockerfile. “Rebuild Without Cache” for a clean rebuild - Dotfiles: Configure a personal dotfiles repository in VS Code settings to automatically apply your shell customizations inside any Dev Container
- GPU support: For ML/AI workloads, use the
--gpusflag inrunArgsto pass through NVIDIA GPUs to the container
Troubleshooting
- Container fails to build: Check Docker is running, pull the base image manually (
docker pull mcr.microsoft.com/devcontainers/typescript-node:22), and check Dockerfile syntax - Extensions not installing: Verify extension IDs are correct. Some extensions only work in the host, not in containers
- Port forwarding not working: Check
forwardPortsarray indevcontainer.jsonand ensure the application inside the container binds to0.0.0.0, notlocalhost - Slow file access: On macOS/Windows, enable Docker’s VirtioFS file sharing or use named volumes for large dependency directories like
node_modules
Summary
- Dev Containers define reproducible development environments as code using
devcontainer.jsonand Docker - Every team member gets an identical setup regardless of host OS — eliminating “works on my machine” issues
- Features allow adding tools modularly without custom Dockerfiles
- Docker Compose integration enables multi-service stacks with databases, caches, and queues
- GitHub Codespaces uses the same configuration for cloud-based development
- Onboarding time typically drops from days to minutes with proper Dev Container configuration
- Commit the
.devcontainerfolder to your repository for automatic team-wide adoption