Dev Containers: The Ultimate Solution for Consistent Team Development Environments
This article explains how Dev Containers use Docker‑based configurations to give every team member an identical development environment—from OS dependencies to VS Code extensions—detailing core concepts, setup steps, sample devcontainer.json files for Python, Node, Go, and multi‑container stacks, plus best‑practice guidelines and CI/CD integration.
What is a Dev Container?
Core idea
传统开发环境问题:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 开发者 A │ │ 开发者 B │ │ 开发者 C │
│ Python 3.11│ │ Python 3.12│ │ Python 3.10│
│ Node 18 │ │ Node 20 │ │ Node 19 │
│ MySQL 8.0 │ │ PostgreSQL │ │ MariaDB │
│ "能跑!" │ │ 报错了 ❌ │ │ 缺包 ❌ │
└─────────────┘ └─────────────┘ └─────────────┘
Dev Container 方案:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 开发者 A │ │ 开发者 B │ │ 开发者 C │
│ ════════════ │ │ ════════════ │ │ ════════════ │
│ 同一个容器 ←─→│ 同一个容器 ←─→│ 同一个容器 │
│ 完全一致 ✅ │ │ 完全一致 ✅ │ │ 完全一致 ✅ │
└─────────────┘ └─────────────┘ └─────────────┘
↑ ↑ ↑
devcontainer.json(定义在代码仓库中,版本管理)How it works
你的项目仓库:
my-project/
├── .devcontainer/
│ └── devcontainer.json ← 定义开发环境的"配方"
├── src/
└── README.md
团队成员操作:
git clone → VS Code 打开 →
F1 → "Dev Containers: Reopen in Container" →
自动构建 → 进入统一环境 ✅Creating a devcontainer.json
Basic template
{
"name": "My Project Dev Environment",
"image": "mcr.microsoft.com/devcontainers/python:3.12",
// "build": { "dockerfile": "Dockerfile" },
"features": {
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/common-utils:2": {}
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter",
"eamodio.gitlens",
"PKief.material-icon-theme"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"editor.formatOnSave": true,
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
}
}
}
},
"forwardPorts": [8000, 3000, 5000, 8080],
"postCreateCommand": "pip install -r requirements.txt && echo '✅ Dev environment ready!'",
"remoteUser": "vscode"
}Common scenario configurations
Scenario 1: Python full‑stack project
{
"name": "Python Full-Stack",
"image": "mcr.microsoft.com/devcontainers/python:3.12",
"features": {
"ghcr.io/devcontainers/features/python:1": {"version": "3.12"}
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.debugpy",
"charliermarsh.ruff",
"mechatlinder.vscode-github-actions-io",
"GitHub.copilot"
]
}
},
"forwardPorts": [8000, 8888],
"postCreateCommand": "pip install fastapi uvicorn sqlalchemy pytest httpie && pip install -r requirements.txt 2>/dev/null || true"
}Scenario 2: Node.js frontend project
{
"name": "Node.js Frontend",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"features": {
"ghcr.io/devcontainers/features/node:1": {"version": "20"}
},
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"bradlc.vscode-tailwindcss",
"formulahendry.auto-rename-tag",
"GitHub.copilot",
"usernamehw.errorlens"
],
"settings": {
"node.autodetect": "on"
}
}
},
"forwardPorts": [3000, 5173],
"postCreateCommand": "npm install"
}Scenario 3: Go backend service
{
"name": "Go Backend",
"image": "mcr.microsoft.com/devcontainers/go:1.22",
"features": {
"ghcr.io/devcontainers/features/go:1": {}
},
"customizations": {
"vscode": {
"extensions": [
"golang.Go",
"gopls",
"prempilot.devtools-yap"
]
}
},
"forwardPorts": [8080, 3000],
"remoteEnv": {
"GOPATH": "/workspace/go",
"PATH": "/usr/local/go/bin:/workspace/go/bin:${containerEnv:PATH}"
},
"postCreateCommand": "go mod download && go install github.com/air-verse/air@latest"
}Scenario 4: Multi‑container stack (frontend + backend + database)
{
"name": "Full Stack App",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"dbaeumer.vscode-eslint",
"eamodio.gitlens"
]
}
},
"forwardPorts": [8000, 3000, 5432, 6379]
}Combine with docker-compose.yml:
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ..:/workspace:cached
command: sleep infinity
depends_on:
- db
- redis
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev
POSTGRES_DB: appdb
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
pgdata:Usage in WSL
GUI steps
# Prerequisites:
# 1. Docker Desktop installed (WSL backend)
# 2. VS Code Remote - Containers extension installed
# Steps:
# 1. Open project folder in VS Code
# 2. Press F1 or Ctrl+Shift+P
# 3. Run "Dev Containers: Reopen in Container"
# 4. Choose configuration from devcontainer.json
# 5. Wait for build (first time downloads image)Common Dev Container commands
Reopen in Container # reopen inside container
Rebuild Container # rebuild after devcontainer.json changes
Rebuild Without Cache # full rebuild without cache
Attach to Running Container # attach to an already running container
Show Container Logs # view container logs
Clone Repository in Container # clone a repo directly inside the containerFeature ecosystem
node:1 – Node.js – npm, pnpm, nvm/fnm
python:1 – Python – pip, venv, common packages
go:1 – Go – go, gopls, delve
rust:1 – Rust – rustc, cargo, rust-analyzer
java:1 – Java – JDK, Maven, Gradle
docker-in-docker:2 – Docker – Docker CLI (nested)
common-utils:2 – General utilities – git, curl, jq, htop
github-cli:1 – GitHub CLI – gh command
aws-cli:1 – AWS CLI – aws command
terraform:1 – Terraform – IaC tool
Team collaboration practices
Version‑control devcontainer.json
my-repo/
├── .devcontainer/
│ ├── devcontainer.json ← required for sharing
│ └── Dockerfile (optional) custom build
├── src/
├── tests/
└── .gitignore # exclude .devcontainer/cache/Provide multiple configuration options
// .devcontainer/devcontainer.json # default (lightweight)
// .devcontainer/devcontainer.full.json # full (includes DB, etc.)
// .devcontainer/devcontainer.ci.json # CI/CD configurationCI/CD integration example
# .github/workflows/ci.yml (example)
jobs:
test:
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/devcontainers/python:3.12
steps:
- uses: actions/checkout@v4
- run: pip install -r requirements.txt
- run: pytestSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ubuntu
Focused on Ubuntu/Linux tech sharing, offering the latest news, practical tools, beginner tutorials, and problem solutions. Connecting open-source enthusiasts to build a Linux learning community. Join our QQ group or channel for discussion!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
