quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / changes (push) Successful in 4s
quality / docker-check (push) Skipped
quality / web (push) Successful in 57s
quality / api (push) Successful in 41s
CD / quality (push) Successful in 1m46s
CD / publish (push) Successful in 11m48s
Без type/scope semantic-release не ставил тег и пропускал bake.
81 lines
3.9 KiB
Markdown
81 lines
3.9 KiB
Markdown
# CDN Manager
|
||
|
||
Self-hosted панель **desired-state DNS** для флота CHR/VPS: канонические ноды (A/AAAA) + сервисные CNAME (failover / geo / ix), синхронизация с Cloudflare DNS-only.
|
||
|
||
## Vs CFDM
|
||
|
||
| CDNManager | Cloudflare Domain Manager |
|
||
|------------|---------------------------|
|
||
| Флот нод + алиасы + drift/orphan | Домены, сервисы, LB, health-checks, сертификаты |
|
||
| Роутинг-зона (напр. `rtnt.top`) | Мультидоменный ops |
|
||
| Retarget CNAME как основной UX | Service bindings / HC |
|
||
|
||
App id в auth-portal: **`cdn`**.
|
||
|
||
## Стек
|
||
|
||
- Monorepo: pnpm + turbo (`apps/*`, `packages/*`)
|
||
- `apps/web` — Vite + React + TanStack + shadcn **base-nova** + ReUI Frame
|
||
- `apps/api` — Fastify + Drizzle + SQLite
|
||
- Packages: `@cdnmanager/ui`, `@cdnmanager/shared`, `@cdnmanager/db`
|
||
|
||
## Доменная модель
|
||
|
||
- **Location** — справочник кодов (`msk`, `fra`, `ams`, `hel`, `par`)
|
||
- **Node** — канонический FQDN + A/AAAA (`msk-hub01.rtnt.top`)
|
||
- **Alias** — CNAME → node (`msk.rtnt.top`, `ix-eu.rtnt.top`)
|
||
- **Zone** — Cloudflare zone + naming template / TTL
|
||
- Managed-записи всегда **`proxied: false`** (туннели WG/GRE)
|
||
|
||
Нейминг: шаблон `{loc}-{role}{nn}.{zone}` (см. документ по CHR DNS).
|
||
|
||
## Команды
|
||
|
||
```bash
|
||
pnpm install
|
||
pnpm --filter @cdnmanager/shared build
|
||
pnpm --filter @cdnmanager/db build
|
||
pnpm --filter @cdnmanager/api dev # :8081
|
||
pnpm --filter web dev # :5176
|
||
pnpm --filter web build
|
||
```
|
||
|
||
Env: `CLOUDFLARE_API_TOKEN` (Zone DNS Edit + Zone Read). Локально `AUTH_REQUIRED=false`, логин `admin` / `admin`.
|
||
|
||
SSO (prod): [`docs/integrate-auth-portal.md`](docs/integrate-auth-portal.md) — `AUTH_REQUIRED=true`, общий `AUTH_JWT_SECRET` с portal, app id `cdn`.
|
||
|
||
Docker CLI на сервере: [`docs/deploy-traefik.md`](docs/deploy-traefik.md) (Traefik + HTTPS) · [`docs/deploy-docker.md`](docs/deploy-docker.md) (plain).
|
||
|
||
## UI (ReUI PRO + DNA CFDM)
|
||
|
||
Surface: **frame**. Contract: [`docs/ui-design-contract.md`](docs/ui-design-contract.md).
|
||
|
||
| Экран | Kit / pattern |
|
||
|-------|----------------|
|
||
| Dashboard | `OpsDashboard` + `KpiStatGrid` + `QuickActionGrid` + charts + `AttentionQueue` (как CFDM) |
|
||
| Ноды / Алиасы | `ResourcePage` |
|
||
| Топология | Frame grid + IconTile |
|
||
| Зоны / Sync | Frame Item rows + sync/apply/BIND export |
|
||
| Settings | `SettingsShell` (appearance + cloudflare) |
|
||
|
||
Preview: [stats-12](https://reui.io/preview/base/stats-12) · [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2) · [settings-16](https://reui.io/preview/base/settings-16) · [app-shell-12](https://reui.io/preview/base/app-shell-12).
|
||
|
||
MCP `user-reui` primary + `plugin-shadcn-shadcn` primitives. License: `REUI_LICENSE_KEY` в `apps/web/.env.local`.
|
||
|
||
## API (кратко)
|
||
|
||
```
|
||
GET/POST /api/v1/zones · POST .../sync · POST .../apply · GET .../export/bind
|
||
GET/POST /api/v1/nodes · GET/POST /api/v1/aliases · POST .../retarget
|
||
GET /api/v1/locations · GET /api/v1/dashboard/stats · GET /api/v1/topology
|
||
GET /api/v1/cloudflare/zones
|
||
```
|
||
|
||
## CI / Docker
|
||
|
||
Gitea: `.gitea/workflows/{ci,cd,quality}.yaml`. Образы: `deploy/docker` (`cdnmanager` + alias `cdn-manager`).
|
||
Prod: [`docs/deploy-traefik.md`](docs/deploy-traefik.md) — `deploy/docker-compose.traefik.yml` + `deploy/env.traefik.example`.
|
||
Без Traefik: [`docs/deploy-docker.md`](docs/deploy-docker.md) · Compose: `docker-compose.yml` / `deploy/compose/docker-compose.example.yaml`.
|
||
|
||
**Коммиты:** только Conventional Commits (`feat`/`fix`/… + русский subject). Иначе CD: `No releasable commits — skipping image publish`. См. [`.cursor/rules/commit-messages-ru.mdc`](.cursor/rules/commit-messages-ru.mdc), [`docs/releasing.md`](docs/releasing.md).
|