Docs

CI/CD y Despliegue

Tabla de Contenidos

  1. Vision General del Pipeline
  2. Pipeline GitLab CI Completo
  3. Stages del Pipeline
  4. Gestion de Secretos con Bitwarden Secrets Manager
  5. Despliegue con Coolify
  6. Flujo de Deploy Completo
  7. Estrategia de Branching
  8. Migraciones de Base de Datos
  9. Variables de CI/CD en GitLab
  10. 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.

RepositorioPipeline GitLab CIDeploy Coolify
nvito-apiquality (lint + test) + migrateAuto-deploy via webhook
nvito-adminNo tiene pipeline CIAuto-deploy via webhook
nvito-invitationsNo tiene pipeline CIAuto-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-alpine como servicio adjunto; la BD se destruye al terminar.
  • Se instala openssl en 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 BWSAmbienteMachine AccountUso
nvito-localLocallocal-devDesarrollo local via bws
nvito-devDEVgitlab-cicdPipeline GitLab CI/CD
nvito-testTESTgitlab-cicdPipeline 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
  1. Se autentica con BWS usando $BWS_ACCESS_TOKEN (unica variable sensible en GitLab).
  2. Recupera todos los secretos del project indicado.
  3. Los inyecta como variables de entorno (incluyendo DATABASE_URL).
  4. Ejecuta el comando indicado con acceso a esos secretos.

4.3 Variables en GitLab vs BWS

VariableAlmacenada enProposito
BWS_ACCESS_TOKENGitLab CI/CDToken de autenticacion contra BWS
BWS_PROJECT_DEVGitLab CI/CDID del project BWS para ambiente DEV
BWS_PROJECT_TESTGitLab CI/CDID del project BWS para ambiente TEST
DATABASE_URLBWSURL de conexion a la BD (por ambiente)
Demas secretsBWSAPI 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

ServicioBranchDominioPuerto
nvito-api-devdevelopdev-api.nvito.mx3000
nvito-api-testtesttest-api.nvito.mx3000
nvito-admin-devdevelopdev-admin.nvito.mx5050
nvito-admin-testtesttest-admin.nvito.mx5050
nvito-invitations-devdevelopdev.nvito.mx3001
nvito-invitations-testtesttest.nvito.mx3001

5.2 Mecanismo de Auto-Deploy

Coolify se conecta a GitLab mediante deploy keys (Coolify v4 no soporta GitLab como Source nativo):

  1. Se genera una clave SSH (gitlab-deploy-key) en Coolify Security > Private Keys.
  2. La clave publica se agrega como deploy key en cada repositorio de GitLab.
  3. Coolify expone un webhook URL por servicio; GitLab lo dispara en cada push.
  4. Coolify hace git pull, ejecuta docker build (Dockerfile multi-stage), health check, y rollout.
  5. 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

RamaAmbienteURL BaseBase de Datos
developDEVdev-*.nvito.mxNeon nvito-dev
testTESTtest-*.nvito.mxNeon nvito-test

Flujo: feature branch --> merge request a develop (trigger pipeline) --> merge en develop (deploy DEV) --> merge develop a test (deploy TEST).

AcciondeveloptestMerge Request
lintSiSiSi
test:unitSiSiSi
migrate:devSiNoNo
migrate:testNoSiNo
Deploy Coolify (auto-deploy)SiSiNo

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

  1. El desarrollador crea una migracion localmente con npx prisma migrate dev --name <nombre>.
  2. El archivo SQL se commitea junto con los cambios de codigo.
  3. Al hacer push a develop, el job migrate:dev aplica la migracion en Neon DEV via bws run.
  4. Al hacer merge en test, el job migrate:test aplica la misma migracion en Neon TEST.
  5. El job test:unit tambien ejecuta prisma migrate deploy contra 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:

VariableValorProtectedMasked
BWS_ACCESS_TOKENToken del machine account gitlab-cicdSiSi
BWS_PROJECT_DEVProject ID de nvito-dev en BWSNoNo
BWS_PROJECT_TESTProject ID de nvito-test en BWSNoNo

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.

Esta pagina fue util?