fase 3: stack docker-compose local del sistema modernizado
Compose con los 5 servicios: mongo:7 (replica set rs0 + mongo-init one-shot), redis (AOF), web Meteor 3.1 (Dockerfile multi-stage: builder debian con meteor-tool 3.1 -> server-deps alpine -> runtime node:22-alpine), notifications (dry-run) y node-red 4. Healthchecks (127.0.0.1, no localhost: busybox wget prefiere IPv6 y Meteor escucha IPv4), restart unless-stopped, logging rotado 3x10MB, secretos montados desde ./secrets (gitignored, solo .example versionado). .npmrc legacy-peer-deps para el ERESOLVE de las libs react viejas. Validado: los 5 servicios healthy y smoke REST byte-identico (12/12) contra la web dockerizada en :3200. RUNBOOK.md documenta arranque, smoke, backups y rollback. No toca infra de Comunes.
This commit is contained in:
parent
e3f3f4aa20
commit
197a59f641
10 changed files with 341 additions and 1 deletions
125
docker-compose.yml
Normal file
125
docker-compose.yml
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
# 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:
|
||||
Loading…
Add table
Add a link
Reference in a new issue