DevOps Docker

Optimizar imágenes Docker para aplicaciones Node.js

Reduce el tamaño de tus imágenes Docker de Node.js hasta un 80% y mejora los tiempos de build con estas técnicas avanzadas de optimización.

10 min
Docker Node.js DevOps Optimización

Las imágenes Docker pesadas ralentizan deploys y consumen recursos innecesarios. Aprende a optimizar tus imágenes de Node.js drásticamente.

El problema

Una imagen Docker típica de Node.js puede pesar fácilmente 1GB o más. Esto causa:

  • Builds lentos
  • Deploys lentos
  • Mayor uso de ancho de banda
  • Costos más altos de almacenamiento
  • Superficie de ataque de seguridad más grande

Técnica 1: Usar imágenes base Alpine

# ❌ Mala práctica - Imagen pesada
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "index.js"]

# ✅ Buena práctica - Imagen Alpine
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
CMD ["node", "index.js"]

Resultado: De ~900MB a ~170MB

Técnica 2: Multi-stage builds

# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/index.js"]

Resultado: De ~170MB a ~70MB

Técnica 3: Optimizar layers de cache

FROM node:18-alpine

# Instalar dependencias del sistema primero (cambian poco)
RUN apk add --no-cache tini

WORKDIR /app

# Copiar solo package.json primero (mejor cache)
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# Copiar código fuente al final (cambia frecuentemente)
COPY . .

USER node
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "index.js"]
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.env.local
dist
coverage
.vscode
.idea
*.md

Para máxima seguridad y tamaño mínimo:

FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM gcr.io/distroless/nodejs18-debian11
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["dist/index.js"]
``ultado**: ~50MB

## Técnica 6: Comprimir node_modules

\`\`\`dockerfile
FROM node:18-alpine AS deps
```dockerfile
FROM node:18-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && \
    npm prune --production && \
    npm dedupe

FROM node:18-alpine
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
USER node
CMD ["node", "index.js"]
``mparación de tamaños

| Técnica      | Tamaño | Build Time |
| ------------ | ------ | ---------- |
| Node:18 base | 900MB  | 2:30 min   |
| Alpine       | 170MB  | 1:45 min   |
| Multi-stage  | 70MB   | 2:00 min   |
| Distroless   | 50MB   | 2:10 min   |

## Script de build optimizado

```bash
#!/bin/bash

# Build con BuildKit (más rápido)
DOCKER_BUILDKIT=1 docker build \
  --build-arg NODE_ENV=production \
  --cache-from myapp:latest \
  -t myapp:latest \
  -t myapp:$(git rev-parse --short HEAD) \
  .

# Verificar tamaño
docker images myapp:latest

# Análisis de layers
docker history myapp:latest

Herramientas de análisis

Dive - analiza layers de la imagen

# Dive - analiza layers de la imagen
dive myapp:latest

# Container-diff - compara imágenes
container-diff diff daemon://myapp:old daemon://myapp:new
  1. Usa npm ci en lugar de npm install (más rápido y determinístico)
  2. Limpia cache después de instalar dependencias
  3. Ejecuta como non-root con USER node
  4. Usa tini como init process para manejar signals correctamente
  5. Pin versions de imágenes base (node:18.19.0-alpine)

Conclusión

Con estas técnicas, puedes reducir tus imágenes Docker de Node.js significativamente, mejorando tiempos de deploy y reduciendo costos. El tamaño importa.

¿Qué otras técnicas usas para optimizar imágenes Docker?

¿Te gustó este artículo?

Suscríbete para recibir más contenido sobre desarrollo web y programación

Contáctame