todos-contra-el-fuego-web/docker-compose.staging.yml
vjrj 03082a8d55 staging: conecta el importador NASA reimplementado al stack
El servicio `importer` apuntaba a fires-csv-mongo-import/ (el de 2018, sin Dockerfile) y
vivia tras el profile "importer", a la espera de un systemd timer que nunca se creo. Ahora
apunta a todos-contra-el-fuego/nasa-importer/, arranca con el stack y hace su ciclo cada
15 minutos por si mismo.

El JWT de NASA entra por secrets/importer.staging.env (gitignorado); se anade el .example.
Volumen importer-data para los CSV descargados: sin el, cada ciclo se creeria que NASA ha
publicado datos nuevos y reimportaria siempre.
2026-07-28 07:49:05 +02:00

170 lines
5.7 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:
build:
context: .
dockerfile: Dockerfile
image: tcef-web: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: