CI/CD y Despliegue
Tabla de Contenidos
- Vision General del Pipeline
- Pipeline GitLab CI Completo
- Stages del Pipeline
- Gestion de Secretos con Bitwarden Secrets Manager
- Despliegue con Coolify
- Flujo de Deploy Completo
- Estrategia de Branching
- Migraciones de Base de Datos
- Variables de CI/CD en GitLab
- Troubleshooting
1. Vision General del Pipeline
Nvito utiliza un modelo de CI/CD dividido en dos sistemas complementarios:
- GitLab CI/CD se encarga de la calidad del codigo (lint, tests) y de las migraciones de base de datos cuando hay cambios en el schema de Prisma.
- Coolify se encarga del build Docker y deploy, activado automaticamente via webhooks de GitLab al detectar un push.
GitLab CI valida que el codigo cumple los estandares de calidad y que las migraciones se aplican correctamente. Coolify maneja el ciclo de vida del contenedor Docker (build, health check, rollout). Ambos se disparan en paralelo por el mismo push.
| Repositorio | Pipeline GitLab CI | Deploy Coolify |
|---|---|---|
| nvito-api | quality (lint + test) + migrate | Auto-deploy via webhook |
| nvito-admin | No tiene pipeline CI | Auto-deploy via webhook |
| nvito-invitations | No tiene pipeline CI | Auto-deploy via webhook |
Nota: Los frontends no tienen
.gitlab-ci.yml. Su calidad se valida localmente antes de hacer push.
2. Pipeline GitLab CI Completo
El pipeline de nvito-api consta de dos stages secuenciales con cuatro jobs en total:
El pipeline se ejecuta en dos condiciones: push directo a develop o test, y merge request events.
3. Stages del Pipeline
3.1 Stage: quality
Ejecuta dos jobs en paralelo: lint y test:unit.
Job lint — valida formato y estilo con ESLint y Prettier:
lint:
stage: quality
script:
- npm ci --cache $NPM_CONFIG_CACHE
- npm run lint
- npm run format:check
Job test:unit — ejecuta tests contra una BD PostgreSQL efimera:
test:unit:
stage: quality
services:
- postgres:15-alpine
variables:
POSTGRES_DB: nvito_test
POSTGRES_USER: test
POSTGRES_PASSWORD: test
DATABASE_URL: "postgresql://test:test@postgres:5432/nvito_test"
before_script:
- apk add --no-cache openssl
script:
- npm ci --cache $NPM_CONFIG_CACHE
- npx prisma generate
- npx prisma migrate deploy
- npm run test:ci
- GitLab CI levanta
postgres:15-alpinecomo servicio adjunto; la BD se destruye al terminar. - Se instala
opensslen Alpine porque el migration engine de Prisma lo requiere. - Genera reportes de cobertura (Cobertura + JUnit) almacenados como artifacts por 30 dias.
3.2 Stage: migrate
Aplica migraciones a las BD reales (Neon). Solo se ejecuta cuando hay cambios en prisma/migrations/**/*:
migrate:dev:
stage: migrate
before_script:
- apk add --no-cache curl unzip openssl
- curl -fsSL ".../bws-x86_64-unknown-linux-musl.zip" -o bws.zip
- unzip bws.zip -d /usr/local/bin && chmod +x /usr/local/bin/bws
script:
- npm ci --cache $NPM_CONFIG_CACHE
- npx prisma generate
- bws run --project-id $BWS_PROJECT_DEV -- npx prisma migrate deploy
rules:
- if: $CI_COMMIT_BRANCH == "develop"
changes:
- prisma/migrations/**/*
migrate:test es identico pero se ejecuta en la rama test usando $BWS_PROJECT_TEST. Si un push no modifica el schema, este stage se omite completamente.
4. Gestion de Secretos con Bitwarden Secrets Manager
Nvito utiliza Bitwarden Secrets Manager (BWS) como vault centralizado. Ningun secreto sensible se almacena directamente como variable de GitLab CI/CD.
4.1 Organizacion de Projects y Machine Accounts
| Project BWS | Ambiente | Machine Account | Uso |
|---|---|---|---|
nvito-local | Local | local-dev | Desarrollo local via bws |
nvito-dev | DEV | gitlab-cicd | Pipeline GitLab CI/CD |
nvito-test | TEST | gitlab-cicd | Pipeline GitLab CI/CD |
4.2 Inyeccion de Secretos en el Pipeline
El comando bws run inyecta los secretos del project BWS como variables de entorno en el proceso hijo:
bws run --project-id $BWS_PROJECT_DEV -- npx prisma migrate deploy
- Se autentica con BWS usando
$BWS_ACCESS_TOKEN(unica variable sensible en GitLab). - Recupera todos los secretos del project indicado.
- Los inyecta como variables de entorno (incluyendo
DATABASE_URL). - Ejecuta el comando indicado con acceso a esos secretos.
4.3 Variables en GitLab vs BWS
| Variable | Almacenada en | Proposito |
|---|---|---|
BWS_ACCESS_TOKEN | GitLab CI/CD | Token de autenticacion contra BWS |
BWS_PROJECT_DEV | GitLab CI/CD | ID del project BWS para ambiente DEV |
BWS_PROJECT_TEST | GitLab CI/CD | ID del project BWS para ambiente TEST |
DATABASE_URL | BWS | URL de conexion a la BD (por ambiente) |
| Demas secrets | BWS | API keys, tokens de servicios, etc. |
5. Despliegue con Coolify
Coolify gestiona el ciclo de vida de los contenedores Docker en un VPS Contabo (Cloud VPS 10 — 4 vCPU, 8 GB RAM) con Traefik como reverse proxy integrado.
5.1 Servicios Desplegados
| Servicio | Branch | Dominio | Puerto |
|---|---|---|---|
| nvito-api-dev | develop | dev-api.nvito.mx | 3000 |
| nvito-api-test | test | test-api.nvito.mx | 3000 |
| nvito-admin-dev | develop | dev-admin.nvito.mx | 5050 |
| nvito-admin-test | test | test-admin.nvito.mx | 5050 |
| nvito-invitations-dev | develop | dev.nvito.mx | 3001 |
| nvito-invitations-test | test | test.nvito.mx | 3001 |
5.2 Mecanismo de Auto-Deploy
Coolify se conecta a GitLab mediante deploy keys (Coolify v4 no soporta GitLab como Source nativo):
- Se genera una clave SSH (
gitlab-deploy-key) en Coolify Security > Private Keys. - La clave publica se agrega como deploy key en cada repositorio de GitLab.
- Coolify expone un webhook URL por servicio; GitLab lo dispara en cada push.
- Coolify hace
git pull, ejecutadocker build(Dockerfile multi-stage), health check, y rollout. - Traefik actualiza el routing automaticamente con SSL via Let's Encrypt.
Las variables de entorno de cada servicio se configuran directamente en el dashboard de Coolify (no via BWS).
Importante: Las variables
NEXT_PUBLIC_*se inyectan en build time. Si se modifican, es necesario hacer un redeploy para que tomen efecto.
6. Flujo de Deploy Completo
El pipeline CI/CD y el deploy de Coolify se ejecutan en paralelo. Las migraciones suelen completarse antes que el build Docker, asi que para cuando el nuevo contenedor inicia, la BD ya tiene el schema actualizado. Si una migracion falla, el desarrollador debe monitorear ambos procesos ya que Coolify no depende del resultado del pipeline.
7. Estrategia de Branching
| Rama | Ambiente | URL Base | Base de Datos |
|---|---|---|---|
develop | DEV | dev-*.nvito.mx | Neon nvito-dev |
test | TEST | test-*.nvito.mx | Neon nvito-test |
Flujo: feature branch --> merge request a develop (trigger pipeline) --> merge en develop (deploy DEV) --> merge develop a test (deploy TEST).
| Accion | develop | test | Merge Request |
|---|---|---|---|
| lint | Si | Si | Si |
| test:unit | Si | Si | Si |
| migrate:dev | Si | No | No |
| migrate:test | No | Si | No |
| Deploy Coolify (auto-deploy) | Si | Si | No |
8. Migraciones de Base de Datos
8.1 Cuando se Ejecutan
Solo cuando se cumplen ambas condiciones: push a develop o test, y cambios en prisma/migrations/**/*.
8.2 prisma migrate deploy vs prisma migrate dev
prisma migrate deploy es el comando seguro para CI/CD:
- Solo aplica migraciones existentes que aun no se han ejecutado.
- No modifica archivos del proyecto ni requiere input interactivo.
- Es idempotente: si no hay migraciones pendientes, no hace nada.
8.3 Flujo de Migracion
- El desarrollador crea una migracion localmente con
npx prisma migrate dev --name <nombre>. - El archivo SQL se commitea junto con los cambios de codigo.
- Al hacer push a
develop, el jobmigrate:devaplica la migracion en Neon DEV viabws run. - Al hacer merge en
test, el jobmigrate:testaplica la misma migracion en Neon TEST. - El job
test:unittambien ejecutaprisma migrate deploycontra la BD efimera de PostgreSQL, garantizando que los tests corran contra un schema actualizado.
9. Variables de CI/CD en GitLab
Configurar en GitLab > Settings > CI/CD > Variables para el repositorio nvito-api:
| Variable | Valor | Protected | Masked |
|---|---|---|---|
BWS_ACCESS_TOKEN | Token del machine account gitlab-cicd | Si | Si |
BWS_PROJECT_DEV | Project ID de nvito-dev en BWS | No | No |
BWS_PROJECT_TEST | Project ID de nvito-test en BWS | No | No |
Principio de seguridad: Los secretos sensibles (DATABASE_URL, API keys) nunca se almacenan como variables de GitLab. Solo el token de acceso a BWS y los IDs de proyecto se configuran ahi. El resto se inyecta en runtime via
bws run.
10. Troubleshooting
10.1 OpenSSL en Alpine
Problema: Error: Could not parse schema engine response en jobs que ejecutan Prisma.
Solucion: Agregar apk add --no-cache openssl en el before_script.
10.2 Lint falla por formato Prettier
Solucion: Ejecutar npm run format && npm run lint:fix && npm run lint localmente antes de hacer push.
10.3 Migracion no se ejecuta
Causa: La directiva changes no detecto cambios en prisma/migrations/. Verificar que los archivos estan commiteados y el push es a la rama correcta.
10.4 Deploy de Coolify falla
Revisar logs en el dashboard de Coolify. Causas comunes: variables NEXT_PUBLIC_* faltantes (se requieren en build time), devDependencies omitidas por NODE_ENV=production, permisos de directorios en el contenedor.