Despliegue
Hay dos formas de desplegar. La configuración actual del repositorio (vercel.json) usa la opción A.
Opción A: todo en Vercel (recomendada)
Frontend estático y API como función serverless en el mismo dominio.
{
"version": 2,
"builds": [
{ "src": "package.json", "use": "@vercel/static-build", "config": { "distDir": "dist" } },
{ "src": "api/index.js", "use": "@vercel/node" }
],
"rewrites": [
{ "source": "/api/(.*)", "destination": "/api/index.js" },
{ "source": "/(.*)", "destination": "/index.html" }
]
}
buildsSin builds, Vercel convierte cada archivo de api/ en una función serverless (29 en este proyecto). El plan Hobby permite máximo 12 por deploy, y el deploy falla con "No more than 12 Serverless Functions can be added to a Deployment on the Hobby plan". Con builds explícitos, solo api/index.js es función y el resto del código de Express se empaqueta dentro. No agregues functions a este archivo: Vercel no permite usarlo junto con builds.
Con el repo privado, Vercel solo despliega commits cuyo autor de GitHub esté conectado a la cuenta dueña del proyecto (Account Settings → Authentication). Los commits de otras cuentas, o con coautores externos, quedan en Blocked.
Pasos:
- Importa el repositorio en Vercel (detecta Vite).
- Configura las variables del backend y del frontend en Settings → Environment Variables (ver Variables de entorno). Como comparten dominio:
VITE_API_URL=https://<app>.vercel.app/apiCORS_ORIGINpuede quedar vacío o con el mismo dominio.NODE_ENV=productiony no definasPORT(así el pool usa 2 conexiones).
- Despliega y verifica
https://<app>.vercel.app/api/health.
Limitaciones del modo serverless:
- Cada invocación tiene un tiempo máximo (el que asigne Vercel al plan). La sincronización de productos de SIIGO y los correos que se envían después de responder pueden cortarse.
- No hay disco persistente: las imágenes deben ir a Supabase Storage.
Opción B: frontend en Vercel + API en Railway o Render
La API corre como proceso Node persistente (node api/src/index.js). Recomendado si la sincronización de SIIGO tarda más de 30 s.
| Plataforma | Archivo | Notas |
|---|---|---|
| Railway | railway.toml | Build npm install --prefix api, start node api/src/index.js |
| Render | render.yaml | rootDir: api, start node src/index.js, NODE_ENV=production, TZ=America/Bogota |
railway.toml y render.yaml apuntan a /health, pero la API expone el endpoint en /api/health. Actualiza healthcheckPath / healthCheckPath a /api/health o el healthcheck fallará.
En el frontend configura VITE_API_URL=https://<api>/api y en la API CORS_ORIGIN=https://<app>.vercel.app.
Base de datos (Supabase)
- Crea el proyecto y copia la cadena de conexión en modo Session / directa (puerto 5432).
- Define
DATABASE_URLy correnpm run migratedesde tu máquina (leeapi/.env). - Deja RLS deshabilitado: la API controla el acceso.
- Crea el bucket
product-imagescomo público y genera las claves S3 (Storage → S3 Connection).
Checklist
-
NODE_ENV=production -
JWT_SECRETyJWT_REFRESH_SECRETrobustos y distintos -
DATABASE_URLválida y migraciones aplicadas - Claves S3 de Supabase y bucket público
-
VITE_API_URLapunta a/apidel backend correcto -
CORS_ORIGINincluye el dominio del frontend (si están en dominios distintos) - SMTP y
ADMIN_NOTIFICATION_EMAILsi se quieren correos - Credenciales SIIGO cargadas desde
/admin/integracionesytest-connectionOK -
siigo_seller_iden los asesores oSIIGO_DEFAULT_SELLER_ID -
GET /api/healthrespondedb: connected