Files
vtube/docs/DEPLOY.md
goboss d59393a608 ADS: VAST has implicit dependency on popunder cooldown
DEPLOY: document custom CDN stale-cache gotcha + recovery

Findings from 8148 production debug session 2026-05-02:

1. VAST gotcha — _decide() mode логіка:
   mode = popActive ? (vastActive || skipPattern ? "none" : "vast") : "pop"
   Тобто VAST loadable ТІЛЬКИ після того як popunder уже спрацював і
   _popRr cooldown set. На свіжій сесії: mode завжди "pop" → VAST SDK
   never loaded → користувач думає "VAST зламаний". Force test через
   ?clearAds=1 → pop fires → refresh → mode=vast.

2. CDN stale-cache — custom CDN кешує `?v=<hex-like>` URLs з
   s-maxage=31536000 (1 рік). Race у deploy: layout.etlua з новим ?v=
   може hit CDN раніше ніж static file → CDN кешує OLD bundle під
   NEW ?v= ключем → застрягає назавжди. Workaround: bump source md5,
   rebuild, новий ?v= ключ.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 21:51:32 +00:00

7.1 KiB
Raw Permalink Blame History

tubev — Deploy Flow

Як зміна потрапляє з робочого місця → у prod.

Two-tier model

Edit /home/nosfortube/frontend_<port>/      ← work / source-of-truth
        │
        ├──→  t1.<domain>                   ← test (instant, IP-allowlist)
        │
        └──→  admin panel "site/control"    ← prod деплой per-site (юзер натискає)
                або через Адміна             ← для var.lua / нових файлів
                  │
                  └──→ <domain>             ← live, з CDN

Test environment — t1.<domain>

  • Доступ: IP-allowlist (ймовірно nginx-level, не точно). Юзер заходить через VPN щоб мати стабільний IP.
  • Apply: instant — змінив файл у frontend_<port>/ → видно на t1. одразу.
  • Обмеження (per-site різні): CDN off, compression off, повільніше, comments/ads можуть бути обмежені або тестові.
  • AI-side: Claude з сервера МАЄ доступ до t1. (server IP 185.73.222.75 у allowlist). Перевірено 2026-05-01: curl -I https://t1.atube.sex → 200 OK, curl -I https://t1.hdsexvideo.xxx → 200 OK. Можна робити HTTP probes для health-check, regression smoke, response inspection.

Prod deploy — три шляхи

A) Через admin panel "site control" (юзер сам, instant per-site)

https://rss.g--o.info/admin/site/control — список усіх сайтів, кнопка викатати оновлення з тесту → прод.

Покриває: templates .etlua, CSS, JS (звичайні per-site файли).

Не покриває (потрібен Адмін):

  • lib/<port>/var.lua — нові/змінені змінні
  • Нові файли (yet not in admin's git)
  • Shared views/static/js/lib/, lib2/ (cross-site impact)

B) Через admin panels (settings / translations / sitemap)

Контент-шар, не код. Самостійно, без Адміна:

  • Per-site settings: https://<domain>/admin/index, /admin/settings
  • Languages set: https://<domain>/moderation/languages/langs
  • Translations (UI strings): https://<domain>/moderation/languages/translation/
  • Sitemap: https://rss.g--o.info/admin/site

Деталі: ADMINS.md.

C) Через Адміна (Орест / основний програміст)

  • Нові файли потрапляють у Адмінів git → kor pull/reload
  • var.lua зміни → kor reboot
  • Mass operations (mirror swaps, multi-site fixes)

Trigger: попросити (чат / задача).

kor reload

  • lib/<port>/var.lua зміни → потрібен kor reboot щоб env змінні підвантажилися
  • Templates .etlua — підхоплюються hot (без reboot)
  • Static assets — hot, але CDN cache може тримати стару версію → потрібен cache-bust (через ?v=<md5> у layout — реалізовано у ~/git-save-all.sh)

CDN

  • Custom CDN для більшості сайтів (наявний; провайдер невідомий поки)
  • Cloudflare на двох сайтах (наприклад 8081) — додаткове edge кешування
  • При оновленні prod для Cloudflare-сайтів: треба purge cache + враховувати у логіці що зміни не миттєві (cache TTL до purge)
  • Cache-bust через ?v=<md5> у layout.etlua працює для обох (custom + CF)

⚠️ Stale-cache gotcha (custom CDN, 8148 confirmed 2026-05-02)

Custom CDN serve-ить різні cache-control залежно від виду query string:

Pattern URL s-maxage Поведінка
?v=<hex-like-7-chars> (md5 prefix) 31536000 (1 рік) "Content-addressed asset" — immutable, edge cache aggressive
?v=<short> (число, ZZZZ etc.) 10 sec Швидко refresh-иться
(no query) ~ Звичайний cache

Race condition при deploy:

  1. Template (layout.etlua) deploy-иться з новим ?v=<new_md5> reference
  2. До того як static (ad-bundle.min.js) сам file deploy-иться — браузер/crawler hit-ить <host>/ad-bundle.min.js?v=<new_md5>
  3. CDN cache-miss → origin ще має OLD bundle → CDN кешує OLD під новим ?v= ключем
  4. Static deploy-иться з NEW bundle, але CDN cache stuck на 1 рік з OLD content

Симптом: curl <host>/ad-bundle.min.js → NEW. curl <host>/ad-bundle.min.js?v=<deployed_md5> → OLD. Live site поломаний.

Рішення:

  • Bump bundle md5 (тривіальна зміна у source — додаткова line, build stamp): git-save-all.sh rebuilds → новий md5 → новий ?v= → нова cache entry → fresh
  • Або purge CDN cache (через адмін / hostiserver)
  • Краще довгостроково: змінити cache-bust scheme у git-save-all.sh щоб включав timestamp (?v=<md5>-<unix>) → завжди унікально

Перевірка чи це сталося: curl -sI <host>/<file>?v=<md5> | grep s-maxage — якщо 31536000, кеш заблокувався на рік.

git-save-all.sh — git-snapshot для backup_/

~/git-save-all.sh "msg" ітерує /home/w4/backup_*/:

  1. sync.sh per backup — копіює з prod (/home/nosfortube/frontend_<port>/) у backup. Tracked subset (whitelist у sync.sh): templates (layout.etlua, id_index.etlua, video.etlua, banner modules), ad orchestration JS (ad-config.js, ad-core.js, vast-preroll.js, ad-bundle.min.js), player files, тести, robots.txt. Решта prod-коду — поза git.
  2. Auto-rebuild ad-bundle: якщо будь-який з 5 source JS (ad-config.js, ad-core.js, ad-mute.js, vast-preroll.js, ad-bootstrap.js) новіший за ad-bundle.min.js → запуск bash build-ad-bundle.sh (terser concat+minify).
  3. Cache-bust: md5sum bundle → перші 7 hex → sed -i ?v=... у views/layout.etlua. Idempotent (однаковий контент = однаковий хеш).
  4. Commit per backup: message формат YYYY-MM-DD_HH:MM - <msg> [backup_<port>]. Кожен backup repo окремо — N changed sites = N commits у різних repos.

Призначення: git-tracking для recovery / audit / blame. Не deploy mechanism.

Open questions

  • CDN — який провайдер (Cloudflare / BunnyCDN / Fastly)? Per-site чи unified?
  • Backup_/ покриття — чому 14 із 94 сайтів? Поширити чи це історичний субсет? (open-разом з юзером)
  • Headless browser (Puppeteer / Playwright) на сервері для visual regression / ad-render check — варто setup-нути на потребу?