Redis
Sdílená cache — BullMQ message queue (core→edge eventy), S60Auth token/session cache, agent komunikace.
Hosty
| Server |
URL |
Použití |
| cerebro (s60-redis) |
redis://localhost:6379 (Tailscale) |
Dev agenti, agent komunikace, memory:inbox |
| hub-alfa |
s60-redis:6379 (interní docker network) |
Hub aplikace |
| prod-alfa |
s60-redis:6379 |
Prod aplikace |
| hub-alfa (cortex-redis) |
100.102.29.119:6380 (Tailscale-only) |
Dedikovaná Cortex↔badwolf BullMQ fronta (testing) |
| prod-alfa (cortex-redis) |
100.78.87.88:6380 (Tailscale-only) |
Dedikovaná Cortex↔badwolf BullMQ fronta (prod) |
cortex-redis — dedikovaný pro Cortex↔badwolf (2026-07-13)
Samostatný Redis izolovaný od s60-redis — Cortex (externí host, 100.120.98.59) je cross-host přes Tailscale, sdílený s60-redis drží auth token blacklist → nechceme mu ho vystavovat. Dedikovaný = izolace + vlastní silné heslo + žádný blip na s60-redis.
- Container:
cortex-redis (redis:alpine, AOF, volume cortex-redis-data) na hub-alfa i prod-alfa, --network host + redis-server --bind <TS_IP> --port 6380 (hub 100.102.29.119, prod 100.78.87.88).
- Spuštěno přes
docker run (NE deploy.sh — nemá manifest; deploy-guard tvrdě blokuje docker compose na hub/prod). Recreate = docker rm -f cortex-redis + stejný docker run --network host … (viz secrets/heslo).
- ⚠️ MUSÍ být
--network host (ne -p published port) — root cause timeoutu: Docker published-port dělá DNAT → odpověď z containeru se conntrackem un-DNAT-uje na source=TS_IP (∈ 100.64.0.0/10) a jde ven tailscale0 → Tailscale ts-forward chain má DROP out=tailscale0 source=100.64.0.0/10 (anti-loop, běží ve FORWARD PŘED docker/ufw) → odpověď zahozena → externí peer timeout. ufw route/DOCKER-USER to NEspraví (drop je Tailscaleův, na návratu). --network host + bind na TS IP → traffic je INPUT (do hostu), ne FORWARD/DNAT → ts-forward se neúčastní. (Zjištěno+opraveno cs timeout 2026-07-13; viz memory feedback_docker_ufw_routed_gotcha.)
- ⚠️ REÁLNÁ brána pro tailscale klienty = Tailnet ACL, NE UFW:
ts-input chain má ACCEPT all in=tailscale0 PŘED ufw chainy → cokoliv, co dorazí na tailscale0, je přijato bez ohledu na UFW (UFW allow pro Cortex je fakticky no-op). Tagged devices (cortex=tag:cortex, cerebro=tag:dev) filtruje tailscaled ACL na přijímací straně (drop PŘED tailscale0 → tcpdump nic neukáže, tailscale ping projde, TCP timeout). Nutný grant v admin console: {"src": ["tag:cortex"], "dst": ["100.102.29.119", "100.78.87.88"], "ip": ["tcp:6380"]} (grants syntax; dst přes IP — hub/prod jsou netagované user-owned stroje, tag:hub/prod na nich neexistují; user-owned zdroje jedou přes autogroup:member → *). Aplikováno 2026-07-13, ověřeno cs backfillem. Bind na TS IP (ne 0.0.0.0) drží port veřejně zavřený z internetu.
- Hesla per-env:
/root/secrets/cortex-redis/{hub,prod}.env (silná, ne changeme123). Connstringy předány badwolf+cs inline relayem.
- badwolf (konzument, s60-network bridge container) → connectuje na host TS IP
100.78.87.88:6380 přes REDIS_BUS_URL. ⚠️ Container→host-TS-IP jde přes INPUT se source docker subnet → UFW default deny ho dropne (allow byl jen pro Cortex) → ETIMEDOUT. Nutné ufw allow from 172.18.0.0/16 to any port 6380 (s60-network subnet). (Pozn.: „docker network connect s60-network cortex-redis" NEfunguje — host-network container nejde připojit na bridge; proto UFW allow pro subnet.) cs/Cortex (producent) connect z 100.120.98.59 přes Tailscale (ACL grant).
- Fronta design (název/payload/idempotence/DLQ) = badwolf+cs spec (DEC-005 vzor). Dev Redis na Cerebru = infra (T-20260713-058), ne sentinel.
Auth
- Heslo:
changeme123 (dev/cerebro) — nebo per-server v /root/secrets/
- Container:
s60-redis (Docker)
Použití
| Co |
Kde |
| BullMQ queues |
mail (s60-mail), badwolf (jobs), billit (export jobs) |
| Token blacklist |
s60auth (@s60/auth-sdk checkuje při validaci JWT) |
| Cache |
obecná |
| Pub/sub |
agent komunikace, memory pipeline |
| Server lifecycle keys |
be:status, be:maintenance_by, be:last_action (Main agent) |
Klíče (BE server lifecycle)
| Key |
Value |
be:status |
running \| stopped \| starting \| deploying \| maintenance |
be:maintenance_by |
jméno agenta |
be:last_action |
audit log JSON |
be:action_history |
last 100 actions |
Příkazy
# Cerebro
docker exec s60-redis redis-cli -a changeme123 GET be:status
# Hub
ssh root@100.102.29.119 "docker exec s60-redis redis-cli -a <hub-pwd> KEYS '*'"
Klíčová pravidla
- AOF persistence zapnutá — data nezmizí při restartu
- Named volume —
redis-data
- Heslo nikdy v plain logu (vždy
--no-auth-warning)