Guía de Instalación
en VPS

Paso a paso para desplegar OpusSuite en un servidor Ubuntu con MySQL, Nginx y PM2.

Ubuntu 22.04 / 24.04 MySQL 8.0 Node.js 20 LTS Nginx + SSL PM2
⚠️
Sobre PHP y Python en tu VPS
OpusSuite está construido con Node.js (NestJS + Next.js), no con PHP ni Python. Esto no es un problema: Node.js coexiste perfectamente con PHP y Python en el mismo VPS. Tu instalación de PHP/Python no se toca ni se modifica. Solo necesitas instalar Node.js 20 y Redis, todo lo demás (MySQL, Nginx) ya lo tienes.

Contenido de esta guía

00 — Requisitos

Antes de empezar

Verifica que tienes todo esto antes de ejecutar el instalador.

Servidor

ComponenteMínimoRecomendadoNotas
SOUbuntu 22.04Ubuntu 24.04LTS obligatorio
RAM2 GB4 GBPara compilar Next.js
CPU1 vCPU2 vCPUPM2 cluster mode
Disco20 GB SSD40 GB SSDPara fotos / uploads
MySQL8.0+8.0+Ya instalado ✓
Nginx1.18+1.18+Ya instalado ✓
Node.js20 LTSEl instalador lo instala
Redis7.0+El instalador lo instala

Acceso necesario

💡
Analogía fotográfica
Piensa en el VPS como tu estudio físico. MySQL es el archivador de fotos que ya tienes. Node.js es una nueva cámara que vas a instalar: no reemplaza nada de lo que tienes, simplemente se añade al equipo.
01 — Stack

Qué se instalará

El instalador configurará estos componentes. Los que ya tienes no se modifican.

⚙️
Node.js 20 LTS
Motor de ejecución
🗄️
MySQL 8
Ya instalado ✓
Redis 7
Caché + colas
🌐
Nginx
Ya instalado ✓
🔒
Let's Encrypt
SSL gratuito
🔄
PM2
Gestor de procesos

Arquitectura en producción

Flujo de peticiones
Internet (usuario / navegador)
        ↓  HTTPS :443
    Nginx (reverse proxy + SSL termination)
       ↙                    ↘
Next.js :3000        NestJS :3001
(Frontend UI)           (Backend API)
                            ↓
                  MySQL :3306   Redis :6379

Los puertos 3000, 3001, 3306 y 6379 son
internos al servidor — NO expuestos a internet.
02 — Transferencia

Subir el paquete al VPS

Desde tu computadora local, sube el archivo opussuite.tar.gz al servidor.

Opción A — SCP (recomendado)

Terminal local
# Subir el archivo
scp opussuite.tar.gz root@IP_DE_TU_VPS:/var/www/

# Conectarse por SSH
ssh root@IP_DE_TU_VPS

Opción B — Panel de Hosting (FileZilla / SFTP)

Descomprimir en el servidor

SSH en el VPS (como root)
# Ir a /var/www
cd /var/www

# Descomprimir
tar -xzf opussuite.tar.gz

# Verificar la estructura
ls -la opussuite/
# Debes ver: backend/ frontend/ nginx/ scripts/ README.md

# Dar permisos de ejecución a los scripts
chmod +x /var/www/opussuite/scripts/*.sh
03 — Instalación

Ejecutar el instalador automático

Un solo comando instala todo. El script es interactivo y te pedirá la información necesaria.

⚠️
Asegúrate de que tu dominio ya apunta al VPS
El instalador configurará SSL con Let's Encrypt. Para que funcione, el DNS del dominio debe apuntar a la IP del VPS ANTES de ejecutar el script. Espera 5-10 minutos tras cambiar el DNS.
SSH en el VPS — ejecutar como root
sudo bash /var/www/opussuite/scripts/install.sh

El instalador te preguntará:

01

Contraseña para el usuario MySQL opussuite

Se creará un usuario MySQL dedicado para la app. Usa una contraseña fuerte y guárdala.

02

Dominio del servidor

Ej: studio.tuempresa.com — debe estar ya apuntando a este VPS.

03

Email para SSL

Let's Encrypt lo usará para notificarte antes de que expire el certificado (90 días).

Lo que hace el instalador automáticamente:

⏱ Tiempo estimado: 10–20 minutos (dependiendo de la velocidad del VPS y la conexión a npm)

04 — Variables de entorno

Configurar servicios externos

El instalador crea el archivo /var/www/opussuite/backend/.env con los valores base. Debes añadir las claves de los servicios externos.

Editar el archivo .env
nano /var/www/opussuite/backend/.env

Variables que debes añadir manualmente:

/var/www/opussuite/backend/.env — sección servicios
# ── EMAIL (Resend — https://resend.com, plan gratuito 3000/mes)
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxx
EMAIL_FROM=noreply@tudominio.com

# ── STRIPE (https://stripe.com/es)
STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxxxxxx
STRIPE_PUBLISHABLE_KEY=pk_live_xxxxxxxxxxxxxxxxxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxx

# ── ALMACENAMIENTO (Cloudflare R2 — gratis hasta 10GB/mes)
STORAGE_PROVIDER=r2
R2_ACCOUNT_ID=tu_account_id
R2_ACCESS_KEY_ID=tu_access_key
R2_SECRET_ACCESS_KEY=tu_secret
R2_BUCKET_NAME=opussuite-assets
R2_PUBLIC_URL=https://assets.tudominio.com

# ── WEB PUSH (genera las claves en el siguiente paso)
VAPID_PUBLIC_KEY=Bxxx...
VAPID_PRIVATE_KEY=xxx...

Generar claves VAPID (Web Push)

En el VPS
npx web-push generate-vapid-keys
# Copia las dos claves generadas en el .env

Alternativa: almacenamiento local (sin Cloudflare)

Si prefieres guardar las fotos en el propio VPS (más simple, pero sin CDN):

.env — almacenamiento local
STORAGE_PROVIDER=local
LOCAL_STORAGE_PATH=/var/www/opussuite/uploads
LOCAL_STORAGE_URL=https://tudominio.com/uploads

Guardar y reiniciar

Tras editar el .env
# Guardar en nano: Ctrl+O, Enter, Ctrl+X

# Reiniciar la aplicación para aplicar los cambios
pm2 restart all

# Verificar que todo arrancó bien
pm2 status
05 — DNS

Configurar DNS y dominio

Desde el panel de tu registrador de dominio (Namecheap, GoDaddy, Cloudflare, etc.):

TipoNombreValorTTL
A@ (raíz)IP del VPS300
AwwwIP del VPS300
AassetsIP del VPS o CF R2300
Propagación DNS
Los cambios DNS tardan entre 5 minutos y 24 horas en propagarse mundialmente. Puedes verificar en dnschecker.org. Para Let's Encrypt solo necesitas que el dominio resuelva correctamente.
06 — Verificación

Verificar que todo funciona

Comprobaciones rápidas

En el VPS
# 1. Estado de los procesos PM2
pm2 status
# Debes ver: opussuite-api (online) y opussuite-web (online)

# 2. Verificar backend responde
curl http://localhost:3001/api/v1/health
# Respuesta esperada: {"status":"ok","timestamp":"..."}

# 3. Verificar frontend responde
curl -I http://localhost:3000
# Respuesta esperada: HTTP/1.1 200 OK

# 4. Verificar MySQL
mysql -u opussuite -p -e "SHOW TABLES;" opussuite_db
# Debes ver 20+ tablas (User, Organization, Client, Project...)

# 5. Verificar Redis
redis-cli ping
# Respuesta esperada: PONG

# 6. Verificar Nginx
nginx -t
systemctl status nginx

Desde el navegador

Si todo está en verde
Crea tu organización desde la pantalla de registro, configura el nombre del estudio en Ajustes → Organización, y ya puedes empezar a usar OpusSuite.
07 — Mantenimiento

Comandos de mantenimiento

Gestión de procesos (PM2)

PM2 — comandos frecuentes
# Ver estado en tiempo real
pm2 monit

# Ver logs en vivo (Ctrl+C para salir)
pm2 logs opussuite-api   # Backend
pm2 logs opussuite-web   # Frontend

# Reiniciar sin downtime
pm2 reload all

# Reinicio completo
pm2 restart all

# Ver procesos
pm2 list

Backups

Backup manual
# Hacer backup manual ahora
bash /var/www/opussuite/scripts/backup.sh
# Guarda en: /var/backups/opussuite/

# Configurar backup diario automático a las 2am
crontab -e
# Añadir esta línea:
0 2 * * * bash /var/www/opussuite/scripts/backup.sh

Actualizar OpusSuite

Actualización zero-downtime
# Subir nueva versión del paquete, luego:
bash /var/www/opussuite/scripts/update.sh
# Hace backup automático antes de actualizar

SSL — renovación automática

El instalador configura la renovación automática. Para verificar que funciona:

Verificar certificado
certbot renew --dry-run
# Sin errores = renovación automática funcionando

certbot certificates
# Ver fecha de expiración actual
08 — Problemas

Solución de problemas frecuentes

❌ PM2 no inicia / status "errored"

Diagnóstico
pm2 logs opussuite-api --lines 50
# Lee el error específico. Causas comunes:
# - Variables .env faltantes o incorrectas
# - Puerto 3001 ocupado por otro proceso
# - Error de conexión a MySQL o Redis

❌ Error de conexión a MySQL

Verificar MySQL
systemctl status mysql
mysql -u opussuite -p opussuite_db
# Si falla: verificar la contraseña en DATABASE_URL del .env

❌ Nginx 502 Bad Gateway

Verificar nginx y procesos
pm2 status        # Verificar que los procesos están online
pm2 restart all   # Si están stopped/errored, reiniciar
nginx -t          # Verificar configuración Nginx
tail -f /var/log/nginx/opussuite-error.log

❌ El build de Next.js falla por falta de memoria

Aumentar memoria para Node.js
# Crear swap si el VPS tiene poca RAM
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# Volver a compilar
cd /var/www/opussuite/frontend && npm run build

❌ Let's Encrypt falla

Obtener SSL manualmente
# Verificar que el dominio resuelve a este servidor:
dig +short tudominio.com
# Debe mostrar la IP del VPS

# Intentar manualmente:
certbot --nginx -d tudominio.com -d www.tudominio.com
09 — Servicios externos

Registro en servicios externos

Estos servicios tienen plan gratuito suficiente para comenzar.

ServicioPara quéPlan gratisURL
ResendEmails transaccionales 3.000/mesresend.com
Cloudflare R2Almacenamiento fotos 10 GB/mescloudflare.com
StripePagos de clientes 2.9% + 0.30€ por transacciónstripe.com/es
Let's EncryptSSL/HTTPS 100% gratuitoAutomático via Certbot
💡
Costos en Venezuela (contexto bimonetario)
Todos estos servicios son gratuitos hasta cierto volumen. Con un estudio fotográfico típico (hasta 100 clientes activos, 50 GB de fotos), los costos mensuales combinados serían aproximadamente 0–5 USD. Stripe solo cobra cuando procesas pagos.