Saltar al contenido principal

Instalar Dokploy en DigitalOcean

Qué es esto: cómo montamos Dokploy (PaaS self-hosted) en un droplet de DigitalOcean, configurado como si fuera producción. El objetivo era evaluar si puede reemplazar Netlify / Render / Blackbird.

Versiones: Dokploy v0.29.12 · Ubuntu 24.04 LTS · Julio 2026


Parte 0 — Crear el droplet

CampoValor
PlanBasic / Shared CPU (Regular SSD)
Tamaño$24/mo — 2 vCPU, 4 GB RAM, 80 GB SSD
RegiónNew York (NYC1)
OSUbuntu 24.04 LTS x64
IP pública143.198.113.169

Por qué Regular y no Premium Intel: al mismo precio, Premium daba 2 GB de RAM contra 4 GB. Con Docker + Traefik + panel + apps, la RAM es el cuello de botella, no el CPU.

Opciones que apagamos y por qué:

OpciónEstadoRazón
Backups automáticosEl droplet del POC es desechable — si falla, se recrea
Managed Database ($15/mo)Dokploy gestiona las BD como contenedores; pagar esto iría contra el objetivo de reducir costos
Improved Metrics (Free)Gráficas de CPU/RAM/disco para ver si 4 GB aguantan

Autenticación: password de root. El acceso habitual es por DigitalOcean Web Console (Droplet → Access → Launch Console), que funciona aunque se pierda la password. Se puede migrar a SSH keys después sin recrear el droplet.

Costo backups (referencia para producción): Weekly $4.80/mo (retención 28 días) · Daily $7.20/mo (7 días). Se activan cuando se quiera, sin recrear nada.


Parte 1 — Preparar el servidor

Acceso por Web Console como root. Si sale droplet-agent is not running, esperar 1–3 min y darle Reload (normal en droplet nuevo).

Zona horaria: se deja en UTC (estándar en servidores multi-proyecto; evita líos con horario de verano y cron). Cada app maneja su offset con la variable TZ.

Problema al hacer apt update — error de llave GPG:

NO_PUBKEY 77B79B3FFAF7EF65

Es una rotación de llave del lado de DigitalOcean (solo afecta al repo del Metrics Agent, no a los de Ubuntu). Se arregla con el script oficial, que limpia las fuentes viejas y reinstala la llave correcta:

curl -sSL https://repos.insights.digitalocean.com/install.sh | sudo bash
systemctl status do-agent # debe decir: active (running)

Después, actualizar el sistema:

apt update && apt upgrade -y

Parte 2 — Instalar Dokploy

Dokploy necesita los puertos 80, 443 y 3000 libres:

ss -tulnp | grep -E ':80 |:443 |:3000 '   # salida vacía = libres ✅

Instalación (script oficial, idempotente y reproducible):

curl -sSL https://dokploy.com/install.sh | sh

⚠️ El script corre docker swarm leave --force al inicio. Nunca correrlo en un servidor con Docker Swarm en producción.

Qué instala:

ComponenteRol
Docker + SwarmMotor de contenedores
dokploy v0.29.12Panel web
dokploy-postgres (PostgreSQL 16)BD interna del panel
dokploy-traefik (Traefik v3.6.7)Reverse proxy + SSL automático

Verificar:

docker service ls        # dokploy y dokploy-postgres en 1/1
docker ps | grep traefik # traefik Up, puertos 80/443

Crear la cuenta admin: abrir http://143.198.113.169:3000 → pantalla "Setup the server" → llenar los datos.

  • Usar correo de empresa (recuperable a nivel organización, no atado a una persona).
  • Dokploy cierra el registro tras el primer usuario. Registrarse de inmediato — hasta entonces el panel está expuesto sin protección.

Parte 3 — Dominio y SSL

Dominio: inmersys.dev (Namecheap) · Subdominio del panel: panel.inmersys.dev

1. Registro DNS (Namecheap → Advanced DNS → Add New Record):

TypeHostValue
A Recordpanel143.198.113.169

2. Verificar propagación (desde el droplet, que es lo que Let's Encrypt contacta):

dig +short panel.inmersys.dev   # → 143.198.113.169 ✅

⚠️ No continuar hasta que el DNS resuelva. Si se pide el certificado antes, Let's Encrypt falla.

Los dominios .dev están en la lista HSTS de Google: los navegadores fuerzan HTTPS. Sin SSL válido, el dominio no carga. En .dev el SSL no es opcional.

3. Configurar en Dokploy (Settings → Web Server → Server Domain):

CampoValor
Domainpanel.inmersys.dev
Let's Encrypt Emaildeveloper@inmersys.com
HTTPS
Certificate ProviderLet's Encrypt

3.5 Problema encontrado: certificado ACME no se emitió al primer intento

Error en los logs de Traefik (docker logs --tail 50 dokploy-traefik):

ERR Unable to obtain ACME certificate ... error: 404 ... Certificate not found

No era fallo de DNS (ya propagaba, y el puerto 80 respondía con un 308 correcto). El estado de ACME quedó atorado con una solicitud fallida. Solución:

rm -f /etc/dokploy/traefik/dynamic/acme.json
docker restart dokploy-traefik
docker logs --since 5m dokploy-traefik # observar el reintento

⚠️ Rate limit de Let's Encrypt: ~5 fallos por hora por dominio. No repetir esto varias veces seguidas o el dominio queda bloqueado una hora.

Resultado: certificado emitido, panel en https://panel.inmersys.dev con SSL válido y renovación automática.


Pendientes para producción

Hardening

Cerrar el puerto 3000 (el panel sigue accesible por http://IP:3000 sin cifrar). Una vez confirmado que el dominio HTTPS carga bien:

docker service update --publish-rm "published=3000,target=3000,mode=host" dokploy

Otros pendientes: firewall (abrir solo 22, 80, 443), fail2ban, migrar de password a SSH keys.

Al migrar a producción real

ÍtemDecisión
DropletSubir a $48/mo (4 vCPU, 8 GB RAM)
BackupsActivar (Weekly $4.80/mo alcanza)

⚠️ Hallazgo para la evaluación

Dokploy no tiene "Netlify Drop" (arrastrar una carpeta dist/). Todos los métodos parten de un repo Git o una imagen Docker. Es una diferencia real frente a Netlify a considerar en la comparativa. (Sí hay subida de .zip, ver Desplegar con .zip.)