DevContainers + DevPod: Reproducible Dev Environments Anywhere

11 min read by M1NDB3ND3R
devcontainersdevpodcontainersdevopsdevelopment-environmenttutorial

DevContainers + DevPod: Reproducible Dev Environments Anywhere

Ever joined a new project and spent days just getting your environment set up? You clone the repo, run npm install, and then hit a wall—wrong Node version, missing dependencies, conflicting packages. “Works on my machine” becomes the most dreaded phrase in software development. What if I told you there’s a better way? Enter DevContainers and DevPod – the dynamic duo that makes environment setup a one-command affair, whether you’re on macOS, Windows, or Linux.


The Problem: “Works On My Machine”

We’ve all been there. Your teammate spends hours debugging an issue only to realize their Python version was 3.11 instead of 3.9. Or the database configuration that works perfectly on their Ubuntu machine completely breaks on your macOS setup. These environment inconsistencies waste countless hours and drive developers crazy.

Traditional approaches have limitations:

  • Manual setup guides – Always outdated, hard to maintain, and prone to human error
  • Docker containers – Great for production, but setting up local dev with hot-reload is painful
  • VM-based solutions – Heavy, slow, and resource-intensive
  • Cloud development environments – Lock you into specific providers and can get expensive

The industry needed a standard way to define development environments that works everywhere. That’s exactly what DevContainers and DevPod provide.


What Are DevContainers?

DevContainers is an open specification for defining reproducible development environments through a devcontainer.json file. Think of it as a blueprint that tells exactly how your development environment should be set up – what tools, extensions, runtimes, and configurations your project needs.

The magic is in the simplicity:

{
  "name": "Node.js Development Environment",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20",
  "features": {
    "ghcr.io/devcontainers/features/github-cli:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "esbenp.prettier-vscode",
        "dbaeumer.vscode-eslint"
      ]
    }
  },
  "postCreateCommand": "npm install",
  "remoteUser": "node"
}

How DevContainers Work

The DevContainers specification works by defining a containerized environment that includes everything your project needs:

  1. Container Image – The base operating system and runtime (Node.js, Python, Go, etc.)
  2. Features – Reusable installation steps for common tools that can be shared across projects
  3. Templates – Complete development environment configurations that can be applied to new projects
  4. Lifecycle Scripts – Commands that run at specific points during container creation

Lifecycle Script Reference:

ScriptWhen It RunsUse Case
initializeCommandOn host machine during initializationSetup host-side tools
onCreateCommandFirst command inside containerInstall base dependencies
updateContentCommandWhen new content is availableSync or update files
postCreateCommandAfter workspace is assignedFinal setup, npm install
postStartCommandEach time container startsStart services, daemons
postAttachCommandEach time tool attachesIDE-specific configurations

Example with lifecycle scripts:

{
  "name": "Full-Stack Development",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20",
  "onCreateCommand": "apt-get update && apt-get install -y git curl",
  "postCreateCommand": "npm install && npm run build",
  "postStartCommand": "service docker start",
  "remoteUser": "node"
}

This approach ensures every developer on your team has an identical environment, eliminating the “works on my machine” problem.

Where DevContainers Shine

  • VS Code Integration – The official extension provides seamless local development
  • GitHub Codespaces – Cloud-hosted dev environments using the same specification
  • Team Consistency – Everyone gets the same tools, versions, and configurations
  • Onboarding New Developers – Clone, open, and start coding in minutes

But here’s the catch: VS Code’s DevContainers extension is great, but it ties you to VS Code and local Docker. What if you want to use JetBrains IDEs? Or run your environment in the cloud? Or work from a remote machine? That’s where DevPod comes in.


Enter DevPod: DevContainers, But Better

DevPod is an open-source tool that creates reproducible development environments from devcontainer.json files – but here’s the game-changer: it’s completely client-only, IDE-agnostic, and runs anywhere.

Their tagline says it all: “Codespaces but open-source, client-only and unopinionated.”

Unlike cloud-hosted solutions that lock you into their infrastructure, DevPod treats devcontainers as remote machines you SSH into. You get to choose where your development environment runs.

DevPod vs VS Code DevContainers Extension

FeatureVS Code DevContainersDevPod
IDE SupportVS Code onlyVS Code, JetBrains, any IDE via SSH
LocationLocal Docker onlyLocal, cloud VMs, Kubernetes, any remote machine
Provider Lock-inNoneNone (open-source, client-only)
Setup ComplexitySimple (local Docker)Requires provider configuration
CostFree (local resources)Pay for cloud resources you choose
SSH AccessLimitedFirst-class citizen
Multi-ProviderNoYes (AWS, GCP, Azure, local Docker, Kubernetes)

Key DevPod Features

  • Any Infrastructure, Any IDE – Use Docker locally, spin up AWS EC2 instances, or deploy to Kubernetes – all with the same workflow
  • Client-Only Architecture – No server to install and manage; DevPod runs entirely on your machine
  • Open-Source and Extensible – Missing a provider? Build your own; the code is public
  • Cost-Effective – Use bare VMs instead of managed services, saving 5-10x on cloud costs
  • Persistent Workspaces – Stop and restart without losing state; install additional tools without reconfiguring
  • Prebuild Support – Pre-configure environments for faster startup times

Real-World Use Cases

Remote Development for Distributed Teams

Your team is spread across time zones. With DevPod, everyone can spin up identical environments on their preferred cloud provider. The designer uses a powerful macOS machine for Figma integration, while the backend developer prefers a cost-effective Linux VM. Same devcontainer.json, different backends, consistent experience.

Onboarding New Team Members

New hire starting tomorrow? Have their dev environment ready by simply running devpod up. No more “let me send you the setup guide” emails. They clone the repo, run one command, and they’re productive from day one.

Testing Across Environments

Need to verify your app works on Python 3.9 and 3.12? DevPod makes it trivial to spin up two environments with different Python versions side by side.

Legacy Project Revival

That old project nobody has touched in years? Its devcontainer.json documents exactly what it needs. DevPod brings it back to life without hunting down dependencies.


Getting Started: Hands-On Tutorial

Let’s walk through setting up a Node.js project with DevPod. I’ll show you both the quick-start approach and a custom configuration.

Prerequisites

  • DevPod installed (we’ll cover this)
  • A cloud provider account (AWS, GCP, Azure) or Docker locally
  • Your favorite IDE

Step 1: Install DevPod

# macOS with Homebrew
brew install devpod

# Linux (download from GitHub releases)
curl -L https://github.com/loft-sh/devpod/releases/latest/download/devpod-linux-amd64 -o devpod
chmod +x devpod
sudo mv devpod /usr/local/bin/

# Verify installation
devpod --version

Step 2: Configure a Provider

DevPod needs to know where to create your development environment. Let’s set up Docker as our provider for local development:

# Add Docker provider
devpod provider add docker

# Configure Docker provider
devpod provider set docker --default-ide none

For cloud development, you’d configure providers like this:

# Add AWS provider
devpod provider add aws

# Configure with your AWS credentials
devpod provider set aws \
  --aws-access-key-id $AWS_ACCESS_KEY_ID \
  --aws-secret-access-key $AWS_SECRET_ACCESS_KEY \
  --aws-region us-west-2 \
  --aws-instance-type t3.medium

Step 3: Create a devcontainer.json

Let’s create a practical devcontainer.json for a Node.js project with TypeScript:

{
  "name": "Node.js TypeScript Development",
  "image": "mcr.microsoft.com/devcontainers/typescript-node:20-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/github-cli:1": {},
    "ghcr.io/devcontainers/features/docker-in-docker:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "esbenp.prettier-vscode",
        "dbaeumer.vscode-eslint",
        "bradlc.vscode-tailwindcss"
      ]
    }
  },
  "postCreateCommand": "npm install && npm run build",
  "remoteUser": "node",
  "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}"
}

Step 4: Create and Start Your Workspace

# Navigate to your project
cd my-node-project

# Create and start the workspace
devpod up

# If you want to use a specific IDE or none (SSH terminal)
devpod up --ide none

# SSH into your workspace
ssh $(devpod get workspace).devpod

Step 5: Manage Your Workspace

# Check workspace status
devpod list

# Stop a workspace (preserves state)
devpod stop

# Start a stopped workspace
devpod start

# Delete a workspace
devpod delete

# Update workspace after devcontainer.json changes
devpod up --recreate

Step 6: Connect Your IDE

VS Code:

# Open in VS Code (automatically installs Remote - SSH extension)
devpod up --ide vscode

JetBrains IDEs:

# DevPod integrates with JetBrains Gateway
devpod up --ide jetbrains-gateway

Any IDE via SSH:

# Get SSH connection details
devpod ssh-config

# Add to your ~/.ssh/config
Host my-project.devpod
  HostName $(devpod get workspace-ip)
  User root
  Port 2222
  IdentityFile ~/.devpod/provider-docker/ssh-key

Complete Example: Full-Stack Project

Here’s a more complex devcontainer.json for a full-stack project with a Node.js backend and frontend:

{
  "name": "Full-Stack Development",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/github-cli:1": {},
    "ghcr.io/devcontainers/features/docker-in-docker:1": {},
    "ghcr.io/devcontainers/features/kubectl:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "eamodio.gitlens",
        "ms-vscode.vscode-typescript-next"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "typescript.preferences.importModuleSpecifier": "non-relative"
      }
    }
  },
  "postCreateCommand": "npm install && cd client && npm install",
  "remoteUser": "node",
  "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
  "portsAttributes": {
    "3000": {
      "label": "Frontend Dev Server",
      "onForward": "notify"
    },
    "4000": {
      "label": "Backend API",
      "onForward": "notify"
    }
  }
}

Usage with DevPod:

# Start with auto-forwarded ports
devpod up --ide none

# Inside the workspace, start both applications
npm run dev:all

# Or in separate terminals
npm run dev:backend  # Port 4000
cd client && npm run dev  # Port 3000

Comparison: Detailed Decision Framework

Feature-by-Feature Comparison

FeatureVS Code DevContainersDevPodGitHub Codespaces
Open SourceYes (spec is open)Yes (MPL-2.0)No (proprietary)
Client-OnlyNo (requires VS Code)Yes (CLI + Desktop)No (cloud service)
Multi-IDE SupportNo (VS Code only)Yes (VS Code, JetBrains, SSH)VS Code + web editor
Local Docker✅ Native✅ Via provider❌ No
Kubernetes✅ Yes✅ Via provider❌ No
Cloud VMs❌ No✅ Yes (AWS, GCP, Azure, etc.)✅ Yes (managed)
SSH Remote Access✅ Via extension✅ First-class citizenLimited
Prebuilds✅ Supported✅ Supported✅ Automatic
Auto Shutdown⚠️ Limited✅ Yes, with timeout✅ Automatic
Cost ControlLimited (local only)✅ Excellent (5-10x cheaper)Expensive at scale
Vendor Lock-inMedium (Microsoft)✅ NoneHigh (GitHub)
Custom ProvidersNo✅ Yes (write your own)No
Community ProvidersN/A✅ 15+ providersN/A

Provider Ecosystem

DevPod Official Providers:

# Infrastructure providers
devpod provider add docker          # Local Docker
devpod provider add kubernetes      # Kubernetes cluster
devpod provider add ssh             # SSH to any machine
devpod provider add aws             # Amazon EC2
devpod provider add gcloud          # Google Cloud
devpod provider add azure           # Microsoft Azure
devpod provider add digitalocean    # DigitalOcean

DevPod Community Providers:

  • Hetzner, OVHcloud, Scaleway, Vultr (cloud VPS)
  • Multipass (local VMs on Ubuntu)
  • Custom cloud providers (Flow, Cloudbit, STACKIT, Exoscale, Open Telekom Cloud)

Decision Matrix

Choose VS Code DevContainers if:

  • ✅ You use VS Code exclusively
  • ✅ Need local Docker development
  • ✅ Want quick setup without additional tools
  • ✅ Already using GitHub Codespaces
  • ✅ Team is small (1-10 developers)

Choose DevPod if:

  • ✅ Need cloud VM provisioning (AWS/GCP/Azure)
  • ✅ Team uses multiple IDEs (VS Code + JetBrains)
  • ✅ Want cost optimization (5-10x cheaper than Codespaces)
  • ✅ Need vendor-neutral approach
  • ✅ Platform/SRE team managing environments at scale
  • ✅ Require auto-shutdown and prebuilds
  • ✅ Team is medium-large (10+ developers)
  • ✅ Terminal-based developer who prefers SSH

Choose GitHub Codespaces if:

  • ✅ Want fully managed, zero-configuration cloud environments
  • ✅ Team is already on GitHub
  • ✅ Need powerful cloud machines without managing infrastructure
  • ✅ Security and compliance require managed services
  • ✅ Don’t want to manage providers or cloud costs

Pros and Cons at a Glance

DevContainers (VS Code Extension)

Pros:

  • Free (uses local Docker)
  • Excellent VS Code integration
  • Simple setup for local development
  • Large community and documentation
  • Supported by Microsoft

Cons:

  • Tied to VS Code
  • Requires Docker installed locally
  • Local resources can be limiting
  • Not suitable for teams with mixed IDE preferences

DevPod

Pros:

  • IDE-agnostic (any IDE via SSH)
  • Runs anywhere (local, cloud VMs, Kubernetes)
  • Open-source and extensible
  • Cost-effective (use bare VMs)
  • No vendor lock-in
  • Great for remote/distributed teams

Cons:

  • Requires initial provider configuration
  • Cloud costs apply (but you control them)
  • More concepts to learn initially
  • SSH setup required for terminal-only workflows

GitHub Codespaces

Pros:

  • Zero configuration
  • Powerful cloud machines
  • Deep GitHub integration
  • Fully managed and secure
  • Scales with your needs

Cons:

  • Vendor lock-in to GitHub
  • Can get expensive at scale
  • Requires internet connection
  • Limited customization options

Best Practices for DevContainer Configurations

1. Pin Specific Versions

Always specify exact versions to ensure consistency:

{
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20-bullseye",
  "nodeVersion": "20.x"
}

2. Use Features for Common Tools

Reuse pre-built features instead of manual installation:

{
  "features": {
    "ghcr.io/devcontainers/features/github-cli:1": {},
    "ghcr.io/devcontainers/features/docker-in-docker:1": {},
    "ghcr.io/devcontainers/features/kubectl:1": {
      "version": "1.28.0"
    }
  }
}

3. Keep Post-Create Commands Light

Fast startup is crucial:

{
  "postCreateCommand": "npm install --prefer-offline --no-audit"
}

For heavy installations, use prebuilds or multi-stage builds.

4. Document Custom Requirements

Add a README for manual steps or non-standard configurations:

## Development Setup

This project uses DevContainers for consistent development environments.

### Getting Started

1. Install DevPod: `brew install devpod`
2. Run `devpod up` in the project root
3. SSH into workspace: `ssh $(devpod get workspace).devpod`
4. Start development: `npm run dev`

### Troubleshooting

If you encounter issues with Docker daemon, ensure Docker Desktop is running.

5. Test Your Configuration

Regularly verify your devcontainer.json works:

# Validate configuration
devpod up --dry-run

# Test fresh environment
devpod up --recreate

Troubleshooting Common Issues

Docker Not Running

# Verify Docker is running
docker version

# Start Docker Desktop or dockerd
# On macOS
open -a Docker

# On Linux
sudo systemctl start docker

SSH Connection Issues

# Regenerate SSH keys
devpod ssh-keys generate

# Check SSH config
devpod ssh-config

Provider Authentication

# Verify provider credentials
devpod provider list

# Reconfigure provider
devpod provider set aws --aws-access-key-id $AWS_ACCESS_KEY_ID

Slow Build Times

  • Use prebuilt images when possible
  • Cache dependencies in your Dockerfile
  • Use smaller base images
{
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20-bullseye-slim"
}

The Future of Development Environments

The industry is moving toward containerized, reproducible development environments. DevContainers provides the standard, and tools like DevPod make that standard work everywhere. We’re moving away from “works on my machine” toward “works the same way everywhere.”

Key trends to watch:

  • AI-Assisted Environment Setup – AI tools analyzing your project and suggesting optimal configurations
  • Hybrid Local-Cloud Workflows – Seamless switching between local and cloud environments
  • Enhanced Prebuilds – Faster environment startup through intelligent caching
  • Better IDE Integration – Deep support across more IDEs and editors

Your Next Steps

  1. Try DevPod Today – Install it and run devpod up on your current project
  2. Create a devcontainer.json – Document your project’s dependencies
  3. Experiment with Providers – Try local Docker, then explore cloud providers
  4. Share with Your Team – Standardize your development environment

The future of development is consistent, reproducible, and portable. DevContainers and DevPod give you that future today.

What’s your experience with containerized development environments? Have you tried DevPod? Share your thoughts and questions below!


Key Takeaways:

  • DevContainers specification provides a standard way to define development environments
  • DevPod extends DevContainers with flexibility to run anywhere and any IDE
  • Client-only architecture means no vendor lock-in
  • Cost savings come from using bare VMs instead of managed services
  • The combination enables truly reproducible development across teams

Official Resources:

DevContainers:

DevPod:

Community: