Docker y TypeScript: contenedorización de aplicaciones de la A a la Z

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Docker y TypeScript: contenedorización de aplicaciones de la A a la Z



La contenedorización se ha convertido en el estándar del desarrollo moderno. Docker permite empaquetar una aplicación TypeScript junto con todas sus dependencias y entorno, garantizando su funcionamiento estable en cualquier plataforma, desde el ordenador local del desarrollador hasta un servidor de producción. En este artículo, analizaremos el ciclo completo: desde un Dockerfile básico hasta una compilación de producción optimizada.



1. Fundamentos de Docker para desarrolladores de TypeScript



Docker es una plataforma para crear, distribuir y ejecutar aplicaciones en entornos aislados (contenedores). Para aplicaciones TypeScript que se compilan a JavaScript y se ejecutan en Node.js, Docker resuelve tres tareas clave:



  • Reproducibilidad del entorno: olvídate de la frase "en mi máquina funciona". Las versiones de Node.js, npm y paquetes del sistema quedan fijadas en la imagen.
  • Aislamiento: cada aplicación se ejecuta en su propio contenedor sin afectar a otros servicios.
  • Escalabilidad: los contenedores se replican y orquestan fácilmente.


Antes de empezar, asegúrate de tener Docker y Docker Compose instalados. Puedes verificarlo con los comandos:



docker --versiondocker-compose --version


2. Creación de un Dockerfile para una aplicación TypeScript



Empecemos con una aplicación TypeScript simple. Supongamos que tenemos un archivo src/index.ts:



import express from 'express';

const app = express();const port = process.env.PORT || 3000;

app.get('/', (req, res) => { res.send('¡Hola desde Docker + TypeScript!');});

app.listen(port, () => { console.log(`Servidor iniciado en el puerto ${port}`);});


Ahora creemos un Dockerfile en la raíz del proyecto:



# ---- Imagen base para desarrollo ----FROM node:18-alpine AS baseWORKDIR /appCOPY package*.json ./RUN npm ci --only=production

# ---- Compilación de TypeScript ----FROM base AS buildCOPY tsconfig.json ./COPY src/ ./src/RUN npm ci && npm run build

# ---- Imagen de producción ----FROM node:18-alpine AS productionWORKDIR /appCOPY --from=build /app/dist ./distCOPY --from=base /app/node_modules ./node_modulesEXPOSE 3000CMD ["node", "dist/index.js"]


Esto es una compilación multi-etapa (multi-stage build). Permite:

  • Instalar todas las dependencias (incluyendo devDependencies) solo en la etapa de compilación
  • Que en la imagen final solo se incluya el JavaScript compilado y las dependencias de producción
  • Reducir el tamaño de la imagen entre 2 y 3 veces


Construye la imagen y ejecuta el contenedor:



docker build -t mi-app-typescript .docker run -p 3000:3000 mi-app-typescript


3. Configuración de docker-compose para desarrollo y producción



Docker Compose simplifica el trabajo con aplicaciones multi-contenedor. Creemos un docker-compose.yml:



version: '3.8'

services: app: build: context: . target: development ports: - "3000:3000" volumes: - .:/app - /app/node_modules environment: - NODE_ENV=development command: npm run dev

# Versión de producción app-prod: build: context: . target: production ports: - "80:3000" environment: - NODE_ENV=production


Para mayor comodidad, añadamos un Dockerfile separado para desarrollo (se puede extender la imagen base):



# Dockerfile.devFROM node:18-alpineWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .EXPOSE 3000CMD ["npm", "run", "dev"]


Ejecución en modo desarrollo:



docker-compose up app


Gracias a volumes, los cambios en el código se detectan automáticamente (hot-reload), y /app/node_modules está excluido para no sobrescribir las dependencias del contenedor.

Blogs

Book Recommendations