Přeskočit obsah

Serverová infrastruktura — Specifikace

Přehled

Veškerá serverová část platformy AVAX běží na vlastním Proxmox clusteru. Infrastruktura je rozdělena do specializovaných VM tak, aby každá VM měla jasnou odpovědnost, šla škálovat nezávisle a výpadek jedné části neohrozil celý systém.

Proxmox cluster již provozuje S3 úložiště (https://s3.avaxis.cz) — ostatní VM se přidají do stejného clusteru.


Přehled VM a služeb

┌─────────────────────────────────────────────────────────────────────┐
│  PROXMOX CLUSTER (4 uzly, HA aktivní)                               │
│                                                                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────┐  │
│  │  vm-gateway  │  │  vm-api      │  │  vm-db                   │  │
│  │              │  │              │  │                           │  │
│  │  Nginx       │  │  FastAPI     │  │  PostgreSQL + pgvector    │  │
│  │  SSL termin. │  │  WebSocket   │  │  Redis                   │  │
│  │  Load bal.   │  │  Gateway     │  │                           │  │
│  └──────────────┘  └──────────────┘  └──────────────────────────┘  │
│                                                                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────┐  │
│  │  vm-worker   │  │  vm-ai       │  │  vm-monitor              │  │
│  │              │  │              │  │                           │  │
│  │  Celery      │  │  AI Service  │  │  Prometheus              │  │
│  │  Background  │  │  RAG engine  │  │  Grafana                 │  │
│  │  jobs        │  │  Ollama CPU  │  │  Loki (logy)             │  │
│  └──────────────┘  └──────────────┘  └──────────────────────────┘  │
│                                                                     │
│  ┌──────────────┐  ┌──────────────┐  (již existuje)                 │
│  │  vm-gpu      │  │  vm-s3       │  MinIO / Ceph                   │
│  │              │  │              │                                 │
│  │  Ollama GPU  │  │  https://    │  s3://avaxis/...               │
│  │              │  │  s3.avaxis.cz│                                 │
│  │  NVIDIA GPU  │  │  30 TB       │                                 │
│  │  LLM inference│ └──────────────┘                                 │
│  └──────────────┘                                                   │
└─────────────────────────────────────────────────────────────────────┘

vm-gateway — Vstupní bod

OS: Debian 12 | RAM: 2 GB | CPU: 2 vCPU | Disk: 20 GB

Nginx (reverse proxy + SSL terminace)
  • Přijímá veškerý HTTPS provoz (port 443)
  • Certifikáty: Let's Encrypt (certbot auto-renewal)
  • Routování:
      api.avaxis.cz      → vm-api:8000
      admin.avaxis.cz    → vm-api:8000/admin
      ws.avaxis.cz       → vm-api:8001 (WebSocket)
      avaxis.cz          → webhosting (statický Next.js build nebo Vercel)
  • Rate limiting (ochrana před DDoS)
  • Gzip komprese odpovědí
  • HTTP → HTTPS redirect

vm-api — Hlavní API server

OS: Debian 12 | RAM: 4–8 GB | CPU: 4 vCPU | Disk: 40 GB

FastAPI aplikace (Python 3.12)

Moduly (viz jednotlivé spec soubory):
  /auth/         → přihlášení, JWT, refresh, 2FA
  /org/          → firmy, uživatelé, role, oprávnění
  /catalog/      → aplikace, verze, kanály, download URLs
  /sync/         → manifest sync, presigned URLs pro zálohy
  /backup/       → snapshoty, GC scheduling
  /chat/         → konverzace, zprávy, moderace
  /support/      → tikety, agenti, znalostní báze
  /admin/        → portál Avaxis (super admin)
  /notifications/→ push notifikace, e-maily
  /webhooks/     → Stripe platební webhooky

Technologie:
  • FastAPI + Uvicorn (ASGI server)
  • SQLAlchemy 2.0 (async ORM)
  • Alembic (DB migrace)
  • Pydantic v2 (validace)
  • boto3 (S3 komunikace)
  • httpx (async HTTP klient pro Claude API)

WebSocket Gateway (port 8001)

Samostatný Uvicorn worker pro WebSocket spojení
  • Správa WS spojení per uživatel
  • Subscribe/unsubscribe na Redis Pub/Sub kanály
  • Broadcast skupiny → Redis fan-out
  • Malé konverzace → přímé doručení
  • Heartbeat kontrola spojení (30s)
  • Reconnect logika pro klienty

Konfigurace procesu

Supervisor nebo systemd spravuje procesy:
  avaxis-api      → uvicorn main:app --port 8000 --workers 4
  avaxis-ws       → uvicorn ws:app   --port 8001 --workers 2

vm-db — Datové úložiště

OS: Debian 12 | RAM: 8–16 GB | CPU: 4 vCPU | Disk: 200 GB SSD

PostgreSQL 16

Hlavní relační databáze celé platformy.

Databáze: avaxis_prod

Klíčová rozšíření:
  pgvector    → vektorové embeddingy pro RAG (znalostní báze, support)
  uuid-ossp   → generování UUID
  pg_trgm     → trigram full-text search (vyhledávání uživatelů)

Schéma (dle spec souborů):
  Firmy a uživatelé:   companies, users, company_roles, app_assignments
  Auth a 2FA:          audit_log, tfa_qr_sessions, tfa_backup_codes
  Katalog:             apps, app_versions, app_version_files, app_installs
  Předplatné:          company_subscriptions, subscription_history
  Zálohy:              backup_snapshots, company_storage, sync_state
  Chat:                conversations, messages, message_reactions,
                       message_attachments, conversation_members
  Support:             support_tickets, support_agents, ticket_notes,
                       ticket_transfers, kb_articles
  Portál:              company_registrations, platform_settings,
                       gdpr_consents, gdpr_requests
  Notifikace:          portal_notifications

Výkon a indexy:
  • Kritické indexy na users(email), users(company_id), messages(conversation_id)
  • login_history partitioned by month (miliony řádků)
  • GIN index na users pro full-text search

Záloha PostgreSQL:
  • pg_dump denně ve 01:00 → komprimovaný dump → upload na S3
  • WAL archivace pro point-in-time recovery
  • Zálohy uloženy: s3://avaxis/system/db-backups/

Redis 7

Použití:
  Chat Pub/Sub    → kanály conv_{id} pro broadcast skupiny
  Session cache   → refresh tokeny, 2FA session tokeny
  Rate limiting   → počítadla per IP, per user
  Task queue      → fronty pro Celery (vm-worker)
  Presence        → kdo je online (support agenti, WS spojení)

Konfigurace:
  maxmemory 2gb
  maxmemory-policy allkeys-lru
  appendonly yes  (persistence pro session data)

Záloha Redis:
  • RDB snapshot každou hodinu → S3

pgvector — vektorová databáze (součást PostgreSQL)

Tabulky s vektory:
  kb_articles.embedding  vector(1536)  → embeddingy FAQ článků
  support_tickets.embedding vector(1536) → embeddingy vyřešených tiketů

Index:
  CREATE INDEX ON kb_articles USING ivfflat (embedding vector_cosine_ops)
  WITH (lists = 100);

Alternativa — Qdrant (samostatná služba):
  Pokud pgvector nedostačuje výkonnostně (>100k dokumentů),
  přejít na Qdrant jako samostatný kontejner na vm-db.

vm-worker — Background Jobs

OS: Debian 12 | RAM: 4 GB | CPU: 4 vCPU | Disk: 40 GB

Celery worker zpracovává asynchronní úlohy aby neblokoval API.

Fronty a workery

Celery s Redis jako broker:

  Fronta: default (obecné úlohy)
    • Odeslání e-mailů (registrace, CSAT výzva, notifikace)
    • Push notifikace (desktop, web push)
    • Výpočet velikosti S3 bucketu per firma
    • Embedding nových KB článků (pgvector)

  Fronta: ai (AI úlohy — pomalejší, izolované)
    • Generování AI návrhu odpovědi (Claude API)
    • AI fallback odpověď mimo pracovní dobu
    • Embedding nových tiketů pro RAG

  Fronta: gc (Garbage Collector — nízká priorita)
    • Označení expirovaných záloh (status → expired)
    • Fyzické mazání pending_delete ze S3
    • Archivace starých chat zpráv
    • Mazání expirovaných log souborů

  Fronta: scheduled (periodické úlohy — Celery Beat)
    • Každou hodinu:    Kontrola expirujících předplatných
    • Každé 4 hodiny:  Tray notifikace "prosím restartujte"
    • Denně 01:00:     pg_dump záloha PostgreSQL
    • Denně 02:00:     Automatické zálohy dat firem (Standard plán)
    • Denně 03:00:     GC job (mazání pending_delete)
    • Denně 04:00:     Přepočet company_storage (S3 ListObjects)
    • Každých 6 hodin: Automatické zálohy dat firem (Premium plán)
    • Týdně:           Upozornění na překročení soft limitu storage

E-mailová služba

Provider: vlastní SMTP server mail.avaxis.cz
Šablony: Jinja2 HTML šablony pro každý typ e-mailu

Konfigurace:
  SMTP host:  mail.avaxis.cz
  Port:       587 (STARTTLS) nebo 465 (SSL)
  From:       noreply@avaxis.cz

Typy e-mailů:
  Registrace:         Potvrzení e-mailu, vítejte
  Auth:               Reset hesla, 2FA deaktivace administrátorem
  Předplatné:         Expirace trial, expirace předplatného, obnova
  Support:            Nový tiket přijat, tiket vyřešen, CSAT výzva
  Zálohy:             Kritické překročení storage limitu
  Portál:             Nová registrace firmy (Avaxis admini)

vm-gpu — GPU server pro LLM inference

OS: Debian 12 | RAM: 32 GB | CPU: 8 vCPU | GPU: NVIDIA (dedicated)

Dedikovaný GPU server pro rychlou lokální LLM inferenci. GPU akceleruje Ollama inference 10–50× oproti CPU — lokální modely dosahují srovnatelné latence s Claude API.

Ollama (GPU režim):
  Modely:
    nomic-embed-text   → embeddingy (velmi rychlé na GPU, ~1ms)
    llama3.2:3b        → rychlé klasifikace, shrnutí
    mistral:7b-instruct → kvalitní drafty odpovědí (čeština)

  GPU memory alokace (příklad NVIDIA RTX 4090 / 24 GB VRAM):
    mistral:7b-q4      → ~5 GB VRAM
    llama3.2:3b-q4     → ~2 GB VRAM
    embed model        → ~0.5 GB VRAM
    Rezerva            → ~16.5 GB (více modelů souběžně)

  API (interní):
    http://vm-gpu:11434/api/generate
    http://vm-gpu:11434/api/embeddings

Paralelní zpracování:
  GPU zvládá více requestů souběžně (batching)
  → Vhodné pro špičky (mnoho tiketů najednou)

vm-ai — AI Service (orchestrace)

OS: Debian 12 | RAM: 8 GB | CPU: 4 vCPU | Disk: 40 GB

Orchestrační vrstva — rozhoduje kdy použít GPU/lokální model nebo Claude API. API klíče jsou pouze zde. Izolace od hlavního API pro bezpečné zacházení s klíči.

AI Service (FastAPI microservice)

Interní API (dostupné pouze vm-api, ne zvnějšku):
  POST /ai/support-draft
       Body: { ticket_id, customer_message }
       → vyhledá podobné tikety + KB články (RAG)
       → zavolá Claude API
       → vrátí { draft, sources: [{type, id, title, relevance}] }

  POST /ai/offline-response
       Body: { ticket_id, customer_message }
       → stejný RAG + Claude pipeline
       → vrátí automatickou odpověď pro zákazníka mimo prac. dobu

  POST /ai/embed
       Body: { text, document_id, document_type }
       → vygeneruje embedding → uloží do pgvector

  POST /ai/search
       Body: { query, limit, filters }
       → embed dotaz → cosine similarity search → vrátí top-N dokumentů

RAG Pipeline

1. INDEXOVÁNÍ (při přidání nového dokumentu):
   Nový KB článek nebo vyřešený tiket
     → ai/embed → OpenAI Embeddings API nebo lokální model
     → uloží vector do kb_articles.embedding (pgvector)

2. VYHLEDÁVÁNÍ (při příchodu nového tiketu):
   Zákazníkova zpráva → embed
     → SELECT ... ORDER BY embedding <=> query_vector LIMIT 5
     → vrátí top-5 nejpodobnějších dokumentů

3. GENEROVÁNÍ (Claude API):
   System prompt:
     "Jsi asistent support týmu AVAX. Na základě kontextu níže
      připrav návrh odpovědi zákazníkovi. Buď konkrétní, přátelský,
      piš česky. Neposílej odpověď přímo — je to návrh pro agenta."

   Context:
     { customer_message, similar_tickets[5], kb_articles[3] }

   Výstup:
     { draft_response, confidence, sources_used }

Hybridní LLM strategie — lokální + online

Princip: lokální model vždy prvně, Claude API jen kdy je to potřeba.
Výhody: nižší náklady, nižší latence, funguje i při výpadku internetu.

┌─────────────────────────────────────────────────────────────────┐
│  ÚLOHA                    LOKÁLNÍ MODEL      CLAUDE API         │
├─────────────────────────────────────────────────────────────────┤
│  Embeddingy (RAG)         ✓ vždy lokálně     —                  │
│  Klasifikace tiketu       ✓ lokálně           —                  │
│  Jednoduchý AI draft      ✓ lokálně (zkusit)  ✓ fallback         │
│  Komplexní AI draft       —                   ✓ preferovat       │
│  AI offline odpověď       ✓ lokálně (rychle)  ✓ pokud dostupný   │
│  Shrnutí konverzace       ✓ lokálně           —                  │
│  Detekce jazyka           ✓ lokálně           —                  │
└─────────────────────────────────────────────────────────────────┘

Lokální modely (Ollama na vm-gpu)

Primárně běží na vm-gpu (GPU akcelerace).
vm-ai má CPU fallback Ollama pro případ nedostupnosti vm-gpu.

Embeddingy:  nomic-embed-text  → GPU: ~1ms, CPU fallback: ~20ms
Klasifikace: llama3.2:3b       → GPU: ~200ms, CPU fallback: ~3s
Drafty:      mistral:7b-q4     → GPU: ~2s, CPU fallback: ~30s

Použití GPU vs CPU Ollama:
  Normální provoz: vm-gpu (rychlý, preferovaný)
  vm-gpu nedostupný: vm-ai CPU Ollama (fallback, pomalejší)
  Oba nedostupní: Claude API jako záloha

Claude API (Anthropic)

Model: claude-sonnet-4-6 (výchozí), claude-haiku-4-5 (rychlé úlohy)
Použití: komplexní AI drafty, kvalitní odpovědi zákazníkům

Kdy se volá Claude:
  1. Lokální model vrátil nízkou confidence score (< 0.7)
  2. Tiket označen jako priorita 1 nebo 2 (kritický)
  3. Explicitní požadavek agenta "Zkus Claude"
  4. Lokální model nedostupný (fallback)

Kdy se NEVOLÁ Claude (šetření nákladů):
  1. Embeddingy — vždy lokálně
  2. Klasifikace kategorie tiketu — vždy lokálně
  3. Jednoduché FAQ dotazy s vysokou confidence

Prompt caching:
  System prompt (instrukce, kontext produktu) se cachuje
  → Anthropic účtuje cache read tokeny 10× levněji
  → Výrazná úspora při opakovaných voláních

AI Service API

Interní API (dostupné pouze vm-api, ne zvnějšku):

  POST /ai/support-draft
       Body: { ticket_id, customer_message, priority }
       → RAG vyhledávání (lokální embeddingy)
       → Pokud priority >= 2 nebo low confidence → Claude API
       → Jinak → lokální LLM
       → Vrátí: { draft, model_used, confidence, sources }

  POST /ai/offline-response
       Body: { ticket_id, customer_message }
       → RAG + lokální LLM (rychlá odpověď, bez čekání na API)
       → Pokud Claude dostupný → použij Claude pro lepší kvalitu
       → Vrátí: { response, model_used }

  POST /ai/classify
       Body: { text }
       → Lokální model klasifikuje kategorii tiketu
       → Vrátí: { category, confidence }

  POST /ai/embed
       Body: { text, document_id, document_type }
       → vm-gpu Ollama embeddingy → pgvector

  POST /ai/search
       Body: { query, limit, filters }
       → embed dotaz → cosine similarity → top-N dokumentů

RAG Pipeline

1. INDEXOVÁNÍ:
   Nový KB článek / vyřešený tiket
     → Ollama embed (lokální, rychlý)
     → uloží vector do pgvector

2. VYHLEDÁVÁNÍ:
   Zákazníkova zpráva → Ollama embed
     → SELECT ORDER BY embedding <=> query_vector LIMIT 5

3. GENEROVÁNÍ (hybridní):
   confidence = cosine_similarity(nejlepší shoda)

   if priority == CRITICAL or confidence < 0.7:
     → Claude API (nejlepší kvalita)
   else:
     → vm-gpu Ollama mistral:7b (rychlý, ~2s, levný)
     → pokud vm-gpu nedostupný → Claude API fallback

   System prompt (cachovaný u Claude):
     "Jsi asistent support týmu AVAX. Piš česky, profesionálně.
      Navrhni odpověď agentovi ke kontrole — neodesílej přímo."

   Výstup: { draft, model_used, confidence, sources_used }

vm-monitor — Monitoring a observabilita

OS: Debian 12 | RAM: 4 GB | CPU: 2 vCPU | Disk: 100 GB

Prometheus
  → scrape metriky z vm-api, vm-worker, vm-db, vm-ai
  → vlastní metriky: počet tiketů, délky front, AI latence,
    WS spojení, S3 upload/download rychlost

Grafana
  → dashboardy pro každou komponentu
  → alerty (e-mail + notifikace) při:
      API latence > 500ms
      Celery fronta > 100 úloh
      PostgreSQL connections > 80%
      Redis memory > 80%
      VM CPU > 90% po dobu 5 minut
      Chybová míra API > 1%

Loki + Promtail
  → agregace logů ze všech VM
  → full-text search v logách
  → propojení s Grafana (logy k metrikám)

Uptime monitoring
  → pravidelný ping /health endpointu API
  → notifikace pokud API nereaguje > 60s

Síťová architektura na Proxmox

Proxmox cluster (4+ uzly, HA aktivní — spravuje Proxmox)
  ├── Privátní síť (10.0.1.0/24) — interní komunikace VM
  │     vm-gateway  10.0.1.1
  │     vm-api      10.0.1.2
  │     vm-db       10.0.1.3
  │     vm-worker   10.0.1.4
  │     vm-ai       10.0.1.5
  │     vm-gpu      10.0.1.6   ← GPU server pro LLM
  │     vm-monitor  10.0.1.7
  │     vm-s3       10.0.1.10  (existující, 30 TB)
  └── Domény (DNS → veřejná IP vm-gateway):
        avaxis.cz        → Next.js web aplikace
        api.avaxis.cz    → REST API (FastAPI, port 8000)
        ws.avaxis.cz     → WebSocket gateway (port 8001)
        admin.avaxis.cz  → Správa portálu (super admini)
        mail.avaxis.cz   → existující SMTP (e-maily platformy)

Nginx routing na vm-gateway:
  api.avaxis.cz    → http://vm-api:8000
  ws.avaxis.cz     → http://vm-api:8001  (proxy_read_timeout 3600s)
  admin.avaxis.cz  → http://vm-api:8000/admin

Firewall pravidla:
  vm-gateway → vm-api:8000 (REST)          ✓
  vm-gateway → vm-api:8001 (WebSocket)     ✓
  vm-api     → vm-db:5432 (PostgreSQL)     ✓
  vm-api     → vm-db:6379 (Redis)          ✓
  vm-api     → vm-ai:9000 (AI orchestrace) ✓
  vm-ai      → vm-gpu:11434 (Ollama GPU)   ✓
  vm-ai      → internet (Claude API)       ✓ (pouze odchozí)
  vm-api     → vm-s3:9000 (S3)             ✓
  vm-worker  → vm-db, vm-s3, vm-ai         ✓
  vm-monitor → všechny VM (Prometheus)     ✓
  Internet   → vm-gateway (443, 80)        ✓
  Internet   → ostatní VM                  ✗

Dostupnost a zálohy infrastruktury

S3 úložiště (vm-s3):
  Kapacita: 30 TB
  Odhad využití: 500 firem × 1 GB = 500 GB firemních dat
                 + app binárky, chat přílohy, logy, DB dumpy
  Rezerva: 30 TB je dostatečné pro několik let provozu

Databáze:
  PostgreSQL → denní pg_dump na S3 + WAL archivace (PITR)
               → obnovení do libovolného bodu v čase
  Redis      → RDB snapshot každou hodinu na S3

VM snapshoty (Proxmox):
  Každá VM → snapshot jednou týdně
  Uchovávat poslední 4 snapshoty (měsíc zpět)

High Availability:
  Proxmox HA je aktivní — při výpadku uzlu VM automaticky migruje.
  Není potřeba řešit na úrovni aplikace.

Technologické verze (doporučené)

Komponenta Verze Poznámka
Debian 12 (Bookworm) LTS, stabilní
Python 3.12 FastAPI, Celery
FastAPI 0.115+ async, Pydantic v2
PostgreSQL 16 pgvector podpora
pgvector 0.7+ ivfflat index
Redis 7.2 Pub/Sub, persistence
Nginx 1.24 reverse proxy
Celery 5.4 async workers
Claude API claude-sonnet-4-6 Komplexní AI drafty
Ollama 0.5+ Lokální LLM runtime
llama3.2 / mistral 3b / 7b-q4 Lokální generování
nomic-embed-text latest Lokální embeddingy

Rozhodnuté otázky

Otázka Rozhodnutí
Proxmox uzly 4+ fyzické uzly, libovolně rozšiřitelné
Proxmox HA Aktivní — neřešíme na úrovni aplikace
S3 kapacita 30 TB (vm-s3, existující) — dostatečné na roky
Domény avaxis.cz, api.avaxis.cz, ws.avaxis.cz, admin.avaxis.cz
E-mail Vlastní SMTP mail.avaxis.cz → noreply@avaxis.cz
GPU server vm-gpu přidán — Ollama GPU inference (10–50× rychlejší)
LLM strategie Hybridní: vm-gpu Ollama vždy první, Claude API pro komplexní
Embeddingy Vždy lokální na vm-gpu (nomic-embed-text, ~1ms)
Lokální LLM mistral:7b-q4 na GPU (~2s), llama3.2:3b pro klasifikace
Claude použití Priorita 1/2 nebo confidence < 0.7, prompt caching aktivní
CPU fallback vm-ai má CPU Ollama pro případ výpadku vm-gpu

Otevřené otázky

Všechny otázky k server-infrastructure.md jsou vyřešeny.


Poslední aktualizace: 2026-04-21