# 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 (no en prod), alimentando el # matcher en shadow. No arranca con `up` (profile "importer"): lo dispara un systemd timer # del host cada 15 min con `docker compose run --rm importer`. # NOTA: requiere crear su Dockerfile en fires-csv-mongo-import/ (fase-3 §2). Hasta entonces, # este servicio queda declarado pero su build context debe completarse. importer: profiles: ["importer"] build: context: ../todos-contra-el-fuego/fires-csv-mongo-import 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 restart: "no" logging: *default-logging volumes: mongo-data: redis-data: nodered-data: