Saltar al contenido principal

El problema de los builds

Leer antes de escalar Dokploy a más proyectos. Por qué construir en el mismo servidor que corre producción es riesgoso, y la solución con CI/registry.


El aviso del panel

"Builders can consume significant memory and CPU resources (recommended: 4+ GB RAM and 2+ CPU cores)."

La doc oficial es más explícita: los recursos de un build pueden provocar un timeout o congelar el servidor, dejando todas las apps caídas.

De dónde viene

Son dos costos distintos:

RAM
Correr una API Node~60 MB
Construir una imagen con Nixpacks1 – 2 GB de pico

El servidor hace las dos cosas a la vez: mientras compila, sigue corriendo todo lo demás.

Presupuesto real de un droplet de 4 GB:

RAM total                        3.8 GB
Dokploy (control plane) 0.9 GB ← el mayor consumidor
Postgres + Traefik + SO ~0.6 GB
────────────────────────────────────────
Disponible para construir ~2.2 GB

Un build pide 1-2 GB. Cabe, pero el margen es de cientos de MB — y se encoge conforme se agregan apps.

Qué pasa cuando no alcanza

El kernel invoca al OOM killer, que no es selectivo: mata al proceso que más memoria consuma. Puede ser Dokploy (pierdes el panel) o una API en producción.

El deploy no falla limpiamente. Tumba lo que ya estaba corriendo. En lenguaje de negocio:

Un deploy de un cliente puede tirar el sitio de otro cliente.

Lo que NO es el problema

  • No son los builds simultáneos. Dokploy usa una cola por servidor, concurrencia 1 por default. Tres push a la vez → se encolan uno por uno.
  • Tampoco las apps corriendo. Un estático servido por NGINX consume ~3 MB. Decenas de apps caben sin problema.

Es UN SOLO build compitiendo contra el poco espacio que dejan las apps encendidas.


Mitigaciones

Nivel 1 — Límites por app (ya aplicado)

Evita que una app con memory leak se coma todo. Protege el runtime, no el build — Dokploy no permite limitar los recursos del proceso de build.

Nivel 2 — Swap

Un colchón en disco para cuando la RAM se agota. El build se vuelve lento, pero no mata contenedores vivos:

free -h   # si Swap: 0B, no hay red de seguridad

fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
sysctl vm.swappiness=10
echo 'vm.swappiness=10' >> /etc/sysctl.conf

El swap no es más RAM. Vive en disco, es mucho más lento. Es un extintor, no un aire acondicionado. Si las apps en reposo viven en swap, hace falta un servidor más grande. (No está en la doc de Dokploy — es práctica estándar de Linux.)

Nivel 3 — Que el servidor no construya (la solución real)

Lo que recomienda la doc oficial: construir la imagen en CI/CD y publicarla en un registry. El servidor solo la descarga y la corre.

HOY:      GitLab → Dokploy CONSTRUYE en el servidor 🔥 → corre
PROPUESTA: GitLab → CI CONSTRUYE la imagen → registry
└─► Dokploy solo DESCARGA y corre ✅

Un docker pull es descarga de red: consumo de RAM ≈ 0.


Costos de la solución (Inmersys)

PiezaCosto
Dokploy self-hosted$0
GitLab Container Registry$0 — no cuenta para el límite de 10 GiB
Escribir el .gitlab-ci.yml$0
Pipeline en shared runners de GitLab400 min/mes gratis, luego Premium
Pipeline en runner self-hosted$0 — minutos ilimitados

El cálculo que decide todo:

5 devs × 5 deploys/día × 20 días = 500 builds/mes
500 builds × ~4 min = 2,000 minutos
Presupuesto gratuito = 400 minutos

Los shared runners no escalan a este volumen. La salida sin costo es un GitLab Runner self-hosted (GitLab no cobra minutos por runners propios).

Dónde ponerlo:

OpciónCostoNota
Droplet de DEV (ya se paga)$0Si un build satura dev, producción no se entera. Recomendado
Droplet dedicado de $12 (2 GB)$12/mesLo más limpio. El de $4 (512 MB) NO sirve: OOM garantizado

Un solo runner construye todo. Lo que cambia por rama es el tag y a qué app se le avisa:

push a develop → imagen :develop → app DEV
push a main → imagen :latest → app PROD

El runner puede vivir en el droplet de dev y aun así construir las imágenes de producción. Prod solo hace pull, nunca compila, nunca se cae por un deploy.


Resumen

Problema: Dokploy construye (1-2 GB de golpe) y corre (60 MB) en el mismo servidor. Al crecer las apps, la RAM libre se encoge hasta que un deploy ya no cabe — y cuando pasa, tumba las apps en producción.

Solución: que GitLab construya la imagen y el servidor solo la corra. Costo: $0 adicionales (runner self-hosted en el droplet de dev que ya se paga).