Docker en Produccion: Lo que Nadie te Ensena
Usar Docker en desarrollo es facil. Usarlo en produccion de forma segura y eficiente requiere conocimientos especificos que muchos cursos ignoran. En esta leccion cubrimos las practicas que separan a un DevOps junior de un senior.
Seguridad de Contenedores
| Practica | Que hacer | Por que |
|---|---|---|
| No correr como root | USER node en Dockerfile | Limita el impacto de una vulnerabilidad |
| Imagenes minimas | Usar alpine o distroless | Menos superficie de ataque |
| Escanear vulnerabilidades | docker scout, trivy, snyk | Detectar CVEs conocidos |
| Secretos | Docker secrets o vault, NUNCA ENV | ENV visibles en docker inspect |
| Read-only filesystem | read_only: true en compose | Previene modificaciones maliciosas |
# Dockerfile seguro para produccion
FROM node:20-alpine AS builder
RUN apk add --no-cache dumb-init
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
RUN npm run build
FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=builder /usr/bin/dumb-init /usr/bin/dumb-init
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]🚀 Dato Clave
Usa dumb-init o tini como init system. Sin el, tu proceso Node.js no maneja signals correctamente (SIGTERM) y Kubernetes tardara 30 segundos en matar el pod en lugar de hacer graceful shutdown.
Optimizacion de Imagenes
# .dockerignore - SIEMPRE incluir
node_modules
.git
.env*
*.md
tests/
coverage/
.next/
dist/| Base Image | Tamano | Uso |
|---|---|---|
| node:20 | ~1.1 GB | Solo desarrollo |
| node:20-slim | ~250 MB | Produccion basica |
| node:20-alpine | ~180 MB | Produccion optimizada |
| distroless | ~130 MB | Maxima seguridad |
Logging y Monitoreo
En produccion, los logs de Docker deben ir a un sistema centralizado. Nunca dependas solo de docker logs.
# docker-compose con logging centralizado
services:
app:
logging:
driver: 'json-file'
options:
max-size: '10m'
max-file: '3'
tag: '{{.Name}}'Con estas practicas, tus contenedores estan listos para produccion real.