¿Por qué tu proyecto JavaScript merece Docker?
\n\n¿Alguna vez has escuchado la frase: «¡En mi máquina funcionaba!»? Si eres desarrollador JavaScript, seguramente te has encontrado con la situación en la que la aplicación funciona perfectamente de forma local, pero en el servidor o en el ordenador de un colega falla con un error misterioso. La contenerización de aplicaciones JavaScript con Docker resuelve este problema de una vez por todas.
\n\nDocker te permite empaquetar tu código, todas las dependencias (paquetes npm), variables de entorno e incluso la versión de Node.js en un «contenedor» ligero. Este contenedor funcionará igual en tu portátil, en un servidor en AWS y en el ordenador de un principiante que acaba de instalar Git. En este artículo, veremos cómo hacer que JavaScript y Docker funcionen juntos, escribiremos código real y crearemos una imagen lista para producción para tu próximo proyecto personal.
\n\nFundamentos de Docker para el desarrollador JavaScript
\n\nAntes de sumergirnos en el código, aclaremos los conceptos clave. Docker es como una máquina virtual, pero mucho más ligera. En lugar de emular un sistema operativo completo, utiliza el núcleo del host y aísla solo tu aplicación.
\n\nDockerfile: la receta de tu aplicación
\n\nEste es un archivo de texto en el que describes cómo construir la imagen. Para una aplicación Node.js, un Dockerfile típico se ve así:
\n\n# Usamos la imagen oficial de Node.js\nFROM node:18-alpine\n\n# Establecemos el directorio de trabajo dentro del contenedor\nWORKDIR /app\n\n# Copiamos package.json y package-lock.json\nCOPY package*.json ./\n\n# Instalamos las dependencias\nRUN npm ci --only=production\n\n# Copiamos el código fuente\nCOPY . .\n\n# Abrimos el puerto\nEXPOSE 3000\n\n# Comando para ejecutar\nCMD ["node", "server.js"]\n\nObserva: primero copiamos package.json y luego todo el código. Esto no es casualidad. Docker almacena en caché las capas, y si no has cambiado las dependencias, el paso npm ci no se reiniciará con cada cambio de código. Esto acelera enormemente la compilación.
Imágenes y contenedores
\n\n- \n
- Imagen (Image) — es una plantilla. La construyes una vez. \n
- Contenedor (Container) — es una instancia en ejecución de la imagen. Puedes crear 10 contenedores a partir de una sola imagen. \n
Creando una aplicación Node.js desde cero y contenerizándola
\n\nEscribamos una aplicación Express simple y la empaquetemos en Docker. Este será nuestro primer paso práctico en la contenerización de JavaScript.
\n\nPaso 1: Escribimos la aplicación
\n\nCrea una carpeta docker-node-app y dentro, el archivo server.js:
const express = require('express');\nconst app = express();\nconst PORT = process.env.PORT || 3000;\n\napp.get('/', (req, res) => {\n res.json({ \n message: '¡Hola desde el contenedor!',\n nodeVersion: process.version,\n environment: process.env.NODE_ENV || 'development'\n });\n});\n\napp.listen(PORT, () => {\n console.log(`Servidor iniciado en el puerto ${PORT}`);\n});\n\nInicializamos npm e instalamos express:
\n\nnpm init -y\nnpm install express\n\nAhora tenemos una aplicación funcional. Ejecútala localmente: node server.js. Abre http://localhost:3000 — verás un JSON.
Paso 2: Creamos el Dockerfile
\n\nCrea un archivo Dockerfile (sin extensión) en la raíz del proyecto:
FROM node:18-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=production\nCOPY . .\nEXPOSE 3000\nCMD ["node", "server.js"]\n\nAñadimos un .dockerignore para no copiar archivos innecesarios a la imagen:
node_modules\nnpm-debug.log\n.git\n.gitignore\n.env\nDockerfile\n\nPaso 3: Construimos y ejecutamos
\n\nAbre la terminal en la carpeta del proyecto y ejecuta:
\n\ndocker build -t my-node-app .\ndocker run -p 3000:3000 my-node-app\n\nLa bandera