DEV Community

Moon Robert
Moon Robert

Posted on • Originally published at blog.rebalai.com

Docker Compose vs Kubernetes en 2026: Cuándo Usar Cuál (Y Cuándo te Estás Complicando la Vida)

Voy a ser directo: durante el último año cambié de opinión dos veces sobre este tema. Empecé convencido de que Kubernetes era la respuesta correcta para casi todo. Después migré tres proyectos de vuelta a Docker Compose. Y ahora, con la cabeza más fría, creo que puedo darte algo más útil que un vago "depende del caso de uso".

Trabajo con un equipo de cuatro personas. Manejamos una plataforma SaaS con entre 8.000 y 12.000 usuarios activos según el mes, con picos bastante predecibles los martes y jueves. No somos Netflix. Tampoco somos un side project de fin de semana. Estamos exactamente en esa zona gris donde la elección importa de verdad.


Por Qué Docker Compose Llega Más Lejos de lo que la Mayoría Cree

Hay una narrativa muy extendida que dice que Compose es "solo para desarrollo local" y que en cuanto quieres hacer algo serio tienes que saltar a Kubernetes. Eso es, con todo el respeto, una simplificación bastante dañina.

Corrí Docker Compose en producción durante 14 meses. Un VPS de Hetzner, 8 vCPUs, 32 GB de RAM, backups diarios con restic y un nginx actuando de reverse proxy delante de todo. El uptime fue del 99.7%. Los deployments tardaban unos 40 segundos. Y el docker-compose.yml que manejaba todo esto tenía menos de 120 líneas.

# docker-compose.yml (producción, versión simplificada)
services:
  api:
    image: registry.example.com/api:${IMAGE_TAG}
    restart: unless-stopped
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  worker:
    image: registry.example.com/api:${IMAGE_TAG}
    command: ["node", "worker.js"]
    restart: unless-stopped
    depends_on:
      - cache
      - db

  db:
    image: postgres:16.3
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  cache:
    image: redis:7.4-alpine
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:
Enter fullscreen mode Exit fullscreen mode

Nada glamoroso. Pero funcionaba. Los deployments eran docker compose pull && docker compose up -d --no-deps api worker y listo. Cero downtime si lo hacías bien — rolling update manual, sí, pero en 14 meses solo metí la pata una vez. Un viernes por la tarde, cómo no.

Lo que sí me costó: cuando empezamos a necesitar más de una instancia del servicio api, las cosas se pusieron incómodas. Compose no tiene balanceo de carga nativo entre réplicas del mismo servicio de forma que realmente te fíes. Puedes usar --scale api=3 pero entonces tienes que configurar nginx manualmente para distribuir la carga entre los contenedores, y eso se vuelve frágil. Ese fue el primer momento en que empecé a mirar k8s con más interés.

Dicho esto: si tienes una sola máquina, un equipo pequeño y menos de 50.000 usuarios, Compose en producción no es una locura. Es una decisión pragmática perfectamente válida.


El Momento en que Kubernetes Pasa de Solución a Problema

Migré a Kubernetes en octubre del año pasado. Usamos EKS en AWS (en aquel momento con Kubernetes 1.31, aunque ya vamos por 1.33). El razonamiento era sólido: necesitábamos escalar horizontalmente de forma automática, hacer deployments sin downtime con más control, y prepararnos para añadir más servicios sin que la infraestructura se volviera un spaghetti.

Lo que no calculé bien fue el coste de operación.

El clúster mínimo viable en EKS nos salía por unos 180–220 dólares al mes solo en nodos (sin contar el control plane, que en AWS son 70 dólares fijos). Añade el Application Load Balancer, los volúmenes EBS, las transferencias de datos, y llegas fácil a 350–400 dólares al mes solo de infraestructura. En el VPS de Hetzner estábamos pagando 39 euros. La diferencia es significativa cuando eres una startup pequeña.

Pero el coste económico es casi lo de menos. El coste en tiempo de ingeniería fue lo que realmente dolió.

El primer mes post-migración lo pasé — okay, lo pasamos (somos cuatro, pero el tema infra recayó principalmente en mí) — básicamente apagando fuegos de configuración. El cluster RBAC, los secrets con External Secrets Operator porque los nativos de k8s son demasiado básicos, los PodDisruptionBudgets para que los deployments no bajaran el servicio, las NetworkPolicies, los resource limits que había que afinar porque sin ellos un worker se comía toda la memoria del nodo y desalojaba pods de producción...

El error que más me dolió, porque era evitable: estuve dos horas debuggeando por qué un pod se reiniciaba cada 15 minutos. El kubectl describe pod mostraba OOMKilled. Pensé que era un memory leak. Resultó que el límite de memoria del pod era demasiado bajo (512Mi) para un servicio que necesitaba 700Mi en los picos. Lo habría visto antes si hubiera tenido Prometheus + Grafana bien configurados desde el día uno. No los tenía.

No digo que Kubernetes sea malo. Digo que tiene una superficie de configuración enorme que hay que gestionar activamente, y para un equipo pequeño eso tiene un coste real que los tutoriales no mencionan.


Las Diferencias que Importan en 2026: Networking, Secrets y Rollbacks

Pasado el trauma inicial, hay tres áreas donde la comparación entre Compose y k8s no está tan clara como parece.

Networking. En Compose, todos los servicios del mismo fichero comparten una red por defecto y se resuelven por nombre de servicio. Punto. En Kubernetes tienes namespaces, Services de tipo ClusterIP/NodePort/LoadBalancer, Ingress controllers (elige el tuyo: nginx-ingress, Traefik, Cilium Gateway API...), NetworkPolicies opcionales pero recomendadas. Más potencia, más cosas que configurar. Lo que sí te da k8s que Compose no puede igualar: service discovery entre múltiples equipos en el mismo clúster, y routing sofisticado tipo canary releases con Argo Rollouts.

Secrets. Aquí Kubernetes tiene fama de hacer las cosas bien, pero los Secrets nativos son simplemente base64 — no es cifrado. En 2026 ya no tienes excusa para no usar External Secrets Operator con AWS Secrets Manager o HashiCorp Vault, pero eso añade más piezas al puzzle. Con Compose en producción, nosotros pasábamos los secrets como variables de entorno desde un fichero .env que no subíamos al repositorio. Menos elegante, pero funciona y es comprensible al 100%.

Rollbacks. Este es donde Kubernetes gana sin discusión. kubectl rollout undo deployment/api y en 30 segundos estás en la versión anterior. Con Compose, el rollback es docker compose up -d con el tag de imagen anterior — lo cual funciona, pero requiere que tengas ese tag anotado en algún sitio y lo ejecutes manualmente. El domingo a las 3am esto marca la diferencia.


La Sorpresa que No Esperaba: k3s Cambia el Cálculo

Aquí viene la parte que la verdad no había anticipado cuando escribí mi primer draft de este artículo.

A principios de este año empecé a experimentar con k3s — la distribución ligera de Kubernetes de Rancher — en un VPS de Hetzner de 8 vCPUs y 16 GB de RAM. Lo que encontré fue que la experiencia de operación es considerablemente más cercana a Compose de lo que imaginaba. Un solo binario. Control plane y worker en la misma máquina. Incluye Traefik como ingress por defecto, SQLite en lugar de etcd para clústeres pequeños, y el consumo de recursos en idle es sorprendentemente bajo — alrededor de 500MB de RAM para el control plane completo.

El coste: el mismo VPS que usábamos con Compose, a 39 euros al mes, corriendo k3s en nodo único. Y ya tienes kubectl rollout undo, HPA (Horizontal Pod Autoscaler), health checks declarativos, y la posibilidad de añadir nodos workers cuando los necesites.

No estoy 100% seguro de que esto escale bien más allá de dos o tres nodos workers sin empezar a necesitar etcd en alta disponibilidad — que ya es otra conversación. Pero para ese punto dulce entre "Compose se queda corto" y "EKS es demasiado", k3s en 2026 merece estar en la conversación.


El Filtro Real: Las Tres Preguntas que Yo Me Haría

Después de haber migrado proyectos en ambas direcciones, este es el proceso que ahora aplico.

¿Necesitas escalar horizontalmente de forma automática?
Si no — si un servidor bien especificado aguanta tu carga con margen, si tus picos son predecibles y manejables manualmente — entonces Compose. Punto. No te vendas la complejidad de k8s como una inversión en el futuro si ese futuro no existe todavía en tus métricas actuales.

¿Tienes más de un servicio que necesita escalar de forma independiente?
Si la API puede tener diez instancias pero el worker de procesamiento de PDFs solo necesita dos, Kubernetes gestiona esto de forma natural. Con Compose empiezas a hacer malabares con nginx y scripts bash. Si estás en este punto, el salto tiene sentido — pero mira k3s antes de ir directo a EKS o GKE.

¿Tu equipo tiene ancho de banda para aprender y mantener esto? Esta es la que más gente ignora. Kubernetes no es un deployment de un día — es un sistema que requiere atención continua. Los upgrades de versión (k8s depreca APIs con bastante regularidad, mira lo que pasó con PodSecurityPolicy en 1.25), los certificados que caducan, los nodos que necesitan mantenimiento. Si tu equipo de DevOps eres tú solo, o si el backend es un tercio de lo que tu equipo hace, ese tiempo tiene un coste de oportunidad alto que se subestima mucho.

Mi recomendación sin rodeos: menos de 50.000 usuarios activos, equipo de menos de seis personas y un solo servidor o VPS — usa Docker Compose en producción. Si ya se te queda pequeño o necesitas multi-nodo de verdad, prueba k3s antes de comprometerte con EKS. Y si tienes un equipo de plataforma dedicado, múltiples servicios con requisitos de escala distintos y presupuesto para la complejidad operativa, entonces Kubernetes managed tiene todo el sentido.

Nosotros acabamos usando k3s en dos nodos en Hetzner para producción y Docker Compose para todos los entornos de desarrollo y staging. El equipo está contento. Los deployments funcionan. Y yo ya no me despierto pensando en etcd snapshots.

Top comments (0)