Skip to main content
InfraGap.com Logo
Home
Getting Started
Core Concept What is a CDE? How It Works Benefits CDE Assessment Getting Started Guide CDEs for Startups
AI & Automation
AI Coding Assistants Agentic AI AI-Native IDEs Agentic Engineering AI Agent Orchestration AI Governance AI-Assisted Architecture Shift-Left AI LLMOps Autonomous Development AI/ML Workloads GPU Computing
Implementation
Architecture Patterns DevContainers Advanced DevContainers Language Quickstarts IDE Integration CI/CD Integration Platform Engineering Developer Portals Container Registry Multi-CDE Strategies Remote Dev Protocols Nix Environments
Operations
Performance Optimization High Availability & DR Disaster Recovery Monitoring Capacity Planning Multi-Cluster Development Troubleshooting Runbooks Ephemeral Environments
Security
Security Deep Dive Zero Trust Architecture Secrets Management Vulnerability Management Network Security IAM Guide Supply Chain Security Air-Gapped Environments AI Agent Security MicroVM Isolation Compliance Guide Governance
Planning
Pilot Program Design Stakeholder Communication Risk Management Migration Guide Cost Analysis FinOps GreenOps Vendor Evaluation Training Resources Developer Onboarding Team Structure DevEx Metrics Industry Guides
Resources
Tools Comparison CDE vs Alternatives Case Studies Lessons Learned Glossary FAQ

DevContainers Deep Dive

Complete guide to Development Containers - the specification that powers reproducible, containerized development environments

What are DevContainers?

Development Containers (DevContainers) are a standardized way to define complete development environments as code using Docker containers. The specification, maintained by the Development Containers Spec, allows developers to define their entire development environment - tools, runtimes, extensions, settings - in a single JSON file. The specification has seen broad adoption beyond its VS Code origins and is now supported by VS Code, JetBrains, Zed, GitHub Codespaces, and multiple CDE platforms.

Declarative

Define everything in devcontainer.json

Reproducible

Same environment for every developer

Docker-Based

Built on Docker container technology

How DevContainers Relate to Docker

Standard Docker

  • Runs production workloads
  • Minimal images for efficiency
  • Usually stateless
  • Optimized for runtime

DevContainers

  • Runs development environments
  • Full tooling (git, debuggers, linters)
  • Persistent workspaces
  • Optimized for development

DevContainer Anatomy

The devcontainer.json File

{
  "name": "My Dev Container",
  "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye",

  // Or build from Dockerfile
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },

  // Features - modular add-ons
  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },

  // Lifecycle scripts
  "postCreateCommand": "npm install",
  "postStartCommand": "npm run dev",

  // Editor customizations (VS Code, JetBrains, Zed, and more)
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode"
      ],
      "settings": {
        "editor.formatOnSave": true
      }
    }
  },

  // Port forwarding
  "forwardPorts": [3000, 5432],

  // Environment variables
  "containerEnv": {
    "NODE_ENV": "development"
  },

  // Mounts and volumes
  "mounts": [
    "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
  ]
}

Dockerfile Integration

You can use pre-built images or define custom Dockerfiles for complete control:

# .devcontainer/Dockerfile
FROM ubuntu:22.04

# Install system dependencies
RUN apt-get update && apt-get install -y \
    curl \
    git \
    build-essential \
    python3 \
    python3-pip

# Install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
RUN apt-get install -y nodejs

# Create non-root user
ARG USERNAME=developer
RUN useradd -m -s /bin/bash $USERNAME

USER $USERNAME
WORKDIR /home/$USERNAME

Docker Compose Support

For multi-container setups (app + database + cache):

devcontainer.json
{
  "name": "Full Stack",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace"
}
docker-compose.yml
services:
  app:
    build: .
    volumes:
      - .:/workspace

  postgres:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: dev

  redis:
    image: redis:7-alpine

Features System

Features are self-contained, reusable units of installation code. Think of them as modular add-ons:

