1. ¿Qué es Docker y por qué importa?
Docker es una plataforma de contenedorización que permite empaquetar una aplicación junto con todas sus dependencias en una unidad portátil llamada contenedor. A diferencia de las máquinas virtuales, los contenedores comparten el kernel del sistema operativo host, lo que los hace mucho más ligeros y rápidos.
| Aspecto | Máquina Virtual | Contenedor Docker |
|---|---|---|
| Tiempo de arranque | 1-2 minutos | Milisegundos |
| Tamaño típico | 5-50 GB | 50-500 MB |
| Aislamiento | Completo (OS propio) | Proceso aislado |
| Portabilidad | Media | Alta |
| Overhead de recursos | Alto | Muy bajo |
La propuesta de valor de Docker es simple: si el contenedor funciona en tu máquina local, funcionará idéntico en el servidor de staging y en producción. Elimina la clase entera de bugs causados por diferencias de entorno.
2. Conceptos clave
- Imagen: Plantilla inmutable de solo lectura. Define el sistema operativo base, las dependencias y el código de la aplicación. Es como un snapshot del sistema.
- Contenedor: Instancia en ejecución de una imagen. Puedes tener múltiples contenedores del mismo tipo. Son efímeros por naturaleza.
- Dockerfile: Archivo de texto con instrucciones para construir una imagen. Es el "código fuente" de tu imagen.
- Docker Hub / Registry: Repositorio de imágenes. Docker Hub es el público por defecto. Puedes usar uno privado (GitHub Container Registry, AWS ECR, etc.).
- Volumen: Mecanismo para persistir datos fuera del contenedor. Los datos en el sistema de archivos del contenedor se pierden cuando este se elimina.
- Red Docker: Permite la comunicación entre contenedores de forma aislada del host.
3. Comandos esenciales de Docker CLI
Estos son los comandos que usarás a diario. Dominarlos al 100% te ahorrará mucho tiempo:
4. Escribir Dockerfiles eficientes
Un Dockerfile mal escrito produce imágenes enormes, lentas de construir y con capas innecesarias. Aquí el patrón correcto para una aplicación Node.js, con todas las optimizaciones aplicadas:
💡 Regla de oro del caché: Ordena las instrucciones del Dockerfile de "menos frecuente de cambiar" a "más frecuente de cambiar". Las instrucciones que copian el código fuente deben ir al final, porque cualquier cambio en el código invalida todas las capas posteriores.
Crea siempre un archivo .dockerignore junto al Dockerfile para excluir archivos innecesarios del contexto de build:
5. Multi-stage builds para imágenes optimizadas
Los multi-stage builds son una de las características más poderosas de Docker moderno. Permiten usar múltiples imágenes base en un solo Dockerfile: una para compilar/construir y otra mucho más ligera para ejecutar. El resultado final solo contiene lo necesario para producción.
6. Docker Compose: orquestación local
Docker Compose permite definir y ejecutar aplicaciones multicontenedor con un solo archivo YAML. Es indispensable para el desarrollo local: define toda tu stack (app, base de datos, redis, nginx) en un archivo versionable.
Los comandos básicos de Docker Compose que necesitas:
7. Redes y volúmenes en Docker
Por defecto, Docker Compose crea una red para todos los servicios definidos en el mismo archivo. Los contenedores se comunican entre sí usando el nombre del servicio como hostname. Así, la app puede conectarse a la base de datos con el hostname db, no con una IP.
8. Buenas prácticas para producción
El salto de desarrollo a producción con Docker requiere tener en cuenta estas prácticas:
- Nunca uses :latest en producción. Siempre pin a una versión específica (node:22.11-alpine). Así los deployments son reproducibles.
- Ejecuta como usuario no-root. Por defecto, los procesos en contenedores corren como root, lo que es un riesgo de seguridad. Crea un usuario dedicado en el Dockerfile.
- Usa variables de entorno para secretos. Nunca hardcodees contraseñas o API keys en el Dockerfile o en el código. Usa .env localmente y gestores de secretos en producción.
- Implementa healthchecks. Los orquestadores (Kubernetes, Docker Swarm, ECS) usan healthchecks para saber cuándo reiniciar un contenedor.
- Limita recursos. Establece límites de CPU y memoria para evitar que un contenedor consuma todos los recursos del host.
- Usa imágenes minimalistas. Alpine o Distroless tienen menos superficie de ataque y menos vulnerabilidades. Revisa regularmente con docker scout cves.
⚠️ Seguridad: Antes de subir una imagen a producción, analiza sus vulnerabilidades con docker scout cves mi-imagen:tag o trivy image mi-imagen:tag. Es habitual encontrar vulnerabilidades en imágenes desactualizadas, incluso en las oficiales.
Conclusión
Docker es hoy una habilidad fundamental para cualquier desarrollador que trabaje con aplicaciones de backend, servicios web o infraestructura. La curva de aprendizaje inicial es real, pero los beneficios en reproducibilidad, portabilidad y velocidad de deployment compensan ampliamente la inversión.
Los próximos pasos naturales son: aprender Docker Swarm para orquestación básica en producción, explorar Kubernetes para orquestación a gran escala, y familiarizarte con GitHub Actions o GitLab CI para construir y publicar imágenes automáticamente en cada push.