type: concept
title: "Теоретическая модель кластера платформы"
version: 0.1.0
date: 2026-04-02
status: draft
Все серверы связаны через WireGuard VPN. Топология — звезда с центром в Ядре.
ИНТЕРНЕТ
│
┌────────────┼────────────┐
▼ ▼ ▼
:80/:443 :80/:443 :22/:51820
│ │
┌─────────┴──────┐ ┌──┴──────────────────┐
│ ЯДРО │ │ ИСПОЛНИТЕЛЬ × N │
│ DEV-PRO │ │ pm-platform │
│ EU │ │ РФ │
│ 10.10.0.1 │ │ 10.10.0.10 │
│ │ │ │
│ WireGuard HUB │◄─► WireGuard CLIENT │
└────────────────┘ └─────────────────────┘
Новый исполнитель → wg: 10.10.0.11, 10.10.0.12 ...
ЧЕРЕЗ VPN (закрыто снаружи):
Portainer Agent → Portainer Server :9001
Backup Agent → Restic Server :8000
Uptime Kuma → healthcheck сервисов :9001
git pull/push → Gitea :3000
НАПРЯМУЮ (открыто снаружи):
Пользователи → Исполнитель :80/:443
Оператор → SSH :22
Let's Encrypt → ACME challenge :80
Claude Code → Anthropic API outbound
ТОЛЬКО ВНУТРИ СЕРВЕРА (не выходит):
PostgreSQL :5432
Redis :6379
внутренние UI → через reverse proxy
ЯДРО (DEV-PRO):
ОТКРЫТО: 22 (SSH), 80 (HTTP), 443 (HTTPS), 51820/udp (WireGuard)
ЗАКРЫТО: всё остальное
ИСПОЛНИТЕЛЬ (pm-platform и др.):
ОТКРЫТО: 22 (SSH аварийный), 80 (HTTP), 443 (HTTPS)
ЗАКРЫТО: 5432, 6379, 9000, всё остальное
BASE (ставится первым, везде одинаковый)
├── Portainer Agent → подключается к Portainer Server по VPN
├── WireGuard → клиент (или сервер на Ядре)
├── Nginx local → роутинг сервисов этого сервера
└── Backup Agent → restic → Beget S3
CORE (критично — падёт = платформа умерла):
├── PostgreSQL → питает Gitea + Authelia
├── Gitea → git, источник истины
├── Authelia → SSO для всех UI
└── Nginx → главный домен, SSL
NET (сетевые):
├── WireGuard Server → VPN хаб
└── Certbot → SSL сертификаты
OPS (управление):
├── Portainer Server → центральный UI контейнеров
├── Uptime Kuma → мониторинг
└── Telegram Bot → алерты
BACKUP (резервирование):
├── Restic Server → принимает бэкапы от агентов
└── S3 Client → отправляет в Beget S3
CREATOR
├── Claude Code → интерактивный терминал
└── workspace/
├── architect/ rw
├── library/ rw
├── system/ rw
└── infra/ rw
PROJECTOR
├── Claude Code → интерактивный терминал
└── workspace/
├── projects/ rw
├── architect/ ro
├── library/ ro
└── infra/ ro
EXECUTOR (на каждом исполнителе свой)
├── Nginx + Certbot → домены проектов, SSL
├── PostgreSQL → БД проектов этого исполнителя
├── Redis → кэш, очереди
├── MinIO → S3 для медиа (опционально)
└── project-* стеки → сервисы проектов клиентов
Создатель (Claude Code)
│
├─ редактирует architect/standards/...
├─ git commit + git push → Gitea
│
└─ Проектор при следующей сессии:
git pull → получает обновление
Проектор (Claude Code)
│
├─ git clone шаблон → projects/org/shop-x/
├─ настройка docker-compose.yml + .env
├─ git push → Gitea (project-shop-x.git)
│
├─ на Исполнителе (через Portainer API или SSH по VPN):
│ git clone Gitea → /opt/shop-x-stack/
│ docker compose up -d
│
├─ Nginx: добавить домен → shop-x.ru → контейнер
├─ Certbot: выпустить SSL
│
└─ Проверка: curl -I https://shop-x.ru → 200 OK
Создатель пишет код
│
├─ ветка: git checkout -b feature/catalog
├─ код → projects/org/shop-x/modules/catalog/
├─ git push → Gitea (feature ветка)
│
├─ тест на dev-стеке Исполнителя:
│ git pull (feature) → docker compose up --build
│ → shop-x.dev.0kt.ru
│
├─ git merge → main → git push
│
└─ прод:
git pull (main) → docker compose up --build
→ shop-x.ru
Uptime Kuma (каждые 60 сек проверяет)
│
├─ shop-x.ru → 502 (3 раза подряд)
│
├─ Telegram: "DOWN: shop-x.ru — 14:32"
│
└─ Оператор:
ssh 10.10.0.10 (VPN)
cd /opt/shop-x-stack
docker compose ps → смотрит что упало
docker compose logs -f → читает ошибку
docker compose restart → перезапускает
curl -I https://shop-x.ru → 200 OK
Telegram: "UP: shop-x.ru — downtime 3m"
На каждом сервере (Backup Agent):
│
├─ pg_dump всех БД → /var/backups/
├─ restic backup /mnt/data/ → Beget S3
├─ restic backup /opt/*-stack/ → Beget S3
│
└─ Ядро дополнительно:
git mirror → GitHub (страховка Gitea)
Потерян ИСПОЛНИТЕЛЬ:
├─ заказать новый VPS (~5 мин)
├─ ./setup.sh --profile executor (~15 мин)
├─ restic restore /mnt/data/ (~20 мин)
├─ git clone стеки проектов из Gitea
├─ docker compose up -d
├─ DNS → новый IP
└─ Итого: ~45-60 минут
Потеряно ЯДРО (худший случай):
├─ заказать новый VPS EU (~5 мин)
├─ ./setup.sh --profile core (~15 мин)
├─ restic restore Gitea data (~20 мин)
├─ восстановить WireGuard конфиг
├─ Исполнители переподключаются автоматически
└─ Итого: ~45 минут. Проекты всё время живут.
┌─────────────────────────────────────┐
│ ОДИН СЕРВЕР │
│ 4 CPU / 8 GB / 80 GB │
│ │
│ BASE + МАТКА + СОЗДАТЕЛЬ + │
│ ПРОЕКТОР + ИСПОЛНИТЕЛЬ │
│ │
│ Всё вместе. Риск: SPOF полный. │
│ Для: 1-2 проекта, старт. │
└─────────────────────────────────────┘
Порядок установки: PostgreSQL → Nginx → Gitea → Portainer → Uptime Kuma → Restic → первый проект
┌───────────────────┐ ┌───────────────────┐
│ ЯДРО (EU) │ │ ИСПОЛНИТЕЛЬ (РФ) │
│ DEV-PRO │VPN │ pm-platform │
│ │◄──►│ │
│ BASE + МАТКА │ │ BASE + EXECUTOR │
│ СОЗДАТЕЛЬ │ │ проекты клиентов │
│ ПРОЕКТОР │ │ │
└───────────────────┘ └───────────────────┘
Что даёт: изоляция рантайма от управления. Нагрузка проектов не мешает Ядру.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ ЯДРО (EU) │ │ ПРОЕКТОР │ │ ИСПОЛНИТЕЛЬ │
│ │ │ (РФ) │ │ (РФ) │
│ BASE │ │ BASE │ │ BASE │
│ МАТКА │ │ OPS стек │ │ EXECUTOR │
│ СОЗДАТЕЛЬ │ │ ПРОЕКТОР │ │ проекты │
└──────────────┘ └──────────────┘ └──────────────┘
Что даёт: мониторинг и управление независимы от Ядра и рантайма.
┌──────────┐
│ ЯДРО │ (один, EU)
└────┬─────┘
│
┌─────────┴─────────┐
│ │
┌───┴──────┐ ┌─────┴────┐
│ПРОЕКТОР │ │ПРОЕКТОР │
│ (наш) │ │(клиента) │
└───┬──────┘ └─────┬────┘
│ │
┌───┴──┬──────┐ ┌─────┴────┐
│EXEC-1│EXEC-2│ │ EXEC-C │
│РФ │РФ │ │ VPS клиента│
└──────┴──────┘ └──────────┘
Масштабируется горизонтально: +1 VPS = +N проектов.
РЕПЛИЦИРОВАТЬ — не нужно на текущем масштабе (< 10 проектов).
Оправдано при SLA-контрактах или revenue > $5000/мес.
БЭКАПИТЬ (достаточно):
├── PostgreSQL: pg_dump каждые 6ч → Beget S3
├── Gitea repos: push mirror → GitHub (каждые 8ч)
├── Медиа проектов: restic ежедневно → Beget S3
├── Docker compose: в git (уже есть)
├── Конфиги nginx: в git или restic
└── SSH ключи: restic → S3 (шифрованно)
| Что упало | Последствия | Восстановление |
|---|---|---|
| Nginx на EXEC | Все сайты 502 | restart → 30 сек |
| PostgreSQL (проекты) | Сайты с БД down | restart → 30 сек |
| PostgreSQL (Gitea) | Нет деплоев, сайты живут | restore из бэкапа → 30 мин |
| Gitea | Нет git push/pull | restore → 30 мин |
| WireGuard | Нет VPN, сайты живут | restart → 10 сек |
| Весь EXEC упал | Все проекты down | новый VPS + restore → 45-60 мин |
| Всё ЯДРО упало | Нет управления, сайты живут | новый VPS + restore → 45 мин |
| Anthropic API | Claude Code не работает | OpenRouter как fallback |
Если потеряно полностью — управление стоит, проекты живут.
Митигация:
- pg_dump каждые 6ч в Beget S3
- Gitea push mirror → GitHub
- Задокументированный runbook восстановления
- Конфиги WireGuard в бэкапе
| Компонент | Блок | Критичность | Место | Реплицировать |
|---|---|---|---|---|
| PostgreSQL (Gitea) | ЯДРО-CORE | FATAL | Ядро | Нет → бэкап |
| Gitea | ЯДРО-CORE | FATAL | Ядро | Нет → mirror |
| Nginx | BASE | FATAL на сервере | каждый | каждый свой |
| WireGuard | ЯДРО-NET | HIGH | Ядро | Нет |
| Authelia | ЯДРО-CORE | HIGH | Ядро | Нет |
| Portainer Server | МАТКА-OPS | HIGH | Ядро | Нет |
| Uptime Kuma | МАТКА-OPS | HIGH | Ядро/Проектор | Нет |
| PostgreSQL (проекты) | EXECUTOR | HIGH | каждый EXEC | Нет → бэкап |
| Claude Code | СОЗДАТЕЛЬ | HIGH | Ядро | Нет |
| Redis | EXECUTOR | MEDIUM | каждый EXEC | Нет |
| Certbot | EXECUTOR | MEDIUM | каждый EXEC | Нет |
| Restic | ЯДРО-BACKUP | MEDIUM | Ядро | Beget S3 |
| Telegram Bot | МАТКА-OPS | MEDIUM | Ядро | Нет |
| Планировщик | ПРОЕКТОР | MEDIUM | Проектор | Нет |
| docs (md-viewer) | ЯДРО | LOW | Ядро | Нет |
| MinIO | EXECUTOR | LOW | EXEC (опционально) | Beget S3 |
| Portainer Agent | BASE | MEDIUM | каждый | N/A |
Версия: 0.1.0 draft