Files
DenozordecandCursor 5cf39880f8
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 8s
quality / changes (push) Successful in 8s
quality / web (push) Skipped
quality / docker-check (push) Skipped
quality / api (push) Successful in 1m20s
CD / quality (push) Successful in 1m31s
CD / publish (push) Successful in 2m4s
fix(services): сразу возвращать IP в DNS после первой успешной пробы
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 19:51:23 +07:00

7.1 KiB
Raw Permalink Blame History

Cloudflare Domain Manager

Wiki home — synced from repository on main when this file changes.

UI

Design contract (Frame surface, ReUI kit): docs/ui-design-contract.md

Overview

Manage Cloudflare zones, DNS records, domain groups, and TLS certificate expiry from a single UI.

Configuration

Variable Description
CLOUDFLARE_API_TOKEN API token: Zone.DNS и для Worker — Account Workers Scripts Write + Workers KV Storage Write
DATABASE_URL SQLite path (sqlite:/data/app.db)
JWT_SECRET JWT signing secret
ADMIN_USERNAME Admin username
ADMIN_PASSWORD_HASH Argon2 hash (empty = dev admin/admin)
LOG_LEVEL Уровень логов API (info, debug)
HEALTH_CHECK_CRON Cron для health-check (default 0 */2 * * * *). Переопределяется в Настройки → Health-check.
HEALTH_DEGRADED_FAILURES Ошибок подряд до degraded (default 1). То же в UI.
HEALTH_DOWN_FAILURES Ошибок подряд до down (default 2). То же в UI.
HEALTH_SUCCESS_RECOVERIES Успехов подряд для recovery CHECKING → HEALTHY (default 2). То же в UI.
HEALTH_LATENCY_WARN_MS Латентность-порог для degraded (default 1000). То же в UI.

Load balancing & health checks

Группа сервисов может иметь общий домен (service_groups.domain). Балансировка и health-check работают на двух уровнях:

  • Общий домен группы — A-записи формируются из IP сервисов группы; режим LB и параметры health-check настраиваются в карточке группы.
  • Несколько FQDN на сервис — через service_bindings один сервис может быть привязан к нескольким hostname в разных зонах (уникальность (domain_id, service_id, hostname)).
  • Привязка сервиса с multi-A — режим LB и health-check настраиваются в карточке сервиса для каждой привязки с несколькими IP; для IP задаются вес/приоритет.
  • Ноды — first-class адреса сервиса (nodes + binding_nodes); IP-пулы service_ips / service_binding_ips пишутся dual-write.
  • Change IPPOST /api/v1/service-bindings/:id/change-ip (preview + PATCH DNS).
  • Change Domain — перенос привязок между зонами POST /api/v1/services/:id/change-domain.

Режимы LB: round_robin, failover, weighted. В Cloudflare free weighted работает как round_robin (одна A на IP). В A-пул попадает всё, кроме Down (unknown / checking / Slow возвращаются в DNS на первой успешной пробе). Бейдж Healthy — UNHEALTHY → CHECKING → HEALTHY после HEALTH_SUCCESS_RECOVERIES (default 2). Пороги и cron движка задаются в Настройки → Health-check (env — fallback, пока значения не сохранены в UI).

Источники проб: Local, Cloudflare Worker, Globalping

На привязке/группе задаётся мультивыбор источников (health_check_providers JSON) и правило агрегации (health_check_aggregate: any | all | majority). Failover читает одну строку ip_health_status (агрегат). Журнал health_probe_log — строка на каждый источник.

Local Cloudflare Worker Globalping
Кто пробирует процесс API CFDM Worker на edge (Cron Trigger) globalping.io
Планировщик глобальный cron CFDM cron Worker + ingest KV тот же cron CFDM (POST/GET measurements)
Пороги Slow/Down Настройки → Health-check те же те же (по агрегату)
Результат SQLite ip_health_status та же SQLite + colo из KV та же SQLite, colo = city/country пробы
Fallback нет (не Local) нет (нет токена / 429 / timeout = fail)

Агрегация (на сервисе/группе):

  • any — Down, если хотя бы один выбранный источник Down
  • all — Down, только если все выбранные Down
  • majority — Down по большинству (2 источника → оба; 3 → ≥2)

Cloudflare в CFDM — это Worker, не Health Checks API. Продукт Health Checks на Free-плане недоступен и не используется.

Worker сам опрашивает IP/порты/протоколы (TCP/HTTP, паттерн UptimeFlare: sockets.opened, p-limit 5). CFDM создаёт скрипт через Workers Scripts API, кладёт список целей в KV и читает результаты. Публичный URL API не нужен. Если Worker/KV не готовы, cloudflare-цели не пробируются как Local.

Кнопка Создать / обновить WorkerНастройки → Health-check. Токен: Account Workers Scripts Write + Workers KV Storage Write. Zone DNS недостаточно.

Free: 5 Cron Triggers на аккаунт; KV 1000 writes/сутки (интервал ≥ 2 мин); ≤ 48 целей за тик. Исходник: workers/health-probe/.

Globalping: POST /v1/measurements → poll GET каждые ≥ 500 мс. CFDM TCP → type: ping + protocol: TCP; HTTP → type: http, target = IP, request.host = hostname. Токен: dash.globalping.io/tokens. Без токена 250 tests/hour, с токеном 500 + credits. Локации (magic CSV, default World) и limit (110, default 3) — Настройки → Health-check. Один measurement на уникальный origin (IP/порт/path) за тик.

Reconcile DNS запускается cron-задачей health-check после ingest KV и агрегации.

Docker

Один alpine-контейнер (API + SPA + SQLite). Образы cfdm и cloudflare-domain-manager — один манифест.

docker pull git.shx.one/denozord/cfdm:latest
# drop-in для прежнего тега:
docker pull git.shx.one/denozord/cloudflare-domain-manager:latest

docker run -d -p 8080:8080 -v cfdm-data:/data \
  -e CLOUDFLARE_API_TOKEN=... \
  -e JWT_SECRET=... \
  git.shx.one/denozord/cfdm:latest

Compose: корневой docker-compose.yml или deploy/compose/docker-compose.example.yaml. Сборка: deploy/docker (bake). Релизы: docs/releasing.md.