Saltar al contenido principal

Registry + Dockerfile (GitLab)

La solución real al problema de los builds y a la gestión de disco: en vez de compilar en el droplet (Nixpacks), se compila en la máquina local y el servidor solo hace pull de una imagen lista. Se evalúa y descarta DOCR a favor de GitLab.


1. El problema

Hoy Dokploy usa Nixpacks: el droplet descarga el código y compila ahí mismo. La doc advierte que un build puede pedir picos de RAM/CPU y tumbar el servidor completo, incluidas las apps sanas.

El servidor de producción no debería compilar nunca. Solo debería encender cosas ya compiladas.


2. Vocabulario: 3 palabras que separar

Imagen ≠ Contenedor:

Qué esDónde vive
ImagenEl paquete congelado: app + Node + dependenciasEn el registry
ContenedorEsa imagen corriendoEn el droplet

Al registry subes imágenes, no contenedores.

Registry ≠ Repositorio ≠ Tag:

registry.gitlab.com / inmersys/clickupapi-back : 1.0.0
└──── registry ────┘ └───── repositorio ─────┘ └tag┘
  • Registry → el servidor, el "Drive" de imágenes.
  • Repositorioel nombre de UNA imagen (no una carpeta con varias cosas — es la imagen).
  • Tag → las versiones (1.0.0, latest).

⚠️ registro/clickup_back y registro/disney_app no son un repo con dos cosas — son dos repositorios distintos. Nombre distinto = repo distinto.


3. Por qué se descarta DOCR

PlanCostoReposStorage
Starter$01500 MiB
Basic$5/mes55 GiB
Professional$20/mesIlimitados100 GiB

Una imagen de Node/Express pesa 200–400 MB. Con el Starter solo cabe 1 proyecto, y 500 MiB se llenan con una sola app. Meter todo en un repo por tag funciona técnicamente, pero ensucia el historial y no esquiva el límite de 500 MiB.

Conclusión: DOCR gratis no da. DOCR útil cuesta ≥ $5/mes. La restricción es $0 adicionales. (La config paso a paso sigue en Registry DigitalOcean por si se paga.)


4. La solución: GitLab Container Registry

GitLab RegistryDOCR Starter
Costo$0$0
RepositoriosIlimitados1
StorageNo cuenta contra el límite de 10 GiB500 MiB
Cuenta nuevaNinguna — ya usas GitLab

El punto crítico — minutos de CI: docker build + docker push desde tu máquina no es un pipeline. Es tu laptop hablando por HTTPS con el registry, igual que subir a un Drive. No consume ni un minuto de los 400 gratis.

Cada proyecto de GitLab trae su registry incluido, mapeo 1:1 con tus repos:

registry.gitlab.com/inmersys/inmersys-clickupapi-back:1.0.0
registry.gitlab.com/inmersys/disney-spiderman-memorama-web:1.0.0

5. Dockerfile ≠ solución (leer con cuidado)

En Dokploy hay tres configuraciones, y solo una resuelve el problema:

Configuración¿Quién compila?¿Sirve?
Git + Build Type NixpacksEl droplet
Git + Build Type DockerfileEl droplet (solo cambia el builder)
Source Type: Docker (imagen ya construida)Tu máquina — el droplet solo hace pull

Cambiar a Dockerfile por sí solo NO te salva — el servidor sigue compilando. Lo que salva es pasar a Source Type: Docker apuntando a una imagen del registry. El Dockerfile es el medio, no el fin.


6. El flujo completo

PasoDóndeConsumo del droplet
docker buildTu máquina
docker pushRed
docker pullDropletCasi nada
Encender el contenedorDropletLo normal de la app

Beneficio extra: lo que probaste localmente es exactamente lo que corre en producción, bit por bit. Hoy con Nixpacks el droplet construye algo que tú nunca viste.


7. Implementación

a) Dockerfile en el repo (ejemplo Express)

FROM node:22-alpine AS base
WORKDIR /app

FROM base AS deps
COPY package*.json ./
RUN npm ci --omit=dev

FROM base AS runner
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 5000
CMD ["node", "src/index.js"]

Node fijo en 22 (no >=22), para no repetir el problema de reproducibilidad de Nixpacks.

b) .dockerignore (obligatorio)

node_modules
.env
.git
dist

⚠️ Nunca metas el .env en la imagen.

c) Token en GitLab

Proyecto → Settings → Access Tokens (o Deploy Tokens). Scopes: read_registry + write_registry.

d) Build + push (desde tu máquina)

docker login registry.gitlab.com -u USUARIO -p TOKEN

docker build \
-t registry.gitlab.com/inmersys/queruva-back:1.0.0 \
-t registry.gitlab.com/inmersys/queruva-back:latest .

docker push --all-tags registry.gitlab.com/inmersys/queruva-back

Doble tag siempre. Si todo se llama latest, la versión anterior queda huérfana y no hay rollback.

e) Registrar el registry en Dokploy

Settings → Registry → URL registry.gitlab.com, tu usuario, y el token (con read_registry basta para el pull). Se hace una vez para todas las apps.

f) Configurar la app

  • Source Type: Docker
  • Imagen: registry.gitlab.com/inmersys/queruva-back:latest
  • Container Port: el real (5000 Express, 80 Vite+nginx)
  • Environment: igual que ahora — las env vars las inyecta Dokploy, no van en la imagen
  • Deploy

g) Rollback

Cambias la imagen a :1.0.0 → Redeploy. Eso es todo.


8. Detalles que muerden

  • Env vars: viven en Dokploy, no en la imagen. La imagen es idéntica en dev y prod; lo que cambia es lo que se le inyecta.
  • Arquitectura: un compañero con Mac M1/M2 genera imágenes arm64 que no arrancan en el droplet. Debe usar docker build --platform linux/amd64 ....
  • Dokploy no se entera solo: tras el push, avísale con el botón Deploy o disparando el Webhook URL con curl (ver Auto-deploy).
  • Vite es distinto: las VITE_* se hornean en build, no se inyectan al encender. Van como --build-arg en el docker build, no como Environment. Puerto 80.

9. El trade-off honesto

Vale $0, pero:

Los deploys dependen de tu máquina. Si estás en junta o de vacaciones y hay un hotfix, alguien más necesita Docker, el token y hacer el build a mano.

Evolución natural (para después): mover estos comandos a un .gitlab-ci.yml — el pendiente de API Express. Como Inmersys usa 2 de 400 minutos/mes, sigue siendo $0 y desaparece la dependencia de la laptop. Pero primero hazlo a mano, para dominar cada pieza.


📖 Relacionado: El problema de los builds · Gestión de disco · Registry DigitalOcean · Providers