Saltar a contenido

Setup: producción en devops-vm (GCP)

Instalación inicial del stack de producción. La operación diaria (deploy de cambios, logs, rollback, fallas) está en el runbook; el diseño y sus revisiones, en Diseño del despliegue en GCP.

Archivos: unomi-eval/deploy/ (docker-compose.yml, .env.example, cloudflared-ingress.yml).

Dónde corre

Elemento Valor
VM devops-vm, GCP, zona southamerica-east1-a, c3-standard-4 (4 vCPU, 16 GB), Debian 12, Docker 28.5 + Compose 2.39. Compartida con otras aplicaciones.
Ubicación /opt/cdp (clon de CompulandiaTI/cdp-unomi, rama main); compose en /opt/cdp/unomi-eval/deploy
Acceso gcloud compute ssh devops-vm --zone southamerica-east1-a --tunnel-through-iap (usuario con grupo docker y sudo)
Contenedores cdp-es, cdp-unomi, cdp-inoyu-ui; red cdp (172.30.0.0/24); volúmenes cdp-es-data, cdp-es-snapshots
Puertos 0.0.0.0:8181 (Unomi) y 0.0.0.0:3131 (Inoyu) en la red interna de la VPC; el firewall de GCP no los expone a internet. Elasticsearch sin publicar.
Entrada Cloudflare Tunnel existente (servicio cloudflared del host, gestionado por token) con dos Public Hostnames apuntando a la IP interna de la VM
Memoria ES heap 1 GB / límite 2,5 GiB; Unomi heap 1,5 GB / límite 2 GiB; Inoyu límite 512 MiB

Instalación desde cero

# 1. Preparar el host (una sola vez)
echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-elasticsearch.conf && sudo sysctl --system
sudo mkdir -p /opt/cdp && sudo chown "$USER":"$USER" /opt/cdp

# 2. Código
git clone git@github.com:CompulandiaTI/cdp-unomi.git /opt/cdp
cd /opt/cdp/unomi-eval/deploy

# 3. Secretos y dominios
cp .env.example .env && chmod 600 .env
for v in UNOMI_ROOT_PASSWORD UNOMI_HEALTHCHECK_PASSWORD UNOMI_THIRDPARTY_PROVIDER1_KEY INOYU_JWT_SECRET INOYU_ADMIN_PASSWORD; do
  sed -i "s|^$v=.*|$v=$(openssl rand -hex 24)|" .env
done
# revisar CDP_ADMIN_HOST, CDP_API_HOST, INOYU_ADMIN_EMAIL, CDP_BIND y EXTRA_TRUSTED_SUBNETS

# 4. Construir y arrancar
docker compose build inoyu-ui         # ~5 min; usa build.network: host por el DNS de la VM
docker compose up -d
docker compose ps                     # healthy en los tres servicios

Verificación: ver "Cómo verificar que el deploy salió bien" en el runbook.

Cloudflare

En Zero Trust → Networks → Tunnels → túnel de devops-vm → Public Hostnames, en este orden (cloudflared-ingress.yml):

Hostname Service Access
cdp.compulandia.com.py http://10.158.0.22:3131 Aplicación self-hosted, política Allow para los correos del dominio corporativo (SSO)
cdp-api.compulandia.com.py http://10.158.0.22:8181 Aplicación self-hosted, política Service Auth con un token de servicio por sistema (cdp-jitsu, cdp-n8n); la API administrativa exige además Basic auth de Unomi y los eventos protegidos X-Unomi-Peer

Sin la política de Access, cdp-api deja los endpoints públicos de Unomi abiertos a internet: crear la aplicación antes o al mismo tiempo que el hostname. Recomendado: regla de Rate Limiting sobre cdp-api.

Llamadas de los integradores:

POST https://cdp-api.compulandia.com.py/cxs/eventcollector
CF-Access-Client-Id: <client id del token de servicio>
CF-Access-Client-Secret: <client secret>
Content-Type: application/json
X-Unomi-Peer: <UNOMI_THIRDPARTY_PROVIDER1_KEY>      # solo en login y updateProperties

Variables de .env relevantes

Variable Valor en producción Efecto
CDP_ADMIN_HOST / CDP_API_HOST cdp.compulandia.com.py / cdp-api.compulandia.com.py Dirección pública que Unomi e Inoyu comunican
CDP_BIND 0.0.0.0 Interfaz de publicación de 8181/3131 (127.0.0.1 para cerrarlos a la VM)
EXTRA_TRUSTED_SUBNETS ,10.158.0.0/20 Subredes autorizadas para eventos protegidos (IP de origen que ve Unomi: el servidor que aloja cloudflared)
ES_HEAP, ES_MEM_LIMIT, UNOMI_HEAP, UNOMI_MEM_LIMIT, INOYU_MEM_LIMIT 1g, 2560m, 1536m, 2048m, 512m Dimensionado para la VM compartida
RETENTION_* 365 / 400 / 400 / 13 Purga de perfiles inactivos, eventos, sesiones e índices
Secretos generados con openssl Nunca versionados; copia pendiente en Secret Manager

Particularidades de devops-vm

  • Los contenedores de la red bridge por defecto no resuelven DNS (resolver de metadatos de GCE inalcanzable); las redes propias y la red de host sí. Por eso inoyu-ui se construye con build.network: host.
  • No montar un volumen en /opt/apache-unomi/data de Unomi: la caché de Karaf persistida impide regenerar etc/jetty.xml al recrear el contenedor y el HTTP no arranca.
  • La VM no tiene swap y comparte 16 GB con 14 aplicaciones; observar memoria en Grafana (ya instalado en la VM).