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
117
RUNBOOK.md
Normal file
117
RUNBOOK.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# RUNBOOK — stack local dockerizado (fase 3, validación)
|
||||
|
||||
Stack Docker Compose del sistema modernizado de "Todos contra el fuego":
|
||||
web Meteor 3.1 (Node 22), MongoDB 7 (replica set de un nodo), Redis (AOF),
|
||||
`tcef-notifications` y node-red. **Es el entorno de validación local previo a
|
||||
producción** — el despliegue real irá al ansible de Comunes (fase 3 del plan);
|
||||
este compose no toca el proxy ni la infra compartida.
|
||||
|
||||
## Requisitos
|
||||
|
||||
- Docker + Docker Compose v2.
|
||||
- El repo hermano `../tcef-notifications` (el compose construye su imagen desde ahí).
|
||||
|
||||
## Primer arranque
|
||||
|
||||
```bash
|
||||
# 1. Secretos (gitignorados; ver secrets/README.md)
|
||||
cp settings-development.json secrets/meteor-settings.json
|
||||
cp secrets/notifications.env.example secrets/notifications.env # MODE=dry-run
|
||||
|
||||
# 2. Construir y levantar (el primer build de la web tarda: descarga meteor-tool
|
||||
# y compila el bundle; ~10-20 min en frío)
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
|
||||
# 3. Comprobar salud
|
||||
docker compose ps # todo "healthy" / mongo-init "exited (0)"
|
||||
```
|
||||
|
||||
Servicios y puertos en el host:
|
||||
|
||||
| Servicio | Contenedor | URL / puerto |
|
||||
|---|---|---|
|
||||
| web Meteor | `tcef-stack-web` | http://localhost:3200 |
|
||||
| node-red | `tcef-stack-node-red` | http://localhost:1880 |
|
||||
| MongoDB 7 | `tcef-stack-mongo` | solo red interna (usar `docker exec`) |
|
||||
| Redis | `tcef-stack-redis` | solo red interna |
|
||||
| notificaciones | `tcef-stack-notifications` | sin puerto (worker) |
|
||||
|
||||
`mongo-init` es un one-shot: inicia el replica set `rs0` y fija
|
||||
`db.migrations` a la versión 18 (los `up()` históricos ya son async, pero se
|
||||
pinta v18 porque los datos reales de producción llegan pre-migrados).
|
||||
|
||||
> Nota healthcheck: los checks usan `127.0.0.1`, no `localhost`. El `wget` de
|
||||
> busybox (alpine) resuelve `localhost` a `::1` (IPv6) primero, pero los
|
||||
> servidores Meteor/node-red escuchan solo en IPv4 → un `localhost` daría
|
||||
> unhealthy aunque la app responda perfectamente por el puerto mapeado.
|
||||
|
||||
## Smoke test REST (red de seguridad del contrato Flutter)
|
||||
|
||||
Debe ser **byte-idéntico** a los snapshots committeados:
|
||||
|
||||
```bash
|
||||
MONGO_CONTAINER=tcef-stack-mongo MONGO_SHELL=mongosh MONGO_PORT=27017 \
|
||||
BASE_URL=http://localhost:3200 ./smoke/smoke.sh
|
||||
```
|
||||
|
||||
## Operación diaria
|
||||
|
||||
```bash
|
||||
docker compose logs -f web # logs de un servicio (rotados: 3×10MB)
|
||||
docker compose ps # estado + healthchecks
|
||||
docker compose restart notifications # reiniciar un servicio
|
||||
docker compose down # parar todo (los volúmenes persisten)
|
||||
docker compose down -v # ⚠️ borra también mongo/redis/node-red
|
||||
```
|
||||
|
||||
## Desplegar una nueva versión
|
||||
|
||||
```bash
|
||||
# web (tras cambios en el repo)
|
||||
docker compose build web && docker compose up -d web
|
||||
|
||||
# notificaciones (tras cambios en ../tcef-notifications)
|
||||
docker compose build notifications && docker compose up -d notifications
|
||||
```
|
||||
|
||||
Verificar tras cada despliegue de la web: `docker compose ps` healthy + smoke
|
||||
REST byte-idéntico (arriba).
|
||||
|
||||
## Backups y restauración (volúmenes locales)
|
||||
|
||||
```bash
|
||||
# Mongo: dump / restore de la db fuegos
|
||||
docker exec tcef-stack-mongo mongodump --db fuegos --archive > fuegos.dump
|
||||
docker exec -i tcef-stack-mongo mongorestore --archive --drop < fuegos.dump
|
||||
|
||||
# node-red: tar del volumen de datos
|
||||
docker run --rm -v tcef-stack_nodered-data:/data -v "$PWD:/backup" alpine \
|
||||
tar czf /backup/nodered-data.tgz -C /data .
|
||||
```
|
||||
|
||||
## Rollback
|
||||
|
||||
- **web**: `git checkout <commit-anterior>` + `docker compose build web && docker compose up -d web`.
|
||||
(En producción se conservará la imagen anterior etiquetada; aquí basta git.)
|
||||
- **notificaciones**: igual, desde `../tcef-notifications`. `KILL_SWITCH=1` en
|
||||
`secrets/notifications.env` + `docker compose up -d notifications` detiene
|
||||
todo envío al instante sin parar el servicio.
|
||||
- **datos**: restaurar el último dump (arriba).
|
||||
|
||||
## Salvaguardas de notificaciones
|
||||
|
||||
`secrets/notifications.env` arranca en `MODE=dry-run` (no envía nada). La
|
||||
progresión dry-run → shadow → canary → full está documentada en
|
||||
`../tcef-notifications/docs/rollout.md` y **nunca** se salta pasos. En este
|
||||
stack local no hay credenciales reales salvo que las pongas tú.
|
||||
|
||||
## Deuda conocida de este compose
|
||||
|
||||
- `tcef-notifications` no expone endpoint HTTP de salud → healthcheck por
|
||||
proceso (`pgrep`). Añadir `/healthz` al servicio cuando toque.
|
||||
- node-red corre la imagen oficial vacía (los flows de los bots viven en
|
||||
shiva; su migración de datos es parte del cutover real de fase 3).
|
||||
- El driver mongodb 3.7 de `tcef-notifications` (elegido por el Mongo 3.2 de
|
||||
producción) conecta con Mongo 7 en pruebas locales, pero al hacer el cutover
|
||||
real a Mongo 7 debe subirse a driver 6.x (y habilitar change streams).
|
||||
Loading…
Add table
Add a link
Reference in a new issue