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.
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
- Usa npm ci en lugar de npm install (más rápido y determinístico)
- Limpia cache después de instalar dependencias
- Ejecuta como non-root con USER node
- Usa tini como init process para manejar signals correctamente
- 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