todos-contra-el-fuego-web/docker-compose.staging.yml
vjrj 6aa057f739
Some checks failed
build-image / build (push) Failing after 8s
staging: la web se descarga del registry, no se compila en groucho
Cloudflare ya no esta delante de git.comunes.org, asi que el registry de Forgejo acepta
la capa de 508 MB del bundle (comprobado: subida completa desde groucho, la imagen esta
en comunes/-/packages/container/tcef-web con los tags meteor3 y a24c7a567c).

- compose: `build:` -> `image: git.comunes.org/comunes/tcef-web:${TCEF_WEB_TAG:-meteor3}`.
  groucho pasa de 30 min de `meteor build` (que lo dejaron sin ssh) a un pull de segundos.
- workflow: se activa el disparo por push, y se anade una comprobacion de secretos como
  primer paso. Sin ella, faltar REGISTRY_TOKEN se descubria a los ~30 min, al intentar
  el push; ahora falla en 2 segundos diciendo exactamente que crear y donde.
2026-07-28 13:50:23 +02:00

172 lines
6.1 KiB
YAML

# Stack de STAGING de "Todos contra el fuego" para testfuegos.comunes.org.
# Derivado de docker-compose.yml (validación local). Diferencias clave:
# - web sirve en https://testfuegos.comunes.org (tras el proxy assange), puerto host 8004
# - Mongo 7 AISLADO, sembrado con un volcado real de `fuegos` y contactos neutralizados
# (NUNCA apunta al rsmain de producción)
# - notificaciones en MODE=shadow / MATCHER_MODE=shadow: calcula y loguea, NO envía
# - mailhog captura TODO el correo (nada sale a un SMTP real)
# - node-red solo conversacional; si se prueba el bot, con un BOT DE PRUEBAS, nunca los reales
#
# Despliegue real: vía el role ansible roles/tcef_staging/ en el repo de Comunes
# (~/proyectos/sync/comunes/shared-l2/ansible/). Este compose es la fuente que ese role monta.
# Secretos: ./secrets/*.staging.* (gitignored). Uso: RUNBOOK.md.
name: tcef-staging
x-logging: &default-logging
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
mongo:
image: mongo:7
container_name: tcef-staging-mongo
command: ["--replSet", "rs0", "--bind_ip_all"]
volumes:
- mongo-data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"]
interval: 10s
timeout: 5s
retries: 12
start_period: 20s
restart: unless-stopped
logging: *default-logging
# One-shot: inicia el replica set de un nodo y marca las migraciones a v18
# (los datos reales llegan pre-migrados). Idéntico al compose de validación.
mongo-init:
image: mongo:7
depends_on:
mongo:
condition: service_healthy
restart: "no"
entrypoint:
- bash
- -ec
- |
mongosh --host mongo --quiet --eval 'try { rs.status().ok } catch (e) { rs.initiate({_id: "rs0", members: [{_id: 0, host: "mongo:27017"}]}) }'
for i in $$(seq 1 30); do
state=$$(mongosh --host mongo --quiet --eval 'try { rs.isMaster().ismaster } catch (e) { false }')
[ "$$state" = "true" ] && break
sleep 1
done
mongosh --host mongo --quiet fuegos --eval 'db.migrations.replaceOne({_id: "control"}, {_id: "control", version: 18, locked: false}, {upsert: true})'
echo "mongo-init: replica set + migrations OK"
logging: *default-logging
web:
# La imagen se construye en el CI (runner de aaron) y se publica en el registry de
# Forgejo; aquí solo se descarga. groucho NO compila: un `meteor build` lo dejó sin ssh
# (5,9 GB compartidos con Mongo 7 + el resto del stack). Ver
# plan-modernizacion/fase-9-ci-imagenes.md y .forgejo/workflows/build-image.yml.
# Para fijar una versión concreta: TCEF_WEB_TAG=<sha12> docker compose up -d web
image: git.comunes.org/comunes/tcef-web:${TCEF_WEB_TAG:-meteor3}
container_name: tcef-staging-web
depends_on:
mongo-init:
condition: service_completed_successfully
environment:
PORT: "3000"
ROOT_URL: https://testfuegos.comunes.org
MONGO_URL: mongodb://mongo:27017/fuegos?replicaSet=rs0
METEOR_SETTINGS_FILE: /run/secrets/meteor-settings.json
volumes:
- ./secrets/meteor-settings.staging.json:/run/secrets/meteor-settings.json:ro
# Solo el proxy (assange) llega a este puerto; se publica en la red interna del host.
ports:
- "8004:3000"
restart: unless-stopped
logging: *default-logging
redis:
image: redis:7-alpine
container_name: tcef-staging-redis
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 6
restart: unless-stopped
logging: *default-logging
notifications:
build:
context: ../tcef-notifications
image: tcef-notifications:local
container_name: tcef-staging-notifications
depends_on:
mongo-init:
condition: service_completed_successfully
redis:
condition: service_healthy
# secrets/notifications.staging.env → MODE=shadow, MATCHER_MODE=shadow, sin FCM,
# MAIL_URL=smtp://mailhog:1025. No envía nada a usuarios reales.
env_file:
- ./secrets/notifications.staging.env
restart: unless-stopped
logging: *default-logging
# Buzón SMTP de captura: TODO el correo (verificación/reset/notifs) aterriza aquí, nunca fuera.
# UI web en 127.0.0.1:8025 (acceder por túnel SSH). SMTP interno en mailhog:1025.
mailhog:
image: mailhog/mailhog:latest
container_name: tcef-staging-mailhog
environment:
MH_STORAGE: memory
ports:
- "127.0.0.1:8025:8025"
restart: unless-stopped
logging: *default-logging
node-red:
image: nodered/node-red:4.0
container_name: tcef-staging-node-red
volumes:
- nodered-data:/data
ports:
- "127.0.0.1:1880:1880"
healthcheck:
test: ["CMD", "wget", "-qO", "/dev/null", "http://127.0.0.1:1880/"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
restart: unless-stopped
logging: *default-logging
# Importador NASA FIRMS → escribe activefires en ESTE mongo (NUNCA en prod), alimentando al
# matcher en shadow. Proceso de larga vida: hace su ciclo cada INTERVAL_MINUTES (15, igual
# que el cron de shiva), no hace falta timer del host.
# El JWT de Earthdata va en secrets/importer.staging.env, nunca en la imagen ni en el repo.
importer:
build:
context: ../todos-contra-el-fuego/nasa-importer
image: tcef-nasa-importer:local
container_name: tcef-staging-importer
depends_on:
mongo-init:
condition: service_completed_successfully
environment:
MONGO_URL: mongodb://mongo:27017/fuegos?replicaSet=rs0
INTERVAL_MINUTES: "15"
# Reproduce el `when` de producción (acq_time UTC leído como hora local). Ver
# nasa-importer/README.md § "Zona horaria" antes de cambiarlo a UTC.
FIRE_TIME_TZ: Europe/Madrid
env_file:
- ./secrets/importer.staging.env
volumes:
- importer-data:/data
restart: unless-stopped
logging: *default-logging
volumes:
mongo-data:
redis-data:
nodered-data:
importer-data: