Sestavení neví, kam míří

Někdo postaví celý web na notebooku, naimportuje do něj desetiletí starých příspěvků, prohlédne si každou stránku — a nic z toho ještě nikam nedorazilo. V env.sh není řečeno kam a nic dalšího na to nečeká: sestavení proběhne, archiv projde kontrolou, každá stránka se vykreslí na localhost. Sestavení neví, kde má web nakonec skončit, a vědět to nepotřebuje.

Totéž sestavení může začít na notebooku, o rok později se přestěhovat na pronajatý VPS a potom skončit na instanci Cloudronu. Mezi těmito přesuny se v obsahové pipeline nemění nic. Mění se odpověď na jedinou otázku — kam mají soubory jít — a odpovědět na ni může šest věcí.

Co o tom rozhoduje

DEPLOY_BACKEND v env.sh určuje cíl; hodnoty pod ním závisejí na tom, který to je. Všechno za tímto řádkem je u všech šesti stejné. Každý backend si vede vlastní manifest — SHA-256, velikost a čas změny každého souboru, který už nahrál — takže nasazení posílá vždy jen to, co se od minulého změnilo. deploy-web.sh --dry-run tento manifest přečte, aniž by se čehokoli dotkl.

Takhle vypadá výstup, spuštěný právě teď proti vlastnímu backendu tohoto webu:

$ ./scripts/deploy-web.sh --dry-run
== deploy-web.sh ==
Mode: preview (dry-run) -- nothing is actually uploaded.

Deploy web -> Surfer: https://blogsh.app  [DRY-RUN]
  Files selected: 194, 33.3 MB in the build, new or changed: 0, unchanged (skipped): 194

Od posledního skutečného nasazení se nic nezměnilo, takže to manifest oznámí a tím to končí — stejnou větu by vypsal cíl git nebo rclone, jen s jiným řádkem nad ní, který říká, kdo odpověděl.

Manifest je ale pro každý backend zvlášť, takže když stejné sestavení poprvé namíříš na jiný cíl, první nasazení nahraje všechno — přesun je jedno úplné nahrání, ne opakování čehokoli, co sestavení udělalo.

Pravidlo určuje ten nejpřísnější

Jediný soubor nad 100 MB se odmítne při uložení i znovu při nasazení a limit je na všech šesti backendech stejné číslo — ne proto, že by všechny cíle sdílely tentýž strop, ale proto, že engine vybere ten nejpřísnější a všechny se ho drží. Web určený pro rsync tak zůstane nasaditelný i přes sftp a nikdo nemusí zjišťovat na vlastní kůži, který backend byl shovívavý.

To prozrazuje, že tohle není šest nahrávacích nástrojů vedle sebe: je to jeden model nasazení — jeden tvar manifestu, jedna bezpečnostní pojistka, jeden limit velikosti souboru — se šesti způsoby, jak se dostat na druhý konec. Backendy se liší tím, jak bajty putují; co smí putovat, není jejich věc.

Těch šest

surfer je výchozí — nastav SURFER_URL a SURFER_TOKEN a nic dalšího říkat nemusíš. Je to Cloudron Surfer, hosting, na kterém běží i tento projekt.

local zapisuje přímo do adresáře, a to pro kořenový adresář dokumentů za vaším vlastním serverem nginx nebo Caddy. O HTTPS se v každém případě stará webový server; CSP tohoto modulu je dodáván jako meta tag, takže v tomto ohledu není třeba nic konfigurovat, ani kdyby tento tag chyběl.

rsync míří na libovolný server dostupný přes SSH, na kterém je nainstalovaný rsync — nejuniverzálnější z šesti, protože to popisuje většinu VPS i dobrou část sdíleného hostingu.

git pushuje na GitHub, GitLab nebo Codeberg Pages, při každém nasazení force-pushem celé sestavení jako jediný commit. Vlastní doména vyžaduje nastavené GIT_PAGES_CNAME, protože hostitel drží tu adresu v souboru, který leží přímo ve větvi, již snapshot přepisuje.

rclone dosáhne na S3, R2, B2, WebDAV a cokoli dalšího, s čím umí rclone config komunikovat; přihlašovací údaje k bucketu zůstávají v konfiguraci rcloneu, ne v env.sh.

sftp je pro hostitele, kteří nemají rsync ani git: obyčejné SSH, dávkový sftp, jedno spojení na nasazení. Ověřování klíčem je potřeba nastavit předem — dávková úloha nemá terminál, ve kterém by odpověděla na dotaz na heslo, a spojení selže, místo aby čekalo na odpověď, která nepřijde.

Na kterém z těch šesti web běží, je jediný řádek v env.sh, zvolený jednou a jen zřídka přehodnocovaný — protože těžší polovina problému nikdy nebyl backend. Bylo to zajistit, aby nezáleželo na tom, který se vybere.

Komentáře