Skip to content

Latest commit

 

History

History
243 lines (170 loc) · 6.43 KB

File metadata and controls

243 lines (170 loc) · 6.43 KB

🚀 Ultimate Guide to Dev Containers

dev containers

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.


📚 Table of Contents


🧩 What Are Dev Containers?

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.


🎯 Why Use Dev Containers?

  • 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.

⚙️ How Dev Containers Work

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.


🏗️ How to Create a Dev Container (Step-by-Step)

1️⃣ Prerequisites


2️⃣ Setting Up the Dev Container

Step 1: Add a .devcontainer Folder

mkdir .devcontainer
cd .devcontainer

Step 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.

3️⃣ Adding a Custom Dockerfile (Optional)

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"
}

4️⃣ Opening Your Project in a Dev Container

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.

🌐 Full Example: Python + Node.js Dev 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

💡 Pro Tips & Best Practices

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.

🏃 Quick Example: Running Code in a Dev Container

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!

✅ Recap

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.