Skip to content

Despliegue con Dokploy

Esta guía cubre el despliegue completo de Vitality Gym usando Dokploy, incluyendo todos los servicios: Backend (API), Frontend (App), Base de Datos (PostgreSQL), Cache (Redis), y Email (BillionMail).

  • VPS con mínimo 2GB RAM, 2 CPU, 40GB SSD
  • Dominio configurado (ej: vitality-gym.com)
  • Dokploy instalado en el servidor
Terminal window
curl -sSL https://dokploy.com/install.sh | sh

Accede al panel en http://tu-ip:3000 y configura tu cuenta admin.

Los siguientes puertos son utilizados por los servicios:

PuertoServicioDescripción
3000APIBackend Hono/Bun
4321AppFrontend Astro
5432PostgreSQLBase de datos
6379RedisCache
25, 587, 993BillionMailSMTP/IMAP
Terminal window
# Verificar si un puerto está en uso
ss -tulpn | grep :3000
# O con netstat
netstat -tulpn | grep :5432
# Ver todos los puertos en uso
ss -tulpn | grep LISTEN

graph TB
subgraph Dokploy
subgraph Project["Proyecto: vitality-gym"]
DB[(PostgreSQL 17)]
Redis[(Redis 7)]
API[API - Hono/Bun]
App[Frontend - Astro]
Mail[BillionMail]
end
end
Internet --> Traefik
Traefik --> App
Traefik --> API
Traefik --> Mail
API --> DB
API --> Redis
API --> Mail

  1. En Dokploy, ir a ProjectsCreate Project
  2. Nombre: vitality-gym
  3. Descripción: Sistema de gestión de gimnasio

  1. Dentro del proyecto, click en Create ServiceDatabasePostgreSQL

  2. Configurar:

    • Name: database
    • Image: postgres:17
    • Database Name: vitality_db
    • Username: vitality_user
    • Password: (genera una contraseña segura)
  3. En AdvancedVolumes, agregar:

    /var/lib/postgresql/data → vitality-db-data
  4. En Environment, agregar:

    Terminal window
    TZ=America/Bogota
  5. Click Deploy


  1. Create ServiceDatabaseRedis

  2. Configurar:

    • Name: redis
    • Image: redis:7
  3. En AdvancedVolumes:

    /data → vitality-redis-data
  4. Click Deploy


  1. Create ServiceCompose
  2. Nombre: billionmail
  3. Pegar la configuración de BillionMail según su documentación
  4. Configurar los dominios y DNS records

Una vez configurado, tendrás credenciales SMTP:

Terminal window
SMTP_HOST=mail.vitality-gym.com
SMTP_PORT=587
SMTP_USER=noreply@vitality-gym.com
SMTP_PASS=tu_password_smtp

  1. Create ServiceApplication

  2. Configurar:

    • Name: api
    • Source: GitHub
    • Repository: tu repositorio
    • Branch: main
    • Build Type: Dockerfile
    • Dockerfile Path: packages/api/Dockerfile
  3. En Domains, agregar:

    • Domain: api.vitality-gym.com (o testing.api.vitality-gym.com para staging)
    • HTTPS: Enabled (Let’s Encrypt)
  4. En Ports:

    • Container Port: 3000
    • Scheme: https

En la pestaña Environment, configura:

Terminal window
# Core
NODE_ENV=production
PORT=3000
DATABASE_URL=postgresql://vitality_user:PASSWORD@database:5432/vitality_db
AUTH_SECRET=genera_un_secret_seguro_de_32_chars
# Redis
REDIS_URL=redis://redis:6379
# URLs (usar testing.* para staging)
FRONTEND_URL=https://app.vitality-gym.com # o https://testing.app.vitality-gym.com
BACKEND_URL=https://api.vitality-gym.com # o https://testing.api.vitality-gym.com
CORS_ORIGINS=https://app.vitality-gym.com,https://vitality-gym.com,https://testing.app.vitality-gym.com
# Email (BillionMail)
SMTP_HOST=mail.vitality-gym.com
SMTP_PORT=587
SMTP_USER=noreply@vitality-gym.com
SMTP_PASS=tu_password_smtp
# Uploads
UPLOAD_DIR=/app/packages/api/uploads

En AdvancedVolumes:

/app/packages/api/uploads → vitality-uploads
  1. Click Deploy

  1. Create ServiceApplication

  2. Configurar:

    • Name: app
    • Source: GitHub (mismo repositorio)
    • Branch: main
    • Build Type: Dockerfile
    • Dockerfile Path: packages/app/Dockerfile
  3. En Build Arguments:

    Terminal window
    BACKEND_URL=https://api.vitality-gym.com # o https://testing.api.vitality-gym.com
  4. En Domains, agregar:

    • Domain: app.vitality-gym.com (o testing.app.vitality-gym.com para staging)
    • HTTPS: Enabled
  5. En Ports:

    • Container Port: 4321
    • Scheme: https
  6. Click Deploy


Paso 7: Migraciones y Seed de Base de Datos

Section titled “Paso 7: Migraciones y Seed de Base de Datos”

Después de que el API esté desplegado, accede a la terminal del contenedor:

Terminal window
# En Dokploy: Service → api → Terminal
cd /app
bunx prisma migrate deploy --schema=./packages/database/prisma/schema.prisma

O desde tu máquina local con la DATABASE_URL de producción:

Terminal window
DATABASE_URL="postgresql://user:pass@host:5432/db" bunx prisma migrate deploy

Cuando realices cambios en el schema.prisma después de que la aplicación ya esté en producción, sigue estos pasos para actualizar la base de datos sin perder datos:

  1. Generar la migración localmente:

    Terminal window
    # En la raíz del proyecto
    bun run db:migrate --name nombre_de_tu_migración

    Esto creará una nueva carpeta en packages/database/prisma/migrations.

  2. Subir los cambios al repositorio: Haz commit y push de los nuevos archivos de migración.

  3. Desplegar la nueva versión del API: Dokploy detectará el cambio y reconstruirá el contenedor del API.

  4. Aplicar la migración en producción: Una vez que el nuevo contenedor esté corriendo, usa la terminal de Dokploy en el servicio api:

    Terminal window
    bunx prisma migrate deploy --schema=./packages/database/prisma/schema.prisma
Terminal window
# En el contenedor de API
bun run packages/database/seed.ts

Configura los siguientes registros DNS en tu proveedor:

TipoNombreValor
A@IP del servidor
AapiIP del servidor
AappIP del servidor
AdocsIP del servidor
Atesting.apiIP del servidor
Atesting.appIP del servidor
CNAMEwwwvitality-gym.com

Para BillionMail, agrega también los registros MX, SPF, DKIM y DMARC según su documentación.


  • API responde en https://api.vitality-gym.com/health (o testing.api.*)
  • Frontend carga en https://app.vitality-gym.com (o testing.app.*)
  • Login con email funciona
  • Login con Google funciona (si está configurado)
  • Envío de emails funciona (reset password)
  • Uploads de archivos funcionan
  • Pagos con Wompi funcionan (usar sandbox primero)
  • Push notifications funcionan
Terminal window
# Ver logs del API
dokploy logs api --follow
# Reiniciar servicio
dokploy restart api
# Acceder a terminal
dokploy exec api sh

En el panel de Wompi, configura:

  • Producción: https://api.vitality-gym.com/api/v1/payments/webhook
  • Staging: https://testing.api.vitality-gym.com/api/v1/payments/webhook
  • Evento: transaction.updated

Terminal window
# Verificar conexión desde API
bun -e "console.log(await fetch('http://localhost:3000/health').then(r=>r.json()))"
# Verificar PostgreSQL
psql postgresql://user:pass@database:5432/vitality_db -c "SELECT 1"

Terminal window
# Backup manual
docker exec -t vitality-database pg_dumpall -c -U vitality_user > backup_$(date +%Y%m%d).sql
# Restaurar
cat backup.sql | docker exec -i vitality-database psql -U vitality_user
  1. Ir a SettingsBackups
  2. Configurar destino (S3, local, etc.)
  3. Programar backups diarios

Para alto tráfico, considera:

  • Horizontal Scaling: Múltiples instancias del API con load balancer
  • PgBouncer: Connection pooling para PostgreSQL
  • Redis Cluster: Para alta disponibilidad del cache
  • CDN: CloudFlare o similar para assets estáticos

Variables Requeridas

VariableServicioDescripción
DATABASE_URLAPIConexión PostgreSQL
AUTH_SECRETAPISecret para JWT (32+ chars)
REDIS_URLAPIConexión Redis
SMTP_*APICredenciales email
FRONTEND_URLAPIURL del frontend
BACKEND_URLAPI, AppURL del backend
CORS_ORIGINSAPIOrígenes permitidos
GOOGLE_CLIENT_*APIOAuth de Google
UPLOAD_DIRAPIDirectorio de uploads
WOMPI_*APIPasarela de pagos
VAPID_*APIPush notifications