Git
devcontainers/features/git
Node.js
devcontainers/features/node
Python
devcontainers/features/python
Docker-in-Docker
devcontainers/features/docker-in-docker
kubectl
devcontainers/features/kubectl-helm
AWS CLI
devcontainers/features/aws-cli

Common Language Configurations

Click on a language to view its devcontainer.json configuration:

Python / Django
{
  "name": "Python Django",
  "image": "mcr.microsoft.com/devcontainers/python:3.11-bullseye",

  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },

  "postCreateCommand": "pip install -r requirements.txt && python manage.py migrate",

  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "ms-python.black-formatter",
        "batisteo.vscode-django"
      ]
    }
  },

  "forwardPorts": [8000],

  "containerEnv": {
    "DJANGO_SETTINGS_MODULE": "myproject.settings.dev"
  }
}
Node.js / React
{
  "name": "Node.js React",
  "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye",

  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/github-cli:1": {}
  },

  "postCreateCommand": "npm install",
  "postStartCommand": "npm run dev",

  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "bradlc.vscode-tailwindcss"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode"
      }
    }
  },

  "forwardPorts": [3000, 5173],

  "containerEnv": {
    "NODE_ENV": "development"
  }
}
Java / Spring Boot
{
  "name": "Java Spring Boot",
  "image": "mcr.microsoft.com/devcontainers/java:1-21-bullseye",

  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/maven:1": {
      "version": "3.9"
    },
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },

  "postCreateCommand": "./mvnw clean install -DskipTests",

  "customizations": {
    "vscode": {
      "extensions": [
        "vscjava.vscode-java-pack",
        "vmware.vscode-spring-boot",
        "vscjava.vscode-spring-initializr"
      ]
    }
  },

  "forwardPorts": [8080],

  "containerEnv": {
    "SPRING_PROFILES_ACTIVE": "dev"
  }
}
Go
{
  "name": "Go",
  "image": "mcr.microsoft.com/devcontainers/go:1.21-bullseye",

  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },

  "postCreateCommand": "go mod download",

  "customizations": {
    "vscode": {
      "extensions": [
        "golang.go",
        "golang.go-nightly"
      ],
      "settings": {
        "go.toolsManagement.autoUpdate": true,
        "go.useLanguageServer": true
      }
    }
  },

  "forwardPorts": [8080],

  "containerEnv": {
    "CGO_ENABLED": "0"
  }
}
Rust
{
  "name": "Rust",
  "image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",

  "features": {
    "ghcr.io/devcontainers/features/git:1": {}
  },

  "postCreateCommand": "cargo build",

  "customizations": {
    "vscode": {
      "extensions": [
        "rust-lang.rust-analyzer",
        "vadimcn.vscode-lldb",
        "serayuzgur.crates"
      ],
      "settings": {
        "rust-analyzer.checkOnSave.command": "clippy"
      }
    }
  },

  "forwardPorts": [8000]
}
.NET / C#
{
  "name": ".NET",
  "image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm",

  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/azure-cli:1": {}
  },

  "postCreateCommand": "dotnet restore && dotnet build",

  "customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csharp",
        "ms-dotnettools.vscode-dotnet-runtime",
        "kreativ-software.csharpextensions"
      ]
    }
  },

  "forwardPorts": [5000, 5001],

  "containerEnv": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  }
}

Dev Container Features Ecosystem

Dev Container Features are shareable, versioned packages that add tools, runtimes, or configuration to any devcontainer.json with a single line. Published to OCI-compliant registries like ghcr.io, the Features specification is now mature and widely adopted across the ecosystem.

Popular Features

docker-in-docker

Build and run containers inside your dev container

node

Node.js runtime with nvm version management

python

Python with pip, venv, and Conda support

aws-cli

AWS CLI v2 with session manager plugin

azure-cli

Azure CLI with bicep and extensions

Custom Feature Authoring

Organizations can author and publish custom Features for their own internal tooling, proprietary SDKs, or standardized security configurations - distributed through private OCI registries.

// Use community and custom Features together
{
  "features": {
    "ghcr.io/devcontainers/features/node:1": {
      "version": "20"
    },
    "ghcr.io/devcontainers/features/aws-cli:1": {},
    "ghcr.io/myorg/features/internal-sdk:2": {
      "apiEndpoint": "https://api.internal.dev"
    }
  }
}

Features use OCI artifacts for distribution, making them cacheable, versionable, and compatible with any container registry that supports OCI specs.

GPU-Enabled Dev Containers for AI/ML

Dev containers can expose host GPU hardware to containerized AI/ML workloads through the NVIDIA Container Toolkit. This enables teams to develop, train, and test machine learning models inside reproducible container environments with full CUDA acceleration.

Configuration

{
  "name": "ML Workspace",
  "image": "mcr.microsoft.com/devcontainers/python:3.11",

  "features": {
    "ghcr.io/devcontainers/features/nvidia-cuda:1": {
      "cudaVersion": "12.4"
    }
  },

  "hostRequirements": {
    "gpu": "optional"
  },

  "runArgs": [
    "--gpus=all",
    "--shm-size=8g"
  ],

  "postCreateCommand": "pip install torch torchvision"
}

Key Concepts

NVIDIA Container Toolkit

Installed on the host, it exposes GPU drivers and CUDA libraries into containers. Required for any GPU passthrough.

runArgs and --gpus flag

The "runArgs": ["--gpus=all"] flag in devcontainer.json passes GPU access from the Docker daemon to the container at startup.

GPU Workspace Classes

CDE platforms like Coder and GitHub Codespaces offer GPU workspace classes (e.g., T4, A100) that pair with GPU-enabled devcontainer configs for on-demand ML environments.

Multi-Container Workspace Patterns

Real-world applications rarely run in isolation. The dockerComposeFile property in devcontainer.json lets you define multi-service workspaces where your application, database, cache, and other dependencies all run together with automatic service-to-service networking.

devcontainer.json

{
  "name": "Full-Stack App",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",

  "forwardPorts": [3000, 5432, 6379],
  "portsAttributes": {
    "3000": { "label": "Web App" },
    "5432": { "label": "PostgreSQL" },
    "6379": { "label": "Redis" }
  },

  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "cweijan.vscode-postgresql-client2"
      ]
    }
  }
}

docker-compose.yml

services:
  app:
    build:
      context: ..
      dockerfile: .devcontainer/Dockerfile
    volumes:
      - ..:/workspace:cached
    command: sleep infinity

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: appdb
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  pgdata:

Service Networking

Services automatically resolve each other by name. Your app connects to postgres:5432 and redis:6379 with zero configuration.

Persistent Data

Named volumes like pgdata persist database state across container rebuilds, so your test data survives environment updates.

Isolated Stacks

Each developer gets a fully isolated stack. No more shared staging databases or port conflicts between teammates.

Advanced Features

Lifecycle Scripts

{
  "onCreateCommand": "git config --global ...",
  "updateContentCommand": "npm update",
  "postCreateCommand": "npm install",
  "postStartCommand": "npm run dev",
  "postAttachCommand": "echo 'Welcome!'"
}

Run commands at different stages of container lifecycle

VS Code Extensions

"customizations": {
  "vscode": {
    "extensions": [
      "dbaeumer.vscode-eslint",
      "esbenp.prettier-vscode"
    ],
    "settings": {
      "editor.formatOnSave": true
    }
  }
}

Auto-install extensions and configure settings

Port Forwarding

"forwardPorts": [3000, 5432],
"portsAttributes": {
  "3000": {
    "label": "Web App",
    "onAutoForward": "notify"
  },
  "5432": {
    "label": "PostgreSQL"
  }
}

Automatically forward ports with custom labels

Environment Variables

"containerEnv": {
  "NODE_ENV": "development",
  "DATABASE_URL": "postgres://..."
},
"remoteEnv": {
  "PATH": "${containerEnv:PATH}:/custom"
}

Set environment variables for container and remote sessions

Mounts & Volumes

"mounts": [
  "source=/var/run/docker.sock,
   target=/var/run/docker.sock,
   type=bind",
  "source=node_modules,
   target=${containerWorkspaceFolder}/node_modules,
   type=volume"
]

Bind mounts for Docker socket, named volumes for dependencies

GPU Support

"hostRequirements": {
  "gpu": "optional"
},
"runArgs": [
  "--gpus=all"
]

Enable GPU access for ML/AI workloads with CUDA support

Best Practices

Image Size Optimization

Use multi-stage builds and minimal base images. Alpine variants are smaller but may lack some tools.

# Use slim variants for smaller images
FROM node:20-slim  # ~250MB instead of node:20 (~1GB)

Layer Caching

Order Dockerfile commands from least to most frequently changing to maximize cache hits.

# Copy dependency files first (changes rarely)
COPY package*.json ./
RUN npm install
# Then copy source code (changes frequently)
COPY . .

Security Hardening

Always run as non-root user. Pin versions to avoid supply chain attacks.

# Create and use non-root user
RUN useradd -m -s /bin/bash developer
USER developer

# Pin feature versions
"features": {
  "ghcr.io/devcontainers/features/node:1": { "version": "20.11.0" }
}

Version Pinning

Pin all versions - base images, features, extensions - to ensure reproducibility.

# Pin base image with digest
FROM node:20.11.0-bullseye@sha256:abc123...

# Pin feature versions
"features": {
  "ghcr.io/devcontainers/features/git:1": { "version": "1.0.5" }
}

Documentation

Include README.md in .devcontainer/ explaining what is pre-configured and any special setup.

.devcontainer/
|-- devcontainer.json
|-- Dockerfile
|-- docker-compose.yml
+-- README.md  # Document your setup!

DevContainers Across Platforms

PlatformSupportLocationNotes
VS Code (Local)
FullLocal DockerNative support via Remote Containers extension
GitHub Codespaces
FullCloud (GitHub)Native support, reads from .devcontainer/
Ona (formerly Gitpod)
PartialCloud (Ona)Prefers .gitpod.yml but supports devcontainer.json
Coder
FullSelf-hostedVia Terraform + Envbuilder agent
DevPod
FullMulti-cloudOpen-source client for any cloud
JetBrains Gateway
PartialRemote SSHCan connect to existing containers
Zed
FullLocal DockerNative support added in v0.218 (January 2026)

DevContainers for AI Agent Workspaces

DevContainers have become the standard configuration format for AI agent development environments, ensuring agents have reproducible, isolated workspaces. As AI coding assistants and autonomous agents increasingly need to build, test, and run code, DevContainers provide a safe, consistent sandbox with all required dependencies pre-configured.

Isolated Sandboxes

AI agents operate in containerized environments with defined boundaries, preventing unintended changes to host systems.

Reproducible Runs

Every agent session starts from the same known state, eliminating environment drift between automated runs.

Pre-Configured Tooling

Agents get language runtimes, build tools, and testing frameworks automatically through devcontainer.json and Features.

Publishing & Sharing DevContainers

Container Registries

Publish images to Docker Hub, GitHub Container Registry (GHCR), or private registries.

Docker Hub
GitHub Container Registry
Private registries

Template Repositories

Create GitHub template repos with .devcontainer/ that teams can clone and customize.

my-team-template/
|-- .devcontainer/
|   |-- devcontainer.json
|   +-- Dockerfile
+-- README.md

Organization Standards

Platform teams can publish standard images and feature sets for the entire organization.

  • Pre-approved tools
  • Security scanning
  • Compliance standards

Publishing to GitHub Container Registry

# Build and tag your image
docker build -t ghcr.io/myorg/python-dev:latest .devcontainer

# Login to GitHub Container Registry
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin

# Push the image
docker push ghcr.io/myorg/python-dev:latest

# Reference in devcontainer.json
{
  "image": "ghcr.io/myorg/python-dev:latest"
}