Entornos de desarrollo reproducibles con Docker y Dev Containers: Adiós al ‘en mi máquina funciona’
Hace un año incorporamos a un desarrollador senior a un proyecto que integraba microservicios en Node.js 22, utilidades en Python 3.12, PostgreSQL con la extensión pgvector y colas de tareas en Redis.
El proceso de Onboarding para que el nuevo desarrollador pudiera ejecutar la aplicación en su portátil local duró dos días completos.
Hubo conflictos de versiones entre NVM, diferencias en el compilador de C++ para binarios nativos en macOS M3 frente a Windows, e incompatibilidades de variables de entorno. Durante esos dos días, dos ingenieros senior tuvieron que detener su trabajo para hacer pair programming y desatascar la instalación.
Dos semanas después configuramos Dev Containers (.devcontainer/devcontainer.json).
Cuando se sumó el siguiente desarrollador al equipo, clonó el repositorio, abrió VS Code / Cursor, hizo clic en "Reopen in Container", y en 3 minutos y 40 segundos tenía la aplicación corriendo con la base de datos poblada y todos los linters configurados.
Tener entornos de desarrollo reproducibles con Docker no es una preferencia cosmética; es la diferencia entre un equipo acelerado y una pesadilla de soporte técnico interno.
¿Qué son los Dev Containers y por qué superan a Docker Compose?
Durante años intentamos solucionar el problema de las versiones en local usando docker-compose.yml.
Aunque Docker Compose resolvía la ejecución de servicios de fondo (bases de datos o cachés), el código fuente principal seguía ejecutándose en el sistema operativo del anfitrión (Host OS). Tu editor de código utilizaba los binarios de Node.js o Python instalados en tu máquina local, lo que provocaba discrepancias en el intellisense, formatos de línea y extensiones del IDE.
La especificación Dev Containers (estandarizada por la Development Containers Specification de la Linux Foundation) va un paso más allá: mueve todo el entorno de desarrollo (incluyendo el servidor del editor, terminal, extensiones y compiladores) dentro de un contenedor de Docker aislado.
┌─────────────────────────────────────────────────────────┐
│ Máquina Anfitriona (macOS / Windows / Linux) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Editor de Código (VS Code / Cursor Client UI) │ │
│ └──────────────────────────┬──────────────────────────┘ │
│ │ SSH / Socket RPC │
│ ┌──────────────────────────▼──────────────────────────┐ │
│ │ Contenedor Docker (Linux Debian/Ubuntu) │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ VS Code Server + Extensiones + Linters │ │ │
│ │ ├─────────────────────────────────────────────────┤ │ │
│ │ │ Node.js 22 + Python 3.12 + TypeScript + Bun │ │ │
│ │ ├─────────────────────────────────────────────────┤ │ │
│ │ │ Código Fuente Montado + PostgreSQL + Redis │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Configuración Paso a Paso de un Dev Container Profesional
Para convertir cualquier proyecto en un entorno reproducible, solo necesitas crear una carpeta .devcontainer en la raíz del repositorio con los siguientes dos archivos.
1. .devcontainer/docker-compose.yml
version: 39;3.839;
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ..:/workspace:cached
command: sleep infinity
network_mode: service:db
db:
image: pgvector/pgvector:pg16
environment:
POSTGRES_DB: dev_db
POSTGRES_USER: dev_user
POSTGRES_PASSWORD: dev_password
ports:
- "5432:5432"
2. .devcontainer/devcontainer.json
{
"name": "Dominicode Fullstack Dev Environment",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"customizations": {
"vscode": {
"settings": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"typescript.tsdk": "node_modules/typescript/lib"
},
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"eamodio.gitlens",
"biomejs.biome"
]
}
},
"remoteUser": "node",
"postCreateCommand": "bun install"
}
Ventajas Clave para Equipos de Desarrollo e IA
- Onboarding en 1 Clic: Cualquier nuevo desarrollador (o agente de IA que opere en entornos remotos) puede levantar un workspace 100% funcional sin instalar dependencias globales en su máquina.
- Homogeneización de herramientas: Todo el equipo comparte exactamente la misma versión de Node.js, TypeScript y linters. Nadie puede subir código formateado con reglas distintas.
- Aislamiento Total: Puedes trabajar simultáneamente en dos proyectos que utilicen versiones totalmente incompatibles de bases de datos o ejecutables de sistema sin que interfieran entre sí.
Como analizamos en nuestra guía sobre cómo formar a tu equipo de desarrollo en IA, estandarizar los entornos de trabajo es el primer paso para acelerar la adopción de herramientas avanzadas.
Al escribir código dentro del contenedor, sigues aplicando principios de programación defensiva en TypeScript, con la tranquilidad de que las validaciones de tipo en tiempo de ejecución se comportarán exactamente igual en local y en integración continua.
Además, mantener aislados los límites de dependencias de tus servicios facilita aplicar estrategias de graph engineering para mapear tu arquitectura.
Decir adiós al "en mi máquina funciona" es posible. Adoptar Dev Containers eleva la madurez de tu ingeniería de software y ahorra cientos de horas de soporte innecesario.
Si quieres dominar las mejores prácticas de DevOps, arquitectura y desarrollo moderno con TypeScript, explora los Cursos de Dominicode. Y si quieres colaborar en proyectos reales junto a desarrolladores senior, súmate a Dominicode Labs.
Preguntas frecuentes
¿Afecta el rendimiento de lectura de disco al usar Dev Containers en macOS o Windows?
En macOS y Windows, Docker ejecuta una máquina virtual ligera. Para garantizar una velocidad de lectura de archivos óptima en los volúmenes de código fuente, la especificación usa montajes con flag :cached o tecnologías como VirtioFS en macOS, ofreciendo un rendimiento prácticamente idéntico al nativo.
¿Puedo usar Dev Containers si programo en Cursor o WebStorm?
Sí. Cursor soporta la especificación Dev Containers de forma nativa al estar basado en VS Code. JetBrains (WebStorm, IntelliJ) también ofrece soporte completo para Dev Containers a través de su arquitectura de desarrollo remoto.
¿Qué ocurre con mis credenciales de Git y claves SSH?
Dev Containers reenvía automáticamente el agente SSH (SSH Agent Forwarding) y las credenciales de Git de tu máquina anfitriona al interior del contenedor. Puedes hacer git commit y git push desde la terminal del contenedor usando tus claves privadas de forma segura sin copiarlas dentro de la imagen.
¿Dev Containers es útil para proyectos pequeños de un solo desarrollador?
Absolutamente. Además de evitar contaminar tu sistema operativo con decenas de versiones globales de bases de datos o servicios, te permite formatear tu portátil o cambiar de equipo informático y retomar exactamente el mismo estado de desarrollo en minutos.
Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.
