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
Implementation
Architecture Patterns DevContainers Language Quickstarts IDE Integration AI/ML Workloads Advanced DevContainers
Operations
Performance Optimization High Availability & DR Monitoring Capacity Planning Troubleshooting Runbooks
Security
Security Deep Dive Secrets Management Vulnerability Management Network Security IAM Guide Compliance Guide
Planning
Pilot Program Design Stakeholder Communication Risk Management Migration Guide Cost Analysis Vendor Evaluation Training Resources Team Structure Industry Guides
Resources
Tools Comparison CDE vs Alternatives Case Studies Lessons Learned Glossary FAQ

Advanced DevContainers

Master advanced DevContainer configurations, multi-container setups, performance optimization, and enterprise patterns.

DevContainer Features

Modular, reusable configuration components

What are Features?

Features are self-contained units of installation code and configuration. They allow you to quickly add tools, runtimes, or libraries to any DevContainer without modifying the base image.

  • Composable - mix and match features
  • Versioned - pin to specific versions
  • Shareable - publish your own
  • Configurable - pass options
{
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "features": {
    "ghcr.io/devcontainers/features/node:1": {
      "version": "20"
    },
    "ghcr.io/devcontainers/features/python:1": {
      "version": "3.12"
    },
    "ghcr.io/devcontainers/features/docker-in-docker:2": {},
    "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {}
  }
}

Popular DevContainer Features

Node.js

ghcr.io/devcontainers/features/node

Python

ghcr.io/devcontainers/features/python

Go

ghcr.io/devcontainers/features/go

Rust

ghcr.io/devcontainers/features/rust

Docker-in-Docker

ghcr.io/devcontainers/features/docker-in-docker

Kubectl & Helm

ghcr.io/devcontainers/features/kubectl-helm-minikube

AWS CLI

ghcr.io/devcontainers/features/aws-cli

GitHub CLI

ghcr.io/devcontainers/features/github-cli

Multi-Container Setups

Docker Compose for complex development environments

Full-Stack Application Example

docker-compose.yml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: .devcontainer/Dockerfile
    volumes:
      - ..:/workspace:cached
      - node_modules:/workspace/node_modules
    command: sleep infinity
    networks:
      - dev-network
    depends_on:
      - db
      - redis
      - elasticsearch

  db:
    image: postgres:16
    restart: unless-stopped
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: myapp_dev
    networks:
      - dev-network

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    networks:
      - dev-network

  elasticsearch:
    image: elasticsearch:8.11.0
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
    volumes:
      - es-data:/usr/share/elasticsearch/data
    networks:
      - dev-network

volumes:
  postgres-data:
  es-data:
  node_modules:

networks:
  dev-network:
devcontainer.json
{
  "name": "Full Stack Dev",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",

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

  "forwardPorts": [3000, 5432, 6379, 9200],

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

  "postCreateCommand": "npm install",

  "remoteEnv": {
    "DATABASE_URL": "postgres://dev:dev@db:5432/myapp_dev",
    "REDIS_URL": "redis://redis:6379",
    "ELASTICSEARCH_URL": "http://elasticsearch:9200"
  }
}

Service Communication

DNS Resolution

Services are reachable by their name: db, redis

Port Mapping

Use forwardPorts to access from your local browser

Environment Variables

Use remoteEnv to inject connection strings

Performance Optimization

Maximize DevContainer build speed and runtime performance

Build Optimization

Layer Caching

# Bad: Invalidates cache frequently
COPY . .
RUN npm install

# Good: Leverage layer caching
COPY package*.json ./
RUN npm ci
COPY . .

Multi-Stage Builds

# Build stage with all dev tools
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Dev container inherits from builder
FROM builder AS devcontainer
RUN npm install -g typescript@latest

Prebuilds

Build images in CI and push to registry for instant startup:

{
  "image": "ghcr.io/myorg/devcontainer-node:latest",
  "cacheFrom": "ghcr.io/myorg/devcontainer-node"
}

Runtime Performance

Volume Mounts

# Use named volumes for node_modules
volumes:
  - ..:/workspace:cached
  - node_modules:/workspace/node_modules

# Use :cached for better macOS performance
# Use :delegated for write-heavy workloads

Resource Limits

{
  "hostRequirements": {
    "cpus": 4,
    "memory": "8gb",
    "storage": "32gb"
  },
  "runArgs": [
    "--cpus=4",
    "--memory=8g"
  ]
}

Parallelization

{
  "postCreateCommand": "npm ci & pip install -r requirements.txt & wait",
  "initializeCommand": ["./scripts/setup.sh"]
}
5x

Faster with prebuilds

:cached

Mount flag for macOS

Named Volumes

For node_modules

.dockerignore

Exclude unnecessary files

Enterprise Patterns

Scalable DevContainer strategies for large organizations

Base Image Strategy

Base Layer

Company-wide security tools, certificates, proxies

ghcr.io/myorg/base:latest

Language Layer

Node, Python, Java with standard versions

ghcr.io/myorg/node-20:latest

Project Layer

Project-specific tools and configs

devcontainer.json in repo

Private Registry Authentication

{
  "image": "ghcr.io/myorg/private-devcontainer:latest",

  // For GitHub Container Registry
  "containerEnv": {
    "GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
  },

  // For AWS ECR
  "initializeCommand": "aws ecr get-login-password | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com",

  // For Azure Container Registry
  "initializeCommand": "az acr login --name myregistry",

  // Using Docker credential helpers
  "runArgs": [
    "-v", "${localEnv:HOME}/.docker/config.json:/root/.docker/config.json:ro"
  ]
}

Template Repository Structure

devcontainer-templates/
+-- .github/
|   +-- workflows/
|       +-- build-push.yml    # CI to build/push images
+-- base/
|   +-- Dockerfile
|   +-- devcontainer.json
+-- node-20/
|   +-- Dockerfile
|   +-- devcontainer.json
+-- python-312/
|   +-- Dockerfile
|   +-- devcontainer.json
+-- java-21/
|   +-- Dockerfile
|   +-- devcontainer.json
+-- full-stack/
|   +-- Dockerfile
|   +-- docker-compose.yml
|   +-- devcontainer.json
+-- ml-gpu/
    +-- Dockerfile
    +-- devcontainer.json

Best Practices

  • Version images with semantic versioning
  • Automated builds on push to main
  • Security scanning in CI pipeline
  • Documentation for each template
  • Changelog for breaking changes
  • Test containers before release

Lifecycle Scripts

Execute scripts at different container lifecycle stages

Hook When Use Case
initializeCommand Before container created (on host) Docker login, pull base images
onCreateCommand After container created (first time only) Install dependencies, build projects
updateContentCommand After source updates (prebuilds) Incremental dependency updates
postCreateCommand After onCreate/updateContent Final setup, start services
postStartCommand Every container start Start dev servers, background jobs
postAttachCommand Every attach to container Shell customization, greetings

Example Configuration

{
  "initializeCommand": "docker login ghcr.io",
  "onCreateCommand": "npm ci && npm run build",
  "updateContentCommand": "npm ci",
  "postCreateCommand": ".devcontainer/setup.sh",
  "postStartCommand": "npm run dev &",
  "postAttachCommand": "echo 'Welcome! Run npm test to start.'"
}