DevContainers + DevPod: Reproducible Dev Environments Anywhere
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:
- Container Image – The base operating system and runtime (Node.js, Python, Go, etc.)
- Features – Reusable installation steps for common tools that can be shared across projects
- Templates – Complete development environment configurations that can be applied to new projects
- Lifecycle Scripts – Commands that run at specific points during container creation
Lifecycle Script Reference:
| Script | When It Runs | Use Case |
|---|---|---|
initializeCommand | On host machine during initialization | Setup host-side tools |
onCreateCommand | First command inside container | Install base dependencies |
updateContentCommand | When new content is available | Sync or update files |
postCreateCommand | After workspace is assigned | Final setup, npm install |
postStartCommand | Each time container starts | Start services, daemons |
postAttachCommand | Each time tool attaches | IDE-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
| Feature | VS Code DevContainers | DevPod |
|---|---|---|
| IDE Support | VS Code only | VS Code, JetBrains, any IDE via SSH |
| Location | Local Docker only | Local, cloud VMs, Kubernetes, any remote machine |
| Provider Lock-in | None | None (open-source, client-only) |
| Setup Complexity | Simple (local Docker) | Requires provider configuration |
| Cost | Free (local resources) | Pay for cloud resources you choose |
| SSH Access | Limited | First-class citizen |
| Multi-Provider | No | Yes (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
| Feature | VS Code DevContainers | DevPod | GitHub Codespaces |
|---|---|---|---|
| Open Source | Yes (spec is open) | Yes (MPL-2.0) | No (proprietary) |
| Client-Only | No (requires VS Code) | Yes (CLI + Desktop) | No (cloud service) |
| Multi-IDE Support | No (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 citizen | Limited |
| Prebuilds | ✅ Supported | ✅ Supported | ✅ Automatic |
| Auto Shutdown | ⚠️ Limited | ✅ Yes, with timeout | ✅ Automatic |
| Cost Control | Limited (local only) | ✅ Excellent (5-10x cheaper) | Expensive at scale |
| Vendor Lock-in | Medium (Microsoft) | ✅ None | High (GitHub) |
| Custom Providers | No | ✅ Yes (write your own) | No |
| Community Providers | N/A | ✅ 15+ providers | N/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
- Try DevPod Today – Install it and run
devpod upon your current project - Create a devcontainer.json – Document your project’s dependencies
- Experiment with Providers – Try local Docker, then explore cloud providers
- 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:
- DevContainers Specification
- devcontainer.json Reference
- DevContainers Features
- DevContainers Templates
- VS Code Dev Containers Extension
DevPod:
Community: