Por qué la contenerización de aplicaciones TypeScript es imprescindible para el desarrollador moderno
\nImagine la situación: escribió una aplicación TypeScript increíble en su MacBook, todo funciona perfectamente. Sube el código a un servidor Ubuntu y obtiene un montón de errores. ¿Le suena familiar? El problema está en la diferencia de entornos: versiones de Node.js, bibliotecas del sistema, variables de entorno. Docker resuelve este problema de una vez por todas. La contenerización de aplicaciones TypeScript permite empaquetar el código junto con todas sus dependencias en un contenedor aislado que se ejecutará igual en cualquier servidor, en la nube o en la máquina local de un colega.
\nEn este artículo, analizaremos cómo contenerizar correctamente una aplicación TypeScript con Docker. Aprenderá no solo los pasos básicos, sino también técnicas avanzadas: builds multi-etapa, optimización del tamaño de la imagen, almacenamiento en caché de dependencias y trabajo con variables de entorno. ¡Vamos allá!
\n\nQué es Docker y por qué lo necesita un desarrollador TypeScript
\nDocker es una plataforma para crear, distribuir y ejecutar aplicaciones en contenedores. Un contenedor es un entorno ligero y autónomo que contiene todo lo necesario para que funcione su aplicación TypeScript: código, runtime (Node.js), herramientas del sistema, bibliotecas y configuraciones.
\nLas ventajas para proyectos TypeScript son evidentes:
\n- \n
- Reproducibilidad del entorno — nunca más «en mi máquina funciona» y «falló en producción». \n
- Aislamiento — cada aplicación se ejecuta en su propio contenedor sin interferir con otros servicios. \n
- Escalabilidad — es fácil ejecutar 10 instancias de su servidor TypeScript mediante Docker Compose o Kubernetes. \n
- Simplicidad en el despliegue — una sola imagen se puede ejecutar en cualquier plataforma: AWS, Google Cloud, DigitalOcean o localmente. \n
Requisitos previos
\nAntes de comenzar, asegúrese de tener instalado:
\n- \n
- Docker — descárguelo del sitio oficial (funciona en Windows, macOS, Linux). \n
- Node.js versión 18 o superior (para compilar TypeScript). \n
- TypeScript — instalado global o localmente en el proyecto. \n
Como ejemplo, tomaremos una aplicación Express simple en TypeScript. Pero el enfoque es universal: puede contenerizar cualquier proyecto TypeScript, desde un bot de Telegram hasta un servidor NestJS.
\n\nEstructura del proyecto
\nPara empezar, crearemos una estructura mínima de aplicación TypeScript:
\nmy-typescript-app/\n├── src/\n│ └── index.ts\n├── package.json\n├── tsconfig.json\n└── Dockerfile\nEl archivo src/index.ts contendrá un servidor HTTP simple:
import express from 'express';\nconst app = express();\nconst PORT = process.env.PORT || 3000;\n\napp.get('/', (req, res) => {\n res.send('Hello from TypeScript + Docker!');\n});\n\napp.listen(PORT, () => {\n console.log(`Server is running on port ${PORT}`);\n});\nEl archivo tsconfig.json con configuración básica:
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "outDir": "./dist",\n "rootDir": "./src",\n "strict": true,\n "esModuleInterop": true\n }\n}\n\nEscribimos el primer Dockerfile para una aplicación TypeScript
\nLa forma más sencilla es hacer un build de una sola etapa. Pero nosotros seguiremos el camino correcto desde el principio y crearemos un build multi-etapa. Esto permitirá reducir la imagen final varias veces.
\n# Stage 1: Build\nFROM node:18-alpine AS builder\nWORKDIR /app\nCOPY package*.json ./\nRUN npm install\nCOPY . .\nRUN npm run build\n\n# Stage 2: Production\nFROM node:18-alpine\nWORKDIR /app\nCOPY --from=builder /app/dist ./dist\nCOPY --from=builder /app/package*.json ./\nRUN npm install --production\nEXPOSE 3000\nCMD ["node", "dist/index.js"]\nAnalicemos cada etapa:
\n- \n
- bu \n