Перейти к содержанию

VPS и домены

Miami Graphics не имеет собственных backend-сервисов (вся бизнес-логика в лаунчере, БД у Supabase, файлы в R2). Но два VPS нужны для специфических задач.

EU VPS — Swiss

IP: 84.234.18.182 Локация: Швейцария Назначение: AmneziaVPN сервер + cron-job'ы для popularity decay'а.

flowchart LR
  Users[Юзеры в РФ] -->|VPN| AmneziaSrv[Amnezia на 84.234.18.182]
  AmneziaSrv -->|обычный internet| External[Supabase / R2 / CDN]

  Cron[crontab на VPS] --> SupaJob[POST /rpc/daily_popularity_decay]

Зачем AmneziaVPN: когда TLS fragmentation и Zapret не помогают (~5% случаев — клиенты на жёстко контролируемых сетях), они подключаются к нашему VPN через клиента Amnezia. Это последний резорт для самых тяжёлых cases в РФ.

Один VPS обслуживает ~50-200 одновременных коннектов, потолок ~500. На случай роста — план поставить второй сервер в DE/NL.

Что стоит

swiss VPS:
├── AmneziaVPN server (docker-compose)
├── nginx — reverse-proxy для health-check'ов
├── crontab — daily jobs
└── prometheus + grafana — мониторинг ресурсов

Daily jobs

crontab -e на VPS
# Popularity decay — каждый день в 03:00 UTC
0 3 * * * curl -X POST "https://<projref>.supabase.co/rest/v1/rpc/daily_popularity_decay" \
  -H "apikey: $SERVICE_KEY" -H "Authorization: Bearer $SERVICE_KEY"

# Sitemap regenerate (для будущего web-portal'а)
0 4 * * 0 /home/admin/scripts/regenerate_sitemap.sh

# R2 stats report — раз в неделю
0 5 * * 0 /home/admin/scripts/r2_size_report.sh | mail -s "R2 weekly" hunter@email

RU VPS — для тестов

Маленький VPS в РФ (Selectel, Москва) — нужен только для тестирования сети из реальной российской сети.

Когда мы добавляем новый bypass-strategy в BypassTester, мы можем сами протестировать его на этом VPS, не дожидаясь юзерских репортов.

Не используется для прод-сервисов — только debug и тестирование.

Домены

Домен Назначение DNS
miamigraphicsstorage.uk R2 direct access CNAME → <account>.r2.cloudflarestorage.com
cdn.miamigraphicsstorage.uk R2 через CloudFlare Worker (cache) Worker route
miamigraphics.app будущий web-portal Vercel deploy
docs.miamigraphics.app эта документация GitHub Pages

Почему .uk

Изначально хотели .app (TLD для apps), но miamigraphicsstorage.app был занят. Взяли .uk за дешевизну ($5/год через Cloudflare). Юзеру не показывается в UI — он видит preview-картинки, не URL'ы. Так что коммерческая логика для .uk не нужна.

Wildcard SSL

Cloudflare выдаёт wildcard SSL для всего *.miamigraphicsstorage.uk бесплатно. Никаких Let's Encrypt fuss'ов.

CloudFlare Worker

На cdn.miamigraphicsstorage.uk стоит простой CloudFlare Worker который добавляет агрессивный кеш для R2:

worker.js (упрощено)
addEventListener('fetch', event => {
  event.respondWith(handle(event.request));
});

async function handle(request) {
  const url = new URL(request.url);
  const r2Url = `https://<accountId>.r2.cloudflarestorage.com/huntergraphics${url.pathname}`;

  const cache = caches.default;
  let response = await cache.match(request);

  if (!response) {
    response = await fetch(r2Url);
    response = new Response(response.body, response);
    response.headers.set('Cache-Control', 'public, max-age=86400');
    response.headers.set('Access-Control-Allow-Origin', '*');
    event.waitUntil(cache.put(request, response.clone()));
  }

  return response;
}

Это снижает R2 egress costs (мы платим за каждый GB out из R2 после free-tier'а). CloudFlare кеширует, R2 отдает один раз.

Secrets

Где Что
admin-config.json (DPAPI encrypted, на админ-машине) R2 access/secret key, Supabase service key
Anon Supabase key вшит в C# код (Constants.cs), не secret
Github Actions secrets release flow tokens (см. release pipeline)
.env на VPS Supabase service key для cron-job'ов

Сервисы не имеют public admin UI. Все админ-операции делаются через лаунчер в админ-панели (см. admin index). Это намеренно — один интерфейс, никаких параллельных consoles.

Backup и DR

  • Supabase — встроенный daily backup от Supabase (point-in-time recovery 7 дней).
  • R2 — отдельно backup'ится раз в неделю на ~/backup/r2/ на админ-машине через rclone copy. Полный mirror в ~30 GB.
  • VPS configs — stored в private git repo huntergraphics-infra (только конфиги, не secrets).

Что не стоит на VPS

  • Никакого backend для лаунчера (всё в Supabase).
  • Никаких баз данных (Supabase делает hosting).
  • Никакого ML / image processing (всё на клиенте, headless Chromium в renderer).

Архитектура максимально serverless — VPS только для VPN и cron'а. Это intentional simplicity: меньше surface attack, дешевле, проще support.

Дальше: dotnet publish single-file →