Skip to main content

Despliegue

Tres artefactos distintos, con tres caminos distintos.

Backend — Docker Compose

docker-compose.yml levanta un container por rol, todos desde la misma imagen:

ContainerRol
node-appLa API HTTP (clusterizada por cores)
bot-publisherScraper PAMI
bot-consumer-1..4Consumidores de la cola de PAMI
bot-authorizationSync de autorizaciones
rabbitmqBroker (rabbitmq:3.11-management, panel en el 15672)
nginx_proxyReverse proxy y estáticos (puertos 80 / 443)
socket-serverServidor de sockets

Los workers se diferencian solo por su EXECUTION_MODE y tienen límites de recursos propios (512 MB / 0.5 CPU en el publisher). Ver Workers y colas.

La imagen

Dockerfile multi-stage:

# Stage 1: node:20, npm install completo, npm run build (tsc → dist/)
# Stage 2: node:20-slim, npm install --production, copia dist/ y certs/
CMD ["node", "dist/index.js"]
El .env no va en la imagen

Se monta por env_file: .env desde el host. No lo copies al Dockerfile.

Los uploads se persisten con un volumen: /var/uploads del host → /usr/src/app/uploads.

Nginx

Sirve la consola web como estático desde /var/www/oxitec-web-app y proxea la API:

location /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://node-app:3000;
# + headers de upgrade para websockets
}

location /mobile/ { # los APK de BullStock para descarga directa
alias /var/www/mobile/;
}

Por eso el front apunta a .../api/v1 y el backend expone /v1: el prefijo /api lo saca nginx.

Consola web — build estático

npm run build:prod # producción
npm run build:pre # PRE: genera el environment desde env vars y compila

Salida: dist/oxitesa-front/browser. Se publica de dos formas según el ambiente:

  • Copiando el build a /var/www/oxitec-web-app en el server (lo que sirve nginx).
  • Firebase Hosting — hay un firebase.json con public: dist/oxitesa-front/browser y un rewrite **/index.html para el ruteo del SPA.
build:pre genera el environment en tiempo de build

scripts/set-env.js escribe src/environments/environment-pre.ts a partir de variables de entorno (API_URL, CLERK_PUBLISHABLE_KEY, FIREBASE_*, POSTHOG_*, POWER_BI_TENANT_ID…). Así las claves de PRE no quedan committeadas en el repo. Las de producción sí están en el environment.ts versionado.

Mobile — EAS y builds locales

EAS (la vía normal)

npm run build:dev:android # dev client
npm run build:pre:android # PRE, distribución interna

Perfiles en eas.json:

PerfilQué produce
developmentDev client, distribución interna
previewAPK, distribución interna
productionAAB para Play Store, con autoIncrement y appVersionSource: remote

Local (Makefile)

make android-release ENV=prod # APK
make android-bundle ENV=prod # AAB

Envuelve expo prebuild + Gradle, y copia el .env elegido a .env antes de compilar para que los valores queden horneados.

Versionado y update obligatorio

Después de publicar, hay que dar de alta la versión en el módulo mobileConfig del backend (versión semver, entorno, URL del build, changelog). La app compara su versión contra esa fila al arrancar y muestra el modal de actualización obligatoria si corresponde.

Los APK para descarga directa se publican en /var/www/mobile/, que nginx sirve en /mobile/. La consola web tiene una landing de descarga en /download/mobile/bullstock.

Cambios de base de datos

No hay migraciones automáticas de schema. Los cambios se aplican a mano:

TipoDónde viveCómo se aplica
DDL, stored procedures, viewsmigrations/**/*.sqlSe ejecuta el SQL contra la base del ambiente
Datos de configuración (roles, permisos, estados, tipos de movimiento)src/migrations/*.tsnpx ts-node — pero los workers también los corren al arrancar
Al redeployar un SP, aplicá el archivo de store/, no el de fix/

store/ es el estado completo actual. fix/ son parches históricos que quedan como registro. Ver Stored procedures.

Orden recomendado de un release

  1. Base: aplicar el SQL nuevo (SPs, views, DDL) en el ambiente.
  2. Backend: docker compose build && docker compose up -d. Verificar que los workers levanten.
  3. Consola web: build y publicar.
  4. Mobile: build EAS, y recién después dar de alta la versión en mobileConfig.

El paso 1 va primero porque el backend nuevo suele asumir el SP nuevo, y el paso 4 va último porque dar de alta la versión fuerza la actualización en los dispositivos.