5.3 · Docker para Node.js

Nivel 5 · Nivel pro & despliegue

5.3Docker para Node.js

Objetivo: contenerizar su aplicación Node con Docker (Dockerfile, imágenes, contenedores) y orquestar la pila con Compose — reproductibilidad, portabilidad y facilidad de despliegue.
Tiempo estimado: 11 min · lectura autónoma · Si solo tienes 5 min: lee «Lo esencial en 30s» + el esquema.

Lo esencial en 30 segundos

  • Fin del « en mi máquina funciona » : el contenedor lleva la app con su entorno y corre idéntico en todas partes.
  • Imagen → contenedor : el Dockerfile describe la receta, docker build fija la imagen, docker run lanza el contenedor.
  • Compose para la pila : app + base + caché descritos en un archivo y lanzados juntos — incorporación en un comando.

Mini-caso hilado — Salim conteneriza en Argel

La API de Salim corre perfecta en su puesto en Argel — pero falla en el de su colega (versión de Node distinta, variable faltante). Escribe un Dockerfile : imagen base Node, dependencias instaladas en la imagen, comando de arranque. Luego un archivo Compose con la base de datos : un solo lanzamiento monta toda la pila. Continuación de los casos 5.1-5.2 — Salim vuelve su app reproducible en todas partes.

Continuación de los casos 5.1-5.2 — Salim pasa de « en mi casa funciona » a « igual en todas partes ».

1. Contenerizar : imagen y contenedor

Docker resuelve el « en mi máquina funciona » empaquetando la aplicación con todo su entorno (versión de Node, dependencias, configuración) en un contenedor aislado y portable, que corre idéntico en todas partes : puesto, colega, servidor, nube. Conceptos : la imagen (modelo fijo de la app + entorno, definido por un Dockerfile — la receta : imagen base Node, copiar el código, instalar las dependencias, comando de arranque) y el contenedor (instancia en ejecución de una imagen). Se construye (docker build), se lanza (docker run). El .dockerignore excluye lo inútil de la imagen (node_modules — las dependencias se instalan DENTRO de la imagen). Salim ya no discute versiones : el entorno viaja con el código.

Reflejo : todo lo específico de su puesto y ausente de la imagen es un futuro fallo en otro lado — la imagen debe contenerlo todo.

2. Docker Compose y beneficios

Para una pila realista (app + base + caché), Docker Compose (docker-compose.yml) define varios contenedores y sus relaciones, lanzados juntos con un comando (docker compose up). Un solo archivo describe toda la pila, reproducible idéntica — y la incorporación se vuelve trivial : un nuevo desarrollador lanza un comando y obtiene todo el entorno. Beneficios : reproductibilidad (idéntico en todas partes), aislamiento (sin conflictos entre apps y versiones), portabilidad (todo anfitrión Docker), facilidad de despliegue (desplegar = lanzar el contenedor — ver 5.4). Salim añade la base al Compose : su colega arranca en minutos.

Docker es un estándar del desarrollo moderno y una competencia transversal (DevOps) : las bases bastan para empezar, la orquestación avanzada vendrá según las necesidades.

3. La dosis justa para un desarrollador

No hace falta volverse experto en infraestructura : apunte a las bases útiles — escribir un Dockerfile simple, construir y lanzar, orquestar app + base con Compose, excluir lo inútil vía .dockerignore. Domine Node primero (su corazón de oficio), añada Docker cuando trabaje en equipo, prepare un despliegue o gestione varios servicios. A evitar : incluir node_modules en la imagen, apuntar a la orquestación avanzada antes de las bases, o contenerizar un minúsculo script de aprendizaje sin necesidad real. Salim mantiene su Dockerfile legible : seis instrucciones comprendidas valen más que una receta copiada.

El buen perfil : un desarrollador que conoce las bases de la explotación — autónomo, capaz no solo de programar sino de entregar.

Error frecuente de interpretación: « Docker es solo para el despliegue — y copio node_modules en la imagen para ir rápido ». Doble error. Docker sirve desde el desarrollo (entorno idéntico en equipo, incorporación inmediata), no solo en producción. Y copiar node_modules fija binarios compilados para su puesto en la imagen : las dependencias deben instalarse DENTRO de la imagen (RUN npm install), con un .dockerignore que las excluya del contexto.
De la imagen al contenedor Corre igual en todas partes Dockerfile Receta : Node +código + dependenciasdocker build Construye laIMAGEN (modelo fijo)docker run Lanza unCONTENEDOR (instancia)Compose App + base +caché juntas
Corre igual en todas partes
Versión en texto del esquema (SEO / lectores de pantalla / traducción): 1) Dockerfile : Salim escribe la receta (imagen Node, código copiado, dependencias instaladas en la imagen, comando de arranque) con un .dockerignore. 2) Build : la imagen fija la app y su entorno. 3) Run : el contenedor corre idéntico en todo puesto. 4) Compose : app + base lanzadas juntas con un comando. Lección : el entorno viaja con el código — fin del « en mi casa funciona ».

¿Lo sabía?

El « en mi máquina funciona » tiene un nombre de antipatrón : la diferencia de entorno. Docker la elimina haciendo viajar el entorno con el código.
El contenedor es la máquina que viaja.

Misma imagen, mismo comportamiento — en todas partes.

🔎 Ejemplo concreto — El Dockerfile de Salim

La receta de la imagen, legible en seis líneas.

FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "app.js"]
# .dockerignore : node_modules
# docker compose up → app + base juntas

Lectura : cada instrucción tiene un papel — base, dependencias, código, arranque.

Lección : un Dockerfile comprendido vale más que una receta copiada.

Vocabulario de la sección

Docker
Herramienta que empaqueta la app con su entorno en un contenedor portable.

Ejemplo sencillo: La API de Salim corre igual en Argel y en casa de su colega.

Lo que no es: un simple instalador de Node en cada puesto.

Reflejo: ¿mi app aún depende de mi puesto?

Imagen
Modelo fijo de la app + entorno, construido desde el Dockerfile.

Ejemplo sencillo: Salim construye una imagen versionada de cada entrega.

Lo que no es: el contenedor en curso de ejecución.

Reflejo: ¿puedo reconstruir esta imagen idéntica?

Dockerfile
Receta de construcción de la imagen (base, código, dependencias, arranque).

Ejemplo sencillo: Seis instrucciones legibles para la API de Salim.

Lo que no es: un script que instala Node a mano en un servidor.

Reflejo: ¿cada instrucción está comprendida, no copiada?

Contenedor
Instancia en ejecución de una imagen, aislada y portable.

Ejemplo sencillo: Salim lanza un contenedor idéntico en dev y en pruebas.

Lo que no es: la propia imagen fija.

Reflejo: ¿dev y prod lanzan la misma imagen?

Docker Compose
Archivo que describe varios contenedores lanzados juntos.

Ejemplo sencillo: App + base de Salim arrancadas con un solo comando.

Lo que no es: la orquestación avanzada de tipo Kubernetes.

Reflejo: ¿un nuevo dev arranca en un comando?

En la práctica — Contenerizar una aplicación Node

  1. Escriba un Dockerfile : partir de una imagen Node, copiar el código, instalar las dependencias (npm install), definir el comando de arranque. Añada un .dockerignore (node_modules…).
  2. Construya la imagen (`docker build`) y lance un contenedor (`docker run`) ; verifique que la aplicación corre en el contenedor.
  3. Orqueste con Docker Compose : un docker-compose.yml que defina la app Node Y su base, lanzadas juntas (`docker compose up`).
  4. Disfrute los beneficios : reproductibilidad (idéntico en todas partes), aislamiento, e incorporación (un `docker compose up` basta para todo el entorno).
Conteneriza su aplicación Node con Docker (Dockerfile, imágenes, contenedores) y orquesta la pila con Compose — reproductibilidad, portabilidad y facilidad de despliegue.

Guion listo para decir — proponer Docker al equipo

« Nuestra API funciona en mi puesto pero no en otro lado : es un problema de entorno, no de código. Propongo un Dockerfile simple — seis instrucciones — más un Compose con la base. Cada uno lanzará la misma imagen, y un recién llegado arrancará en un comando. Lo mantenemos legible y evitamos la orquestación avanzada por ahora. »

Para decir en reunión de equipo para hacer adoptar la contenerización sin apuntar a la pericia DevOps.

Modelo copiar-pegar — Dockerfile Node genérico

FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
# .dockerignore :
# node_modules
# npm-debug.log
# .git

Solo / presupuesto pequeño

Salim solo : un Dockerfile simple sin Compose basta — la imagen ya fija el entorno.

Pyme / equipo reducido

Compose app + base : cada colega arranca la pila completa sin instalación manual.

Pyme en Argel

Salim comparte la imagen con el equipo en Argel : todos prueban la misma versión, fin de las diferencias de puesto.

Equipo que empieza

Pareja : uno escribe el Dockerfile, el otro lo relee línea por línea ; build probado en dos puestos antes de adoptarlo.

Prudencia: No ponga nunca secretos (contraseñas, claves, tokens) en el Dockerfile ni en la imagen : páselos por el entorno al lanzar. Una imagen compartida conserva todo su contenido — un secreto integrado queda legible.

✓ Buenas prácticas

  • Dominar Node primero, luego aprender las bases de Docker.
  • Añadir un .dockerignore (excluir node_modules).
  • Usar Docker Compose para orquestar app + base (incorporación rápida).

✗ Errores frecuentes

  • Incluir node_modules en la imagen (instalarlo en la imagen vía npm install).
  • Querer dominar la orquestación avanzada antes de las bases.
  • Contenerizar un pequeño script de aprendizaje sin necesidad real.

Puntos clave

  • DOCKER empaqueta la aplicación CON su entorno en un CONTENEDOR aislado y portable, que corre IDÉNTICO en todas partes — fin del « en mi máquina funciona ».
  • IMAGEN (modelo fijo, definido por un DOCKERFILE) → CONTENEDOR (instancia). `docker build` / `docker run`. .dockerignore excluye node_modules.
  • DOCKER COMPOSE define VARIOS contenedores (app + base + caché) lanzados juntos (`docker compose up`) — describe toda la pila, reproducible.
  • Beneficios : REPRODUCTIBILIDAD, aislamiento, portabilidad, facilidad de despliegue, incorporación rápida. Estándar moderno (transversal DevOps).

Reto 48h — aplica mañana

Escriba el Dockerfile de su app (modelo de arriba) y láncela en contenedor : ¿responde igual que en su puesto?

Lista de salida de la sección
  • Puedo explicar imagen frente a contenedor en una frase.
  • Mi Dockerfile construye una imagen que corre.
  • Sé por qué node_modules no figura ahí.
Autoevaluación 1-5 : ¿mi imagen es reconstruible idéntica?¿un colega arrancaría mi pila en un comando?

Preguntas frecuentes

¿Qué aporta concretamente Docker, y es necesario para un desarrollador Node?

Docker aporta sobre todo la reproductibilidad : fin del « en mi máquina funciona » (el contenedor lleva todo, así que corre idéntico en todas partes). También : aislamiento (varias apps/versiones sin conflictos), portabilidad (todo anfitrión Docker), facilidad de despliegue (desplegar = lanzar el contenedor), incorporación rápida (un docker compose up monta toda la pila). Para aprender Node o pequeños proyectos solo, no estrictamente. Para desarrollo profesional, en equipo o con despliegue, se ha vuelto casi imprescindible — y transversal. Domine Node primero, luego las bases de Docker.

Docker, despliegue, CI/CD... ¿debo volverme experto DevOps además de desarrollador?

No, no experto — pero conocer las bases beneficia enormemente : autonomía (poner su trabajo en producción), empleabilidad (ofertas que piden Docker/despliegue/CI-CD), mejor colaboración (apps fáciles de desplegar), visión completa del ciclo. Apunte a las bases : contenerizar y Compose (no la orquestación avanzada), desplegar en una plataforma simple, un pipeline CI/CD simple, secretos y config en variables de entorno, nociones de logs/monitorización/HTTPS. El buen perfil : un desarrollador que conoce las bases de la explotación — capaz no solo de programar sino de entregar.

Comprueba tu comprensión

¿Qué problema resuelve Docker principalmente?

Recursos adicionales (opcional, para ir más allá)

Examen del nivel 5Preguntas inéditas y más difíciles para validar tus conocimientos