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>
7.1 KiB
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:
- Template (layout.etlua) deploy-иться з новим
?v=<new_md5>reference - До того як static (
ad-bundle.min.js) сам file deploy-иться — браузер/crawler hit-ить<host>/ad-bundle.min.js?v=<new_md5> - CDN cache-miss → origin ще має OLD bundle → CDN кешує OLD під новим
?v=ключем - 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.shrebuilds → новий 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_*/:
sync.shper 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.- 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). - Cache-bust: md5sum bundle → перші 7 hex →
sed -i ?v=...уviews/layout.etlua. Idempotent (однаковий контент = однаковий хеш). - 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-нути на потребу?