Paralelní inkrementální FTP deploy v CI pipeline

PHP, Linux, Tipy & triky

Automatizace hýbe světem a v CI lze automatizovat i nahrávání na FTP. Existují nástroje, které dokáží nahrávat jen změněné soubory. Ale taky nástroje, které dokáží nahrávat hodně souborů zároveň. Proto jsem dva z těchto nástrojů zkombinoval a začal používat v Gitlab CI.

Paralelní inkrementální FTP deploy v CI pipeline

Article in English can be found on dev.to/arxeiss/parallel-incremental-ftp-deploy-in-ci-pipeline-2511

TL;DR: Vytvořil jsem repozitář a Docker image, který obsahuje skripty a vše potřebné pro spuštění deploy v Gitlab CI pipeline tak, jak je popsáno níže.

Již dříve jsem napsal článek o nástroji FTP Deployment, který vytvořil David Grudl, a o vlastních úpravách ve forknutém repozitáři. Nevýhodou tohoto řešení ale je nemožnost nahrávat soubory paralelně. Při hodně změnách ve složkách jako je vendor, trval upload dlouhé desítky minut. Poslední změna ve vlastním forku nazvaná New mode: File Output umožňuje namísto provedení uploadu pouze výpis seznamu souborů a složek k vytvoření, nahrání či smazání.

LFTP a paralelní upload

LFTP je velmi rozšířený nástroj pro přenos souborů přes různé protokoly jako HTTP, FTP či SFTP. Možností, jak se soubory pracovat a přenášet je, nabízí LFTP mnoho. Tou nejdůležitější je ale rozhodně paralelní zpracování. A protože ovládání programu lze pouze přes příkazovou řádku, je to ideální kandidát na zapojení do CI/CD pipeliny.

Díky použití kombinace FTP Deploymentu a LFTP jsem dosáhl zrychlení z 30 minut na 5 minut. Měřeno při aktualizaci Laravelu a všech použitých knihoven.

FTP Deployment + LFTP = Paralelní incrementální upload

Jak asi vyplývá z odstavců výše, celý proces se skládá ze 2 kroků popsaných níže. Protože ale napojení není úplně přímočaré, vše je zkompletováno v repozitáři na Gitlabu a rovnou vytvořen Docker image. Ten obsahuje nejnovější PHP, modifikovanou verzi FTP Deploymentu, LFTP, další pomocné utilitky a příklady zprovoznění, které provedou právě zmíněné kroky:

  1. FTP Deployment oskenuje a rozpozná změněné soubory. Namísto jejich synchronizace a nahrání na FTP ale pouze vygeneruje jejich seznam. Ten obsahuje všechny složky a soubory k nahrání či odstranění. Nově vygenerovaný .htdeployment rovněž ponechá pouze lokálně.
  2. Seznamy jsou dále zpracovány nástrojem LFTP. Ten už pouze nahrává nebo maže soubory na FTP, které získal z dříve vytvořených seznamů. Ale hlavně to vše provádí paralelně.

Log z Gitlab CI pipeline

Proč nelze vždy použít lftp mirror?

LFTP má příkaz mirror, který dokáže synchronizovat 2 složky. Na první pohled by se mohlo zdát, že napojení FTP Deploymentu je zbytečné a tento příkaz postačí. A v některých případech by opravdu mohlo. Pipeline v CI/CD to ale nejspíše nebude, a většina FTP serverů také ne. Příkaz mirror porovnává soubory na základě času modifikace a velikosti souboru. Pokud se liší, je soubor automaticky synchronizován dle kritérií - download/upload. To má ale několik problémů:

  1. Některé FTP servery často ignorují čas modifikace, který byl zaslán a nastaví jej na aktuální hodnotu. Díky tomuto LFTP vidí soubor jako by byl změněn pokaždé.
  2. Pokud jsou některé soubory přidány až v pipeline, třeba vendor, tak se může jejich čas modifikace lišit při každém běhu. Tudíž při každém běhu jsou brány jako změněné.
  3. Oba problémy výše lze vyřešit přepínačem --ignore-time. Poté jsou ale soubory kontrolovány pouze na základě velikosti. Tj změna jednoho znaku upload neprovede. A to rozhodně není dostačující pro produkční prostředí.

Zmíněný repozitář obsahuje skript, který spustí mirror příkaz. Ten se hodí ale pouze pro případ, kdy běžný deploy způsobil nekonzistentnost (chyba například). Full deploy provede 1:1 kopii.
POZOR: Dá se to považovat jako reset do původního nastavení, je opravdu nutné dobře nastavit, které složky synchronizovat, aby nedošlo ke smazání uploadů, záloh apod!


Zkušenosti s automatizací deploye na FTP servery můžete sdílet v komentářích.

K tomuto článku již není možné přidávat další komentáře