# Stack local modernizado de "Todos contra el fuego" (fase 3 — validación local). # NO es el despliegue de producción: eso irá al ansible de Comunes (proxies, # firewall, monitorización). Aquí se valida que todo el stack corre en Docker. # # Uso: ver RUNBOOK.md. Secretos: ./secrets/ (montados como ficheros, gitignored). name: tcef-stack x-logging: &default-logging driver: json-file options: max-size: "10m" max-file: "3" services: mongo: image: mongo:7 container_name: tcef-stack-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 (un nodo) y marca las migraciones de Meteor # como aplicadas (v18) para que los up() históricos (aún síncronos) no corran. 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"}]}) }' # espera a que el nodo sea PRIMARY antes de escribir 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-stack-web depends_on: mongo-init: condition: service_completed_successfully environment: PORT: "3000" ROOT_URL: http://localhost:3200 MONGO_URL: mongodb://mongo:27017/fuegos?replicaSet=rs0 METEOR_SETTINGS_FILE: /run/secrets/meteor-settings.json volumes: - ./secrets/meteor-settings.json:/run/secrets/meteor-settings.json:ro ports: - "3200:3000" restart: unless-stopped logging: *default-logging redis: image: redis:7-alpine container_name: tcef-stack-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-stack-notifications depends_on: mongo-init: condition: service_completed_successfully redis: condition: service_healthy # Copia secrets/notifications.env.example -> secrets/notifications.env. # Por defecto MODE=dry-run: no envía nada aunque haya credenciales. env_file: - ./secrets/notifications.env restart: unless-stopped logging: *default-logging node-red: image: nodered/node-red:4.0 container_name: tcef-stack-node-red volumes: - nodered-data:/data ports: - "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 volumes: mongo-data: redis-data: nodered-data: