Zpět na blog

Sestavení a nasazení aplikace Flask pomocí Dockeru na Ubuntu 20.04

Sestavení a nasazení aplikace Flask pomocí Dockeru na Ubuntu 20.04

Úvod

Docker je open-source platforma pro kontejnery. Jedná se o lehké, virtualizované, přenosné, softwarově definované standardizované prostředí, které umožňuje softwaru běžet v izolaci od ostatního softwaru běžícího na fyzickém hostitelském stroji. Docker nabízí lehkou alternativu k virtuálním strojům. Zároveň poskytuje přenositelnost, výkon, agilitu a škálovatelnost aplikací. Pro ucelený návod k ekosystému Docker se podívejte na náš podrobný přehled kontejnerizace s Dockerem.

Flask je open-source minimalistický webový framework vytvořený v jazyce Python. Mezi skvělé vlastnosti Flasku patří to, že je lehký, flexibilní a vysoce strukturovaný. Navíc ke svému spuštění nevyžaduje žádné specifické nástroje ani doplňky.

Kombinace Flasku a Dockeru vám poskytne lehkou, flexibilní a škálovatelnou aplikaci. Díky přenositelnosti kontejnerů Dockeru ji můžete nasadit na mnoha serverech a infrastrukturách. Cílem tohoto návodu je ukázat vám, jak nasadit aplikaci Flask pomocí Dockeru. Ukážeme si také, jak zajistit, aby se projevily budoucí aktualizace vaší aplikace.

Požadavky

Tento návod bude praktický a měli byste si vytvořit prostředí, které vám umožní postupovat podle něj:

Nyní začněme!

Krok 1: Příprava aplikace Flask

Začneme vytvořením adresáře, který bude obsahovat naši aplikaci Flask. Můžete si vybrat název adresáře podle svého uvážení. Pro tento návod jej však pojmenujeme flask_demo. Soubory projektu uložíme do adresáře /var/www, což je obvykle adresář, do kterého Ubuntu standardně povoluje přístup z veřejného internetu. Nejprve spusťte následující příkazy pro vytvoření adresáře a přechod do něj:

V tomto kořenovém adresáři našeho projektu vytvoříme základní strukturu složek aplikace Flask. Dále spusťte následující příkaz pro vytvoření základní struktury s přidáním parametru -p pro vytvoření všech nadřazených složek:

Složka app obsahuje všechny soubory související s aplikací Flask, včetně views a blueprints. Views obsahují kód, který píšete pro reakci na požadavky přicházející do vaší aplikace. Blueprints pomáhají při vytváření komponent aplikace a podporují běžné vzory v aplikacích Flask.

Příhodně pojmenovaná složka static obsahuje statické soubory, jako jsou obrázky, CSS a JavaScript. Adresář templates obsahuje všechny HTML šablony pro projekt.

Nyní můžeme začít psát soubory potřebné k inicializaci aplikace Flask. Začněte vytvořením souboru s názvem __init__.py uvnitř adresáře app, abyste sdělili Python interpretu, že adresář app by měl být považován za balíček. Spuštěním následujícího příkazu v terminálu otevřete soubor v editoru nano:

Balíčky v Pythonu používáme k seskupování modulů do logických jmenných prostorů nebo hierarchií. Modularizace umožňuje rozdělit kód do samostatných a spravovatelných bloků, které plní určité funkce.

Poté uvnitř souboru __init__.py otevřeného v editoru přidejte následující fragment kódu pro spuštění instance Flasku a importujte logiku z views.py, který vytvoříte v následujících krocích:

Až budete hotovi, stiskněte Ctrl + O a ENTER pro uložení souboru, poté jej zavřete pomocí Ctrl + X. Dále vytvořme views.py uvnitř adresáře app adresáře. Soubor views.py bude obsahovat většinu aplikační logiky:

Do souboru přidejte následující fragment kódu. Tento kód zobrazí jednoduchý řetězec, který ukáže, že vaše aplikace běží, když uživatelé navštíví váš web:

V tomto souboru začneme importem instance aplikace Flask. Poté musíme přidat řádek pro definování routy: @app.route(/). Řádek @app.route(/) je ve Flasku označován jako dekorátor v aplikaci Flask. Dekorátory můžete použít k vložení dalších funkcí do jedné nebo více funkcí. V tomto případě předáváme volání routy / funkci home. Když uživatel navštíví tuto routu, uvidí text: "Naše aplikace Flask běží!".

Dále vytvoříte soubor uwsgi.ini pro uložení konfigurace uWSGI pro aplikaci. uWSGI je možnost nasazení pro Nginx, která slouží jako protokol a aplikační server. Spuštěním následujícího příkazu vytvořte soubor v kořenovém adresáři projektu pomocí editoru nano:

Do otevřeného souboru přidejte následující fragment kódu:

Tento soubor obsahuje několik direktiv. Jejich účel definujeme níže:

  • module – definuje modul, ze kterého bude aplikace Flask poskytována. Modul jsme nastavili jako main, což odkazuje na soubor main.py v kořenovém adresáři. Tento soubor vytvoříme v dalším kroku.
  • callable – instruuje uWSGI k použití instance app exportované z aplikace.
  • master – zajišťuje, že aplikace zůstane spuštěná, aby se minimalizovaly výpadky při opětovném načítání celé aplikace.

Až budete hotovi, soubor uložte a zavřete.

Nyní můžete vytvořit soubor main.py pro určení vstupního bodu vaší aplikace. uWSGI bude tento soubor číst, aby věděl, jak s aplikací komunikovat. Spuštěním následujícího příkazu vytvořte soubor main.py pomocí nano uvnitř kořenového adresáře vašeho projektu:

Do souboru přidejte následující řádek, který naimportuje instanci Flask vytvořenou v balíčku aplikace:

Poslední věcí, kterou v tomto kroku uděláte, je definování závislostí nezbytných pro běh aplikace. Tyto závislosti definujeme v souboru s názvem dependencies.txt. Když Docker sestavuje obraz vaší aplikace, spustí příkaz správce balíčků pip (balíčkového správce) k instalaci závislostí. Otevřete soubor v kořenovém adresáři pomocí následujícího příkazu:

Do tohoto okamžiku v našem projektu chceme pouze jednu závislost: Flask. Můžeme tedy přidat následující řádek, který odkazuje na správnou verzi Flasku, kterou pro náš projekt chceme:

Rozhodli jsme se pro Flask verzi 2.0.1 jako závislost. V době psaní tohoto návodu se jedná o nejnovější verzi. Více informací o různých verzích naleznete na stránce Změny ve Flasku. Tím je nastavení aplikace Flask dokončeno. Nyní si připravíme konfiguraci Dockeru pro nasazení.

Krok 2: Konfigurace Dockeru

Pro nastavení nasazení pomocí Dockeru vytvoříme dva soubory, Dockerfile a start.sh. Soubor Dockerfile obsahuje deklarativní řádky, které tvoří obraz Dockeru. Soubor start.sh je základní shellový skript pro sestavení obrazu a spuštění kontejneru z Dockerfile. V kořenovém adresáři projektu spusťte následující příkaz pro vytvoření Dockerfile:

Tento soubor obsahuje potřebné konfigurace pro obraz Dockeru. Dále přidejte následující fragment kódu, který specifikuje závislosti a způsob sestavení obrazu:

První řádek v Dockerfile definuje základní obraz, ze kterého sestavujeme náš obraz. V tomto případě budeme stavět na základě tiangolo/uwsgi-nginx-flask, který je k dispozici na DockerHub. Tento konkrétní obraz jsme vybrali proto, že podporuje mnoho verzí Pythonu.

Také specifikujeme, že chceme obraz aktualizovat. Poté musíme přidat bash příkazový procesor , nano textový editor, a git klienta pro stahování a odesílání zdrojového kódu z repozitářů správy verzí, jako jsou GitHub, Bitbucket, nebo Gitlab. Řádky s ENV specifikují proměnné prostředí, které se mají v kontejneru použít.

Příkaz COPY zkopíruje závislosti do kontejneru. Příkaz RUN vyvolá pip balíčkový správce k analýze dependencies.txt souboru a instalaci závislostí. Po dokončení úprav soubor uložte a zavřete.

Dále vytvoříte skript start.sh . Tento skript bude obsahovat příkazy Dockeru pro sestavení a spuštění obrazu. I když můžete tyto příkazy spouštět postupně v terminálu, myslíme si, že je čistší přidat je do shellového skriptu a jednoduše jej vyvolat z terminálu jediným příkazem.

Než budeme moci definovat obsah tohoto souboru, musíme nejprve najít volný port, který jiné služby nepoužívají. Budeme používat port 45644. Můžete si však vybrat jiný port. Spuštěním následujícího řádku zkontrolujte, zda je port volný:

V závislosti na zvoleném portu, pokud je výstup výše uvedeného příkazu 1, pak je volný. V opačném případě možná budete muset zvolit jiný port a zkusit příkaz znovu:

Flask application Port Check

Vzhledem k tomu, že jsme našli volný port, můžeme nyní vytvořit soubor pomocí nano v kořenovém adresáři projektu spuštěním následujícího příkazu:

Do tohoto souboru přidejte následující fragment kódu:

První řádek, označovaný jako shebang, určuje, že se jedná o soubor bash a měl by být spuštěn jako příkazy. Druhý řádek deklaruje proměnnou s názvem app_name. Tuto proměnnou používáme k nastavení názvů obrazu a kontejneru. Třetí řádek instruuje Docker, aby sestavil obraz na základě definice v Dockerfile v aktuálním adresáři. Obraz se bude jmenovat docker-flask-demo podle této proměnné.

Poslední řádek vytvoří kontejner s názvem docker-flask-demo podle proměnné, kterou jsme definovali. Příznak -d udržuje kontejner spuštěný na pozadí v odpojeném stavu po dokončení provádění příkazu. Příznak -p mapuje port na serveru na konkrétní port v kontejneru. V tomto případě připojujeme port 45644 na hostitelském stroji k portu 80 , který Docker v kontejneru zpřístupní.

Používáme příznak -v k určení Docker svazku pro připojení ke kontejneru. Proměnná $PWD je výchozí proměnná Linuxu, která obsahuje cestu k aktuálnímu adresáři , ve kterém se v danou chvíli nacházíte:

Flask application pwd

V našem případě připojujeme celý adresář projektu do adresáře /var/www kontejneru. Konfigurace Dockeru je nyní připravena. Obraz můžete sestavit a spustit kontejner na základě sestaveného obrazu spuštěním následujícího příkazu:

Počkejte, až se skript dokončí, a poté spusťte následující příkaz Dockeru pro výpis všech běžících kontejnerů:

Výstup zobrazí běžící kontejnery:

Demo Docker

Měli byste vidět náš kontejner s názvem docker-flask-demo v seznamu běžících kontejnerů. Najděte veřejnou IP svého serveru a přejděte na ni v prohlížeči na zadaném portu: http://your-server-public-ip:45644.

Měli byste vidět podobný výstup:

Flask App Running

Pokud v prohlížeči vidíte výše uvedené, úspěšně jste nasadili aplikaci Flask. Dále budeme upravovat soubory a poskytovat obsah uživatelům prostřednictvím šablon.

Krok 3: Poskytování obsahu prostřednictvím souborů šablon

Ve Flasku se Templates používají k zobrazení statického a dynamického obsahu návštěvníkům webu. Ukážeme vám, jak vytvořit HTML šablonu a poskytnout ji uživatelům, když navštíví určitou trasu. Může to být například domovská stránka (Home) nebo stránka O nás (About).

Spuštěním následujícího příkazu v terminálu vytvořte soubor index.html v app/templates adresáři:

Poté do souboru přidejte následující fragment kódu:

Až budete hotovi, soubor uložte a zavřete. Vytvořte také další stránku, nazvěme ji About (O nás), pomocí následujícího příkazu:

Do souboru přidejte následující fragment kódu:

Až budete hotovi, soubor uložte a zavřete. Dále upravte soubor app/views.py , abyste odkazovali na šablony a také na trasy pro samotné stránky:

Upravte soubor tak, aby vypadal následovně:

Až budete hotovi, soubor uložte a zavřete. Provedené změny se neprojeví, dokud kontejner nezastavíte a znovu nespustíte. Spuštěním následujících příkazů Docker zastavte a spusťte kontejner. Poznamenejte si název kontejneru, jak jsme jej definovali dříve:

Jakmile je kontejner spuštěn a běží, navštivte domovskou stránku a stránku O nás, abyste viděli část nového obsahu:

Flask application Index

 Flask application 1

Dosud jste vytvořili aplikaci Flask, která může poskytovat obsah návštěvníkům vašeho webu. Zde je souborová struktura projektu:

File Structure

Pravděpodobně jste si všimli, že jsme museli restartovat kontejner Docker, aby se projevily nové změny. V dalším kroku to zautomatizujeme, abychom zajistili kratší výpadek.

Krok 4: Konfigurace automatického opětovného načítání při aktualizaci souborů aplikace

Každou chvíli provádíme změny v aplikaci, abychom vylepšili logiku, uživatelské rozhraní nebo přidali nějaké závislosti. Aby se tyto změny projevily, může to vyžadovat restartování kontejneru Docker. Naštěstí uWSGI má funkci nazvanou touch-reload pro opětovné načtení skriptu Python bez restartování kontejneru.

Python má již v základu funkci auto-reloading , která sleduje změny v celém souborovém systému a při výskytu změny aplikaci obnoví. I když je automatické načítání dobré pro minimalizaci výpadků, může být náročné na prostředky. Proto se nedoporučuje pro produkční prostředí.

Podívejme se, jak můžete použít touch-reload ke sledování změn v konkrétním souboru a opětovnému načtení aplikace, když dojde ke změnám. Upravte soubor uwsgi.ini pomocí editoru nano:

Přidejte zvýrazněný řádek, aby to vypadalo takto:

Až budete hotovi, soubor uložte a zavřete. Přidaný řádek specifikuje soubor, jehož úprava spustí opětovné načtení aplikace. Aby se však tato podmínka aktivovala pro budoucí úpravy, musíte nejprve restartovat kontejner:

Nyní můžete upravit soubor app/views.py a demonstrovat tak, jak funguje automatické opětovné načítání:

Změňte řetězec vrácený funkcí home, jak je zvýrazněno:

Po dokončení soubor uložte a zavřete.

Otevřete domovskou stránku aplikace v prohlížeči: http://your-server-public-ip:45644.

Zatím neuvidíte žádné změny. Je to proto, že podmínka touch-reload detekuje změnu v souboru uwsgi.ini . K aktivaci podmínky můžete použít touch , čímž se celá aplikace znovu načte pomocí následujícího příkazu:

Nyní, když domovskou stránku znovu načtete, uvidíte zobrazené nové změny:

Touch Reload

Pokud v budoucnu provedete jakékoli další změny, stačí spustit příkaz sudo touch uwsgi.ini a celá aplikace se znovu načte s kratším výpadkem. Tím se dostáváme na konec tohoto návodu.

Závěr

V tomto návodu jste implementovali a nasadili aplikaci Flask s Docker obrazy a kontejnery. Chcete-li minimalizovat výpadky tím, že se vyhnete nutnosti restartovat kontejner, nakonfigurovali jste touch-reload k naslouchání změnám v konkrétním souboru a automatickému opětovnému načtení celé aplikace. Nakonec jste vše otestovali v prohlížeči, abyste se ujistili, že to funguje.

Docker zajišťuje rychlejší nasazení a umožňuje snadné škálování aplikací. Pokud se chcete dozvědět více o různých příkazech Dockeru, podívejte se na tento návod na jak nainstalovat a používat Docker na Ubuntu.

Další zdroje o Dockeru na našem blogu, se můžete podívat na následující:

Příjemnou práci!

author

Pranay Kapgate

Autor · CloudSigma

Preslav Dobrev je kreativní designér ve společnosti CloudSigma, který se zaměřuje na konzistentní firemní identitu prostřednictvím tradičních i inovativních marketingových kanálů. Je zdatný v propojování umělecké vize se strategickým marketingem za účelem vytváření působivých příběhů značky.

Komentáře

Zatím žádné komentáře. Buďte první.