Everything you need to know about Dev Containers—what they are, why they matter, and exactly how to set up and use them in your projects, with code and real-world examples.
- What Are Dev Containers?
- Why Use Dev Containers?
- How Dev Containers Work
- How to Create a Dev Container (Step-by-Step)
- Full Example: Python + Node.js Dev Container
- Pro Tips & Best Practices
- Quick Example: Running Code in a Dev Container
- Further Resources
- Recap
Dev Containers are portable, pre-configured, isolated development environments—think of them as “dev workspaces in a box”—powered by Docker.
A dev container is defined by files in your repo that describe the complete setup: OS, tools, extensions, dependencies, and configuration.
- Consistency: Same environment for everyone—no more “works on my machine”!
- Isolation: Keeps your local machine clean. No dependency conflicts.
- Portability: Clone a repo, open in a dev container—done!
- Speedy Onboarding: New team members can start contributing immediately.
- Automation: Automate everything from extension installs to dependency setup.
Dev Containers use Docker (or a compatible runtime).
You define a .devcontainer folder in your project, which typically includes:
devcontainer.json: Main config file for your environment.Dockerfile: (Optional) Customizes your base image.- Setup scripts or additional configs.
VS Code and GitHub Codespaces both support Dev Containers natively.
- Docker (Desktop or Engine)
- VS Code + Dev Containers extension
Step 1: Add a .devcontainer Folder
mkdir .devcontainer
cd .devcontainerStep 2: Create devcontainer.json
Basic example for a Node.js project:
{
"name": "Node.js & TypeScript Dev",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"features": {
"ghcr.io/devcontainers-contrib/features/zsh:1": {}
},
"postCreateCommand": "npm install",
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
},
"mounts": [
"source=${localEnv:HOME}/.ssh,target=/root/.ssh,type=bind,consistency=cached"
]
}
image: Docker image to use.
postCreateCommand: Commands to run after building the container.
customizations.vscode.extensions: VS Code extensions installed inside the container.
mounts: (Optional) Mount local files like SSH keys.
For more control (like installing OS packages, Python, etc.), add a Dockerfile:
.devcontainer/Dockerfile:
FROM mcr.microsoft.com/devcontainers/javascript-node:20
# Install additional packages
RUN apt-get update && \
apt-get install -y graphviz && \
rm -rf /var/lib/apt/lists/*
# Install global npm packages
RUN npm install -g typescript
Update your devcontainer.json:
"build": {
"dockerfile": "Dockerfile"
}
Open VS Code in your project root.
Run F1 → Dev Containers: Reopen in Container.
VS Code will build the container, set up everything, and reload your project inside the container.
Suppose you need both Python and Node.js:
.devcontainer/devcontainer.json:
{
"name": "Fullstack Dev (Node + Python)",
"build": {
"dockerfile": "Dockerfile"
},
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"postCreateCommand": "npm install && pip install -r requirements.txt",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"dbaeumer.vscode-eslint"
]
}
},
"forwardPorts": [3000, 8000],
"remoteUser": "vscode"
}
.devcontainer/Dockerfile:
FROM mcr.microsoft.com/devcontainers/javascript-node:20
RUN apt-get update && \
apt-get install -y python3 python3-pip && \
rm -rf /var/lib/apt/lists/*
RUN ln -s /usr/bin/python3 /usr/bin/python \
&& ln -s /usr/bin/pip3 /usr/bin/pip
# (Optional) Add a non-root user
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=1000
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& apt-get update && apt-get install -y sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
USER $USERNAME
Version the .devcontainer folder!
Use Dev Container Features to quickly add tools.
Use postCreateCommand for project setup steps.
Forward commonly used ports (like web servers, DBs).
Auto-install extensions for a seamless VS Code experience.
Never commit secrets—use environment variables.
Use remoteUser for security and consistency.
Suppose you have this file:
index.js
console.log("Hello from inside the Dev Container!");
Open the integrated terminal inside the container and run:
node index.js
Output:
Hello from inside the Dev Container!
Dev Containers = Portable, reproducible development environments powered by Docker.
Setup: Add a .devcontainer folder with devcontainer.json (+ optional Dockerfile).
Open: Use VS Code → "Reopen in Container".
Result: Everyone on your team codes in the exact same environment, anywhere.