Setting Up a Local Development Environment with Dev Containers and VS Code

Setting Up a Local Development Environment with Dev Containers and VS Code

Felix HassanBy Felix Hassan
How-ToTools & Workflowsdockervscodedevcontainersdevelopment-environmentproductivity
Difficulty: intermediate

Imagine a new engineer joins your team. They spend the first three days installing Python versions, configuring PostgreSQL, and fighting with environment variables because their macOS version doesn't match the production Linux environment. This "it works on my machine" friction is a massive drain on productivity.

This guide explains how to use Dev Containers to create reproducible, isolated development environments using VS Code and Docker. By shifting your dependencies from your local OS into a container, you ensure every developer on your team works in an identical environment. It’s about consistency, speed, and avoiding the headache of local dependency hell.

What are Dev Containers and how do they work?

Dev Containers are a specification that allows you to use a Docker container as a full-featured development environment. Instead of running your code directly on your laptop's operating system, you run it inside a container that has all the specific tools, compilers, and libraries you need. VS Code connects to this container, making it feel like you're coding locally, even though the actual execution happens inside the containerized environment.

The magic happens through a single folder in your project containing a .devcontainer directory. Inside, you'll find a devcontainer.json file. This file tells VS Code how to build the container, which extensions to install, and which ports to forward. It's a way to treat your development environment as code—just like your application code.

To get started, you'll need a few specific tools installed on your host machine:

  • Docker Desktop (or Rancher Desktop/OrbStack for Mac users)
  • Visual Studio Code
  • Dev Containers Extension (published by Microsoft)

You can find the official documentation for the specification on the official Dev Container specification site. It's a great place to see the technical details behind the scenes.

How do I set up a Dev Container in VS Code?

You can set up a Dev Container by using the "Add Dev Container Configuration Files" command within VS Code. This is the fastest way to get a project containerized without writing everything from scratch.

Here is the standard workflow to get your environment up and running:

  1. Open your project folder: Open the project you want to containerize in VS Code.
  2. Open the Command Palette: Press Cmd+Shift+P (macOS) or Ctrl+Shift+P (Windows/Linux).
  3. Select the Command: Type "Dev Containers: Add Dev Container Configuration Files..." and hit enter.
  4. Choose a Definition: You'll see a list of pre-configured templates. If you're building a Node.js app, select "Node.js & TypeScript." If it's Python, pick the version you need.
  5. Customize Features: The tool will ask if you want to add extra features like the AWS CLI or Git. Pick what you need and click OK.
  6. Reopen in Container: A notification will pop up in the bottom right. Click "Reopen in Container." VS Code will now build the image and connect to it.

Once the process finishes, look at the bottom-left corner of your VS Code window. You'll see a blue box indicating that you are now "Dev Container: [Name of your config]." You're officially inside the container.

One thing to watch out for is the build time. The first time you run this, Docker has to pull all the layers and install your requested features. It might take a few minutes. Subsequent starts will be much faster because of layer caching.

Comparing Local vs. Dev Container Environments

If you're wondering if this overhead is worth it, look at how it compares to a traditional local setup. Most developers find the trade-off favors the container approach once the project grows.

Feature Local Environment Setup Dev Container Setup
Dependency Isolation Hard to manage multiple versions Perfectly isolated per project
Onboarding Time Hours or days of setup Minutes (one-click setup)
Tooling Consistency "Works on my machine" issues Identical for every developer
Host Machine Cleanliness Clutters OS with various runtimes Keeps host OS clean and light

If you are already working with complex architectures, you might find that your containers need to interact with other services. If you've already mastered container-based workflows, you might want to look at optimizing your CI/CD pipelines with Docker layer caching to speed up your build times.

Why use a devcontainer.json file?

The devcontainer.json file serves as the blueprint for your entire development experience, including extensions, settings, and port forwarding. It ensures that every person on the team uses the same linting rules, the same debugger settings, and the same terminal tools.

A typical configuration file looks like this:

{
  "name": "Python 3.11 Project",
  "image": "mcr.microsoft.com/devcontainers/python:3.11",
  "features": {
    "ghcr.io/devcontainers/features/common-utils:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance"
      ],
      "settings": {
        "python.defaultInterpreterPath": "/usr/local/bin/python"
      }
    }
  },
  "forwardPorts": [8000],
  "postCreateCommand": "pip install -r requirements.txt"
}

Notice the postCreateCommand. This is a lifesaver. Instead of manually running pip install or npm install every time you pull a fresh repo, the container handles it automatically during the build. This is also where you'd run database migrations or seed scripts.

The forwardPorts property is another huge win. If your app runs on port 8000 inside the container, VS Code automatically maps that to your local machine. You can just open your browser to localhost:8000 and it works. No manual docker run -p commands required.

If you're dealing with high-performance data requirements, you'll likely need to ensure your database is also correctly configured. I've written about configuring PostgreSQL for high-concurrency, which is a great next step if your Dev Container involves a heavy database load.

One thing to keep in mind: don't put too much heavy lifting in the postCreateCommand. If it takes too long, it can make the initial build feel broken. Keep it to basic dependency installation. For larger tasks, consider using a Dockerfile directly instead of just the devcontainer.json features.

The beauty of this approach is that your .devcontainer folder lives in your Git repository. When a teammate pulls your branch, they aren't just getting your code—they're getting your entire workspace. They can start coding immediately without a single troubleshooting session.

It's a small change in workflow that yields massive returns in team velocity. You're moving away from "setting up a machine" and toward "launching a workspace."

Steps

  1. 1

    Install Docker Desktop and VS Code Extensions

  2. 2

    Create a .devcontainer folder in your project

  3. 3

    Configure the devcontainer.json file

  4. 4

    Reopen in Container to start coding