# Despliegue en Coolify — Moraworld Imports > **TL;DR** — Coolify gestiona Postgres + Redis. Solo necesitas el repo, `coolify-compose.yml` y las variables de `.env.example`. --- ## 1️⃣ Requisitos previos - Servidor con **Docker 24+** y **Coolify** instalado (`curl -fsSL https://get.coolify.io | bash`) - Dominio propio con DNS apuntando al servidor (A/AAAA + wildcard `*.tu-dominio.com`) - Cuenta GitHub/GitLab con el repo clonado --- ## 2️⃣ Crear Project en Coolify 1. **Projects → New Project** → nombre: `moraworld-imports` 2. **Resources → New → Docker Compose** - **Repository**: `https://github.com/lizandrogd/moraworld-imports` - **Branch**: `main` - **Compose file**: `coolify-compose.yml` - **Build pack**: `Dockerfile` (auto-detectado) --- ## 3️⃣ Servicios gestionados (managed services) En el projecto → **Services → Add Service**: | Servicio | Tipo | Nombre lógico | Notas | |----------|------|---------------|-------| | **PostgreSQL** | `PostgreSQL 16` | `postgres` | Coolify inyecta `DATABASE_URL` | | **Redis** | `Redis 7` | `redis` | Coolify inyecta `REDIS_URL` | | **MinIO** (opcional) | `MinIO` | `minio` | Solo si no usas S3 externo; expón puertos 9000/9001 | > **Importante**: Los nombres lógicos (`postgres`, `redis`) deben coincidir con los hostnames usados en `DATABASE_URL`/`REDIS_URL` si los escribes a mano. Coolify los resuelve automáticamente. --- ## 4️⃣ Variables de entorno En **Project → Environment Variables**, añade **una por una** (no pegues el bloque completo): | Variable | Ejemplo / Generación | |----------|----------------------| | `NODE_ENV` | `production` | | `NEXT_PUBLIC_API_URL` | `https://api.tu-dominio.com` | | `NEXT_PUBLIC_WS_URL` | `https://api.tu-dominio.com` | | `JWT_SECRET` | `openssl rand -base64 48` | | `JWT_REFRESH_SECRET` | `openssl rand -base64 48` (distinto) | | `AUDIT_HMAC_SECRET` | `openssl rand -hex 32` | | `CORS_ORIGINS` | `https://app.tu-dominio.com,https://www.tu-dominio.com` | | `S3_ENDPOINT` | `https://s3.tu-proveedor.com` (o vacío para disco local) | | `S3_ACCESS_KEY` | `minioadmin` | | `S3_SECRET_KEY` | `minioadmin` | | `S3_BUCKET` | `moraworld-imports` | | `S3_REGION` | `us-east-1` | | `S3_PUBLIC_URL` | `https://cdn.tu-dominio.com` | | `STRIPE_WEBHOOK_SECRET` | `whsec_...` (de Stripe Dashboard) | > **No pongas** claves de Zeptomail, SENAE, Amazon, Twilio, WhatsApp, etc. aquí. Se configuran en **Admin → Integraciones** tras el primer deploy. --- ## 5️⃣ Dominios y TLS En **Project → Domains** añade: | Dominio | Servicio | Puerto | TLS | |---------|----------|--------|-----| | `api.tu-dominio.com` | `api` | `3001` | ✅ Auto | | `app.tu-dominio.com` | `web` | `3000` | ✅ Auto | | `ws.tu-dominio.com` | `api` | `3001` | ✅ Auto (WebSocket) | Coolify genera certificados Let's Encrypt automáticos y renueva cada 60 días. > **WebSocket**: el gateway corre en `/ws` bajo el mismo puerto 3001. El dominio `ws.tu-dominio.com` apunta al mismo servicio `api`. --- ## 6️⃣ Health Checks Coolify usa los health checks del `docker-compose` para saber cuándo el servicio está listo: - **API**: `GET http://localhost:3001/api/health` → 200 OK - **Web**: `GET http://localhost:3000/status` → 200 OK (crea `apps/web/public/status.txt` con `ok` si no existe) Si el health check falla, Coolify reintenta según `retries` y `start_period`. --- ## 7️⃣ Primer deploy y post-configuración 1. **Deploy** → espera a que ambos servicios estén "Healthy" 2. Entra a `https://app.tu-dominio.com` 3. Regístrate (primer usuario = `SUPER_ADMIN` automático si BD vacía) 4. Ve a **Admin → Configuración → Integraciones** y guarda: - **Zeptomail**: `zeptomail_api_key`, `email_from`, `email_from_name` - **SENAE**: `senae_endpoint`, `senae_api_key`, `senae_ruc`, `senae_agent_code` - **Stripe**: `stripe_public_key`, `stripe_secret_key`, `stripe_webhook_secret` - **Amazon SP-API**: `amazon_client_id`, `amazon_client_secret`, `amazon_refresh_token` - **Twilio SMS**: `sms_account_sid`, `sms_auth_token`, `sms_from_number` - **WhatsApp Business**: `whatsapp_api_token`, `whatsapp_phone_number_id` - **Couriers** (FedEx/DHL/UPS), **INEN**, **Bodega**, etc. según necesites 5. **Stripe Webhook** en Dashboard → `https://api.tu-dominio.com/api/payments/webhook?tenant=mi-tenant-slug` - Eventos: `checkout.session.completed`, `checkout.session.expired` --- ## 8️⃣ Actualizaciones **Auto-deploy** (recomendado): - Project → Settings → **Auto Deploy** = ON - Push a `main` → Coolify detecta, build y despliega sin downtime (rolling update) **Manual**: - Project → Deploy → **Force rebuild** si cambiaste Dockerfile o dependencias --- ## 9️⃣ Backups y recuperación - **PostgreSQL**: Coolify → Service `postgres` → Backups → Schedule (diario/semanal) - **Redis**: No crítico (cache/sesiones), pero puedes snapshottear - **MinIO**: Versiona el bucket o replica a otro S3 - **Código**: GitHub es la fuente de verdad Para restaurar: detén servicios → restaura dump SQL → `pnpm prisma db push` → reinicia. --- ## 🔟 Troubleshooting rápido | Síntoma | Causa probable | Solución | |---------|----------------|----------| | API 502 / health fail | `DATABASE_URL` mal formada | Revisa variable; usa hostname `postgres` | | WebSocket no conecta | Dominio `ws.` no apunta a `api` | Añade dominio `ws.tu-dominio.com` → servicio `api` | | CORS error | `CORS_ORIGINS` sin tu frontend | Añade `https://app.tu-dominio.com` | | Stripe webhook 404 | URL mal escrita en Dashboard | Debe ser `/api/payments/webhook?tenant=` | | Prisma migrate fail | `prisma db push` en prod | Usa `prisma migrate deploy` en CI si migras schema | | Uploads 404 | `S3_ENDPOINT` vacío pero archivos en disco | Configura MinIO/S3 o sirve `/uploads` vía reverse proxy | --- ## 📁 Estructura de archivos Coolify ``` moraworld-imports/ ├── coolify-compose.yml # ← Coolify usa este archivo ├── .env.example # ← Copia valores a Coolify UI ├── apps/ │ ├── api/Dockerfile # Multi-stage, standalone node │ └── web/Dockerfile # Next.js standalone output ├── packages/database/ # Prisma schema └── COOLIFY.md # ← Este archivo ``` --- ## 🔐 Secrets management Coolify encripta las variables marcadas como **Secret** en la UI. Para rotar secrets: 1. Genera nuevo valor local 2. Actualiza en Coolify → Environment Variables 3. Redeploy (rolling, cero downtime) --- ## 📊 Monitoring básico - **Logs**: Coolify → Service → Logs (stdout/stderr) - **Metrics**: Coolify → Service → Metrics (CPU, RAM, Network) - **Uptime**: Configura Uptime Kuma / Better Uptime apuntando a `/api/health` y `/status` --- ## 🚀 Checklist pre-producción - [ ] `JWT_SECRET` y `JWT_REFRESH_SECRET` únicos, 48+ chars base64 - [ ] `AUDIT_HMAC_SECRET` 32+ chars hex - [ ] `CORS_ORIGINS` solo tus dominios reales (sin `*`) - [ ] `DATABASE_URL` apunta a Postgres gestionado por Coolify - [ ] `REDIS_URL` apunta a Redis gestionado por Coolify - [ ] Dominios `api.`, `app.`, `ws.` creados en Coolify con TLS - [ ] Health checks pasan en ambos servicios - [ ] Integraciones guardadas en Admin UI - [ ] Stripe webhook registrado y probado - [ ] Backup automático de Postgres configurado --- **¿Problemas?** Revisa logs en Coolify → Service → Logs. La mayoría son variables de entorno mal escritas o health checks que tardan más de `start_period`.