Architektura
Infrastruktura — přehled
graph TB
subgraph Hetzner
Sentinel["🔴 Sentinel<br/>Orchestrace, deploy<br/>49.13.168.234"]
HubAlfa["🔵 Hub-alfa<br/>Staging<br/>178.104.40.167"]
ProdAlfa["🟢 Prod-alfa<br/>Produkce<br/>178.104.36.211"]
end
subgraph VPSFree
Argus["📊 Argus<br/>Monitoring + Backup<br/>100.110.6.46"]
end
subgraph Hetzner-AX41
Cerebro["🧠 Cerebro<br/>Dev server<br/>100.72.164.58"]
end
subgraph DigitalOcean
DOPG[("🐘 DO Managed PG<br/>PostgreSQL")]
end
subgraph Offsite
Backup["💾 Offsite Storage<br/>(Hetzner Storage Box)<br/>TODO"]
end
Sentinel -->|"SSH + deploy"| HubAlfa
Sentinel -->|"SSH + deploy"| ProdAlfa
Sentinel <-->|"Relay API<br/>port 3020"| Cerebro
Sentinel -->|"monitoruje"| Argus
Argus -->|"pg_dump (RO)"| HubAlfa
Argus -->|"pg_dump (RO)"| ProdAlfa
Argus -->|"záloha Sentinel"| Sentinel
Argus -->|"offsite kopie"| Backup
HubAlfa --> DOPG
ProdAlfa --> DOPG
style Sentinel fill:#ff4444,color:#fff
style HubAlfa fill:#4488ff,color:#fff
style ProdAlfa fill:#44aa44,color:#fff
style Argus fill:#aa44aa,color:#fff
style Cerebro fill:#ff8800,color:#fff
Deploy flow
sequenceDiagram
participant Agent as App Agent
participant Relay as Relay API
participant Sentinel
participant Hub as Hub-alfa
participant Prod as Prod-alfa
Agent->>Relay: Deploy request<br/>(db_change, migration, commit)
Relay->>Sentinel: Message notification
Sentinel->>Sentinel: git pull (na Sentinelu)
Sentinel->>Sentinel: Připravit secrets (.env)
rect rgb(40, 60, 120)
Note over Sentinel,Hub: Staging deploy
Sentinel->>Hub: rsync source + .env
Sentinel->>Hub: docker compose build
Sentinel->>Hub: docker compose down + up
Hub-->>Sentinel: Health check OK
Sentinel->>Sentinel: E2E testy (smoke/standard)
end
rect rgb(40, 80, 40)
Note over Sentinel,Prod: Production deploy
Sentinel->>Prod: rsync source + .env
Sentinel->>Prod: docker compose build
Sentinel->>Prod: docker compose down + up
Prod-->>Sentinel: Health check OK
Sentinel->>Sentinel: E2E smoke test
end
Sentinel->>Relay: Deploy report → PM
Sentinel->>Relay: Status → App Agent
Služby na Hub-alfa (staging)
graph LR
Internet((Internet)) --> Nginx
subgraph Hub-alfa
Nginx["Nginx<br/>reverse proxy<br/>+ SSL"]
subgraph Docker[Docker / s60-network]
AuthBE["S60Auth<br/>Backend<br/>:3002"]
AuthFE["S60Auth<br/>Frontend<br/>:3003"]
Pulse["S60 Pulse<br/>:3100"]
Mail["S60Mail<br/>:3010"]
N8N["N8N<br/>:5678"]
Redis[("Redis<br/>:6379")]
end
end
DOPG[("DO Managed PG")]
Nginx -->|auth.s60hub.cz| AuthBE
Nginx -->|auth.s60hub.cz| AuthFE
Nginx -->|pulse.s60hub.cz| Pulse
Nginx -->|n8n.s60hub.cz| N8N
AuthBE --> Redis
AuthBE --> DOPG
Pulse --> Redis
Pulse --> DOPG
Mail --> Redis
Mail --> DOPG
N8N --> Redis
N8N --> DOPG
style Nginx fill:#44aa44,color:#fff
style Redis fill:#cc3333,color:#fff
style DOPG fill:#336699,color:#fff
Služby na Prod-alfa (produkce)
graph LR
Internet((Internet)) --> Nginx
subgraph Prod-alfa
Nginx["Nginx<br/>reverse proxy<br/>+ SSL"]
subgraph Docker[Docker / s60-network]
AuthBE["S60Auth<br/>Backend<br/>:3002"]
AuthFE["S60Auth<br/>Frontend<br/>:3003"]
Pulse["S60 Pulse<br/>:3100"]
Mail["S60Mail<br/>:3010"]
N8N["N8N<br/>:5678"]
Redis[("Redis<br/>:6379")]
end
end
DOPG[("DO Managed PG")]
Nginx -->|auth.studio60.cz| AuthBE
Nginx -->|auth.studio60.cz| AuthFE
Nginx -->|pulselab.cz| Pulse
Nginx -->|n8n.studio60.cz| N8N
AuthBE --> Redis
AuthBE --> DOPG
Pulse --> Redis
Pulse --> DOPG
Mail --> Redis
Mail --> DOPG
N8N --> Redis
N8N --> DOPG
style Nginx fill:#44aa44,color:#fff
style Redis fill:#cc3333,color:#fff
style DOPG fill:#336699,color:#fff
Backup architektura
graph TB
subgraph Produkce
HubDB["Hub-alfa DB<br/>auth, pulse, mail, n8n"]
ProdDB["Prod-alfa DB<br/>auth, pulse, mail, n8n"]
end
subgraph Sentinel
Secrets["Secrets<br/>SSH klíče<br/>Agent memory"]
end
subgraph Argus["Argus (VPSFree)"]
Cron["Cron<br/>denně 02:00"]
Store["Lokální zálohy<br/>7 denních + 4 týdenní"]
Grafana["Grafana<br/>monitoring"]
end
subgraph Offsite["Offsite (mimo DO)"]
HetznerSB["Hetzner Storage Box<br/>rsync"]
end
subgraph Monitor
SentinelMon["Sentinel<br/>kontrola + test restore"]
end
Cron -->|"pg_dump (RO)"| HubDB
Cron -->|"pg_dump (RO)"| ProdDB
Cron -->|"rsync"| Secrets
Cron --> Store
Store -->|"rsync offsite"| HetznerSB
SentinelMon -->|"ověřuje integritu"| Store
SentinelMon -->|"měsíční restore test"| Store
style Cron fill:#aa44aa,color:#fff
style Store fill:#4488ff,color:#fff
style HetznerSB fill:#ff8800,color:#fff
style SentinelMon fill:#ff4444,color:#fff
DB izolace
graph TB
subgraph DO-Managed-PG["DO Managed PostgreSQL"]
subgraph Dev["Dev (Cerebro)"]
DevAuth["s60_auth"]
DevPulse["s60_pulse"]
DevMail["s60_badwolf"]
end
subgraph Hub["Hub-alfa (staging)"]
HubAuth["s60_auth_hub<br/>s60_hub_user"]
HubPulse["s60_pulse_hub<br/>s60_pulse_hub_user"]
HubMail["s60_mail_hub<br/>s60_mail_hub_user"]
HubN8N["s60_n8n_hub<br/>s60_n8n_hub_user"]
end
subgraph Prod["Prod-alfa (produkce)"]
ProdAuth["s60_auth_prod<br/>s60_prod_user"]
ProdPulse["s60_pulse_prod<br/>s60_pulse_prod_user"]
ProdMail["s60_mail_prod<br/>s60_mail_prod_user"]
ProdN8N["s60_n8n_prod<br/>s60_n8n_prod_user"]
end
end
Dev -.->|"ŽÁDNÝ přístup"| Hub
Dev -.->|"ŽÁDNÝ přístup"| Prod
Hub -.->|"ŽÁDNÝ přístup"| Prod
style Dev fill:#ff8800,color:#fff
style Hub fill:#4488ff,color:#fff
style Prod fill:#44aa44,color:#fff
Komunikace agentů
graph LR
subgraph Cerebro
Main["main"]
PM["pm"]
Auth["auth"]
Pulse["pulse"]
BW["badwolf"]
Venom["venom"]
MailAgent["mail"]
Infra["infra"]
Relay["Relay API<br/>:3020"]
end
Sentinel["🔴 Sentinel"]
Fess["fess"]
Main <--> Relay
PM <--> Relay
Auth <--> Relay
Pulse <--> Relay
BW <--> Relay
Venom <--> Relay
MailAgent <--> Relay
Infra <--> Relay
Sentinel <-->|"HTTP<br/>Tailscale"| Relay
Fess <--> Relay
style Sentinel fill:#ff4444,color:#fff
style Relay fill:#44aa44,color:#fff