We’ve all been there: you clone a repository, follow the README’s installation steps for an hour, and still end up with a version mismatch error because your local Python or Node version is slightly off. It’s the classic ‘it works on my machine’ syndrome. For years, I struggled with this until I learned how to use dev containers in VS Code.
Dev Containers allow you to use a Docker container as your full-featured development environment. Instead of installing compilers, runtimes, and tools directly on your OS, you define them in a configuration file. When you open the project, VS Code ‘enters’ that container, giving you a consistent environment regardless of whether you’re on macOS, Windows, or Linux.
Prerequisites
Before we dive into the setup, you’ll need a few things installed on your machine. I’ve found that missing any of these is the most common reason why the initial setup fails:
- Docker Desktop (or OrbStack/Colima for macOS users who want something lighter).
- Visual Studio Code (the latest stable version).
- Dev Containers Extension: Search for
ms-vscode-remote.remote-containersin the VS Code marketplace.
Steps to Set Up Your First Dev Container
Step 1: Initialize the Configuration
You don’t need to write a Dockerfile from scratch. VS Code provides a wizard to get you started. Press F1 (or Ctrl+Shift+P) and type “Dev Containers: Add Dev Container Configuration Files…”.
From here, you can choose a predefined definition. For example, if you are setting up a C++ environment in VS Code, you can search for the ‘C++’ definition. This will create a .devcontainer folder in your root directory.
Step 2: Understanding devcontainer.json
The heart of this setup is the devcontainer.json file. This file tells VS Code how to build the container and which extensions to install automatically inside it. Here is a typical configuration I use for a Node.js project:
{
"name": "Node.js Project",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"firsttris.vscode-jest-runner"
]
}
},
"forwardPorts": [3000],
"postCreateCommand": "npm install"
}
In this snippet, I’m using a Microsoft-maintained image, pre-installing my favorite linting tools, and ensuring npm install runs the moment the container is created. This means a new developer can join the project and be ready to code in seconds.
Step 3: Reopening in Container
Once the files are created, VS Code will usually prompt you with a notification: “Folder contains a Dev Container configuration file. Reopen folder to develop in a container.”
Click Reopen in Container. VS Code will now build the Docker image and start the container. As shown in the image below, you’ll see a green status bar in the bottom-left corner indicating that you are now connected to the container.
Pro Tips for Power Users
After using Dev Containers for several projects, I’ve picked up a few tricks to make them even more efficient:
- Use Docker Compose: If your app requires a database (like PostgreSQL or Redis), don’t install it in the app container. Use a
docker-compose.ymlfile and reference it in yourdevcontainer.json. - Mount a SSH Key: To avoid logging into GitHub inside the container, VS Code automatically forwards your local SSH agent. Just make sure your agent is running locally.
- Optimize for Large Projects: If your container feels sluggish, check your volume mounts. For those working on massive monorepos, I recommend learning how to optimize VS Code for large projects to reduce indexing overhead.
- Custom Dockerfiles: Instead of a generic image, use
"build": { "dockerfile": "Dockerfile" }to install specific OS-level dependencies (likelibpngorcmake) that your project requires.
Troubleshooting Common Issues
Even with a streamlined process, you might hit some bumps. Here are the most common ones I’ve encountered:
| Issue | Solution |
|---|---|
| Container fails to start / Docker not found | Ensure Docker Desktop is running and the “Expose daemon on tcp://localhost:2375” setting is checked if using older versions. |
| Permissions errors on Linux | Add "remoteUser": "vscode" to your json file to avoid running everything as root. |
| Slow build times | Use a more specific base image or leverage Docker layer caching by placing npm install commands after your dependency files are copied. |
What’s Next?
Now that you know how to use dev containers in VS Code, you can start standardizing your team’s workflow. I suggest moving all your project-specific extensions into the devcontainer.json so that no one has to manually install a list of plugins again. If you’re looking to further automate your productivity, explore my other guides on CI/CD integration.