Späť na blog

Budovanie aplikácie Django a Gunicorn s Dockerom na Ubuntu

Budovanie aplikácie Django a Gunicorn s Dockerom na Ubuntu

Django je open-source webový rámec na vysokej úrovni pre Python, ktorý vám pomôže rýchlo vytvoriť vašu Python aplikáciu. Podporuje rýchly vývoj a čistý, pragmatický dizajn tým, že sa riadi architektonickým vzorom model–šablóna–pohľad (model–template–views). Rámec už v základe obsahuje potrebné moderné komponenty aplikácie, ako je autentifikácia používateľov, rámec pre ukladanie do vyrovnávacej pamäte, objektovo-relačný mapovač, URL dispečer, systém šablón a prispôsobiteľné administratívne rozhranie.

Gunicorn ‘Green Unicorn’ je Python WSGI HTTP server pre systémy UNIX. Server Gunicorn je kompatibilný s rôznymi webovými rámcami, ponúka skvelý výkon a je nenáročný na serverové zdroje. Docker je open-source kontajnerová platforma, ktorá je tu s nami už nejaký čas a robí vývoj aplikácií rýchlym, efektívnym a predvídateľným.

V tomto návode získate zručnosti v oblasti vývoja a nasadzovania škálovateľných kontajnerizovaných webových aplikácií Django. Budeme používať aplikáciu Django Polls vytvorenú podľa úvodných príručiek pre začínajúcich s Django. V čase písania tohto návodu sme ho založili na verzii Django 3.2 podporovanej verziou Python 3.6 alebo novšou. Aplikáciu nasadíme ako kontajner pomocou Dockeru a budeme ju spúšťať pomocou servera Gunicorn. Samozrejme, pred nasadením aplikácie Django v kontajneri budete musieť vykonať určité úpravy v kóde projektu, aby ste vyriešili veci ako logovanie do štandardných výstupných tokov a prácu s premennými prostredia. Statické súbory, ako sú CSS, JavaScript a obrázky, môžu byť presunuté do služieb objektového úložiska, čo umožní jednoduchú správu súborov z jedného miesta v prostredí s viacerými kontajnermi.

Ukážeme vám, ako tieto úpravy implementovať na základe dobre navrhnutej dvanásťfaktorovej metodiky pre tvorbu škálovateľných webových aplikácií. Po dokončení úprav zostavíte Docker obraz aplikácie a nasadíte kontajnerizovanú aplikáciu pomocou Dockeru. Odporúčame vám postupovať podľa krokov opísaných v návode, aby ste mu plne porozumeli.

Požiadavky

Keďže ide o praktický návod, odporúčame vám mať pripravené nasledujúce prostredie, ktoré vám pomôže postupovať podľa krokov:

  • Server Ubuntu 20.04. Môžete postupovať podľa krokov 1 až 4 v tomto podrobnom návode, ktorý vám pomôže nastaviť váš server Ubuntu na CloudSigma.

  • Uistite sa, že pridáte používateľa s privilégiami sudo na oboch uzloch, ktoré budeme používať na spúšťanie príkazov, ako je popísané v návode vyššie.

  • Nainštalujte Docker na server. Môžete postupovať podľa krokov 1, 2 a 3 v našom návode na inštaláciu a prevádzku Dockeru. Nezabudnite pridať vyššie vytvoreného sudo používateľa do skupiny Docker.

  • Kompatibilné objektové úložisko. Django podporuje niekoľko služieb úložiska, ako je uvedené v dokumentácii k django-storages. Môžete si vybrať tú, ktorú preferujete, a postupovať podľa dokumentácie na jej nastavenie. V tomto návode budeme používať MinIO , čo je cloudová úložná služba kompatibilná s S3.

  • Inštanciu SQL databázy. Django podporuje niekoľko SQL databáz, ktoré si môžete slobodne vybrať. V tomto návode budeme používať PostgreSQL. Databáza PostgreSQL nebude nasadená v kontajneri. Nastavíme samostatný server Ubuntu na hosťovanie inštancie PostgreSQL, aby sme zabezpečili nastavenie s viacerými kontajnermi a tiež perzistenciu dát. Môžete vytvoriť ďalšiu inštanciu Ubuntu 20.04 a postupovať podľa tohto návodu na Nastavenie inštancie databázy PostgreSQL na Ubuntu. Nezabudnite pridať rolu v databáze PostgreSQL pre vášho sudo používateľa, ako je vysvetlené v krokoch 2 a 3. Táto rola vám umožní pripojiť sa k databáze z ostatných serverov, na ktorých bežia vaše kontajnery.

Podľa týchto požiadaviek by ste mali mať dve inštancie servera Ubuntu. Na jednej inštancii pobeží váš Docker kontajner a na druhej inštancii pobeží inštancia PostgreSQL. Začnime!

Krok 1: Konfigurácia inštancie databázy PostgreSQL

V tejto časti upravíme konfigurácie Postgresu na serveri Ubuntu, na ktorom beží inštancia Postgresu. To umožní pripojenia z externej IP adresy. Po pripojení môžeme vytvoriť databázu a rolu používateľa, špecifickú pre aplikáciu Django Polls, ktorú nasadzujeme.

Najprv, ak ste si nastavili prostredie podľa Požiadaviek, mali by ste mať vo svojej databáze PostgreSQL rolu pre svojho sudo používateľa. Ďalej musíme pre túto rolu nastaviť heslo. Keď ste na serveri, kde beží PostgreSQL, prihláste sa do terminálu Postgres pomocou nasledujúceho príkazu:

Po vstupe do terminálu Postgres zadajte príkaz \password na zmenu hesla používateľa. Syntaxia pre príkaz \password je \password <používateľské_meno>. V našom prípade príkaz:

Zadajte heslo a potvrďte ho. Uložte toto heslo na bezpečné miesto, pretože ho neskôr použijete na autentifikáciu z druhého servera Ubuntu. Potom napíšte exit a stlačením klávesu Enter ukončite terminál Postgres.

Ak ste na inštancii servera PostgreSQL povolili firewall (ufw), budete musieť povoliť prevádzku na predvolený port Postgresu 5432. Prevádzku môžete obmedziť tak, aby prichádzala iba z konkrétnej IP adresy vášho druhého servera Ubuntu, na ktorom pobeží kontajner Docker. Spustením nasledujúceho príkazu pridajte pravidlo ufw, pričom nahraďte svoju IP adresu tam, kde je zvýraznená:

Tým sa zabezpečí, že k inštancii PostgreSQL sa bude môcť pripojiť iba váš server. Hoci to povoľuje prevádzku cez firewall, musíte tiež upraviť konfiguračné súbory PostgreSQL, aby ste povolili pripojenie z vzdialenej IP adresy. V predvolenom nastavení konfigurácia povoľuje iba pripojenie z localhost. Konfiguračné súbory pre PostgreSQL sa nachádzajú v adresári /etc/postgresql/12/main adresári. 12, v tomto prípade, je verzia PostgreSQL, ktorú sme nainštalovali pre tento návod. Možno ste nainštalovali inú verziu. Preto môžete prejsť do adresára /etc/postgresql/ a vypísať obsah, aby ste zistili číslo verzie nainštalovaného PostgreSQL.

Na úpravu konfiguračného súboru použite nano:

Nájdite riadok nižšie, odkomentujte ho a nastavte ho tak, aby povoľoval pripojenia zo všetkých IP adries:

Uložte a zatvorte súbor. Potom musíte upraviť aj súbor pg_hba.conf, nachádza sa v rovnakom adresári ako postgresql.conf. Súbor pg_hba.conf vám umožňuje definovať, z ktorých počítačov sa môžete pripojiť k inštancii PostgreSQL, ako aj metódu autentifikácie. Otvorte súbor pomocou nano:

Prečítajte si komentáre v tomto súbore, aby ste porozumeli kľúčovým slovám. Hľadaná sekcia je táto:

Building a Django and Gunicorn Application with Docker on Ubuntu 1

Zameriame sa na druhý riadok, po odkomentovaní by mal vyzerať ako riadok nižšie:

Nahraďte zvýraznenú časť IP adresou vášho servera Ubuntu, aby ste mu umožnili pripojiť sa k inštancii PostgreSQL. Keď budete pripravení, súbor uložte. Reštartujte databázu PostgreSQL, aby sa zmeny prejavili:

Náš druhý server Ubuntu so špecifikovanou IP adresou by mal byť schopný pripojiť sa k inštancii Postgresu.

Krok 2: Pripojenie k inštancii servera PostgreSQL a vytvorenie databázy a používateľa

V tomto kroku sa pokúsime zabezpečiť, aby sa inštancia Ubuntu obsluhujúca náš kontajner Docker mohla pripojiť k druhému serveru, na ktorom beží inštancia PostgreSQL. Prihláste sa do inštancie Ubuntu, ktorá má Docker, a nainštalujte balík postgresql-client vo vnútri hostiteľského stroja Ubuntu (zatiaľ nie v kontajneri).

Ako zvyčajne, najprv aktualizujte balík apt a potom nainštalujte balík pomocou nasledujúcich príkazov:

Vyššie nainštalovaný balík vám pomôže vytvoriť databázu a používateľa pre vašu aplikáciu. Ďalej sa musíme pripojiť k inštancii PostgreSQL zadaním parametrov pripojenia klientovi Postgresql.

Parametre pripojenia majú túto syntax:

In this command, the username je používateľ/rola, ktorú ste pridali do svojej databázy PostgreSQL. host je IP adresa inštancie Ubuntu, na ktorej beží vaša databáza PostgreSQL. port je predvolený port, na ktorom Postgres počúva prichádzajúce pripojenia, t. j. 5432. Na mieste database, použijeme predvolenú databázu s názvom postgres, ktorá sa dodáva s inštaláciou PostgreSQL. Nahraďte svoje hodnoty vo zvýraznených častiach a stlačte Enter. Po zobrazení výzvy zadajte heslo, ktoré ste nastavili. Týmto sa prihlásite do príkazového riadku Postgres, kde môžete spravovať databázu.

Úspešne ste sa pripojili k inštancii PostgreSQL. Teraz môžete vytvoriť databázu pre aplikáciu Django polls. Nazvime ju django_polls:

Uistite sa, že váš príkaz končí bodkočiarkou, aby ste predišli chybám. Potom sa prepnite do databázy django_polls pomocou príkazu:

Ďalej vytvorte databázového používateľa špecifického pre tento projekt. Nazvime používateľa django_user:

Vyberte si bezpečné heslo pre svojho používateľa. Po dokončení musíme upraviť parametre pripojenia pre používateľa, ktorého sme práve vytvorili. To pomáha urýchliť databázové operácie tým, že zabezpečí, aby sa správne hodnoty nedopytovali a nenastavovali pri každom nadviazaní pripojenia.

Nastavte predvolené kódovanie, ktoré Django očakáva, na UTF-8:

Ďalej nastavte predvolenú schému izolácie transakcií na „ read committed“, čo blokuje čítanie z nepotvrdených transakcií:

Nastavte svoje časové pásmo. Aby bol návod univerzálny, použijeme UTC:

Nakoniec udeľte novému používateľovi administratívne práva k databáze:

Keď budete pripravení, ukončite príkazový riadok PostgreSQL:

To je pre tento krok všetko. Keď správne nakonfigurujete svoju aplikáciu Django, mala by byť schopná spravovať vašu databázu.

Krok 3: Stiahnutie aplikácie z Git repozitára a definovanie závislostí

V tomto kroku naklonujeme repozitár aplikácie Django-polls. Tento repozitár obsahuje kód pre Django’s tutoriál „Napísanie vašej prvej aplikácie v Django“.

Prihláste sa na server Ubuntu, na ktorom beží Docker, vytvorte adresár s názvom django_project a prejdite doň:

Potom naklonujte repozitár do adresára pomocou nasledujúceho príkazu:

Prejdite do adresára a vypíšte jeho obsah:

Vypíšte obsah adresára:

Building a Django and Gunicorn Application with Docker on Ubuntu 2

Všimnite si nasledujúce položky:

  • manage.py: tento súbor je vstupom do nástroja príkazového riadka, ktorý Django poskytuje na správu vašej aplikácie.

  • mysite: adresár s rozsahom projektu Django a nastaveniami kódu.

  • polls: adresár obsahujúci polls kód aplikácie.

  • templates: obsahuje vlastné súbory šablón pre administrátorské stránky.

Ak sa chcete dozvedieť viac o tom, ako sme projekt skutočne vytvorili, pozrite si Writing your first Django app z oficiálnej dokumentácie. Vo vnútri django-polls adresári chceme mať naše Python závislosti definované v textovom súbore. Nazveme ho requirements.txt. Otvorte súbor vo vašom preferovanom editore:

Vložte do súboru nasledujúce riadky na deklarovanie závislostí:

V tomto súbore sme definovali závislosti Pythonu s ich presnými verziami, ktoré by sa mali nainštalovať pri zostavení aplikácie. Niektoré z nich zahŕňajú Django, django-storages na interakciu s úložiskami objektov, psycopg2 adaptér pre PostgreSQL, gunicorn WSGI server a ďalšie dodatočné závislosti. Po dokončení súbor uložte a zatvorte.

Krok 4: Konfigurácia premenných prostredia pre aplikáciu Django

Metodológia twelve-factor app odporúča, aby ste z kódovej základne vašej aplikácie vyňali pevne zakódované konfigurácie. Tým získate slobodu meniť správanie aplikácie počas jej behu úpravou premenných prostredia bez toho, aby ste zasahovali do kódovej základne. Docker s týmto nastavením spolupracuje, takže upravíme súbor nastavení tak, aby fungoval s premennými prostredia. Kubernetes tiež spolupracuje s týmto nastavením konfigurácie. Ďalší návod na nasadenie s Kubernetes budeme zdieľať na blogu CloudSigma.

Súbor settings.py je hlavný súbor nastavení pre projekt Django. Je to modul Pythonu, ktorý na konfiguráciu aplikácie používa natívne dátové štruktúry. Pre našu aplikáciu sa tento súbor nachádza na mieste django-polls/mysite/settings.py. Väčšina jeho hodnôt je pevne zakódovaná. To by od vás vyžadovalo úpravu konfiguračného súboru v kódovej základni, ak by ste zmenili správanie aplikácie. To chceme zmeniť. Našťastie Python ponúka funkciu getenv v module os. Môžeme ju použiť na konfiguráciu Djanga tak, aby namiesto toho čítalo konfiguračné parametre z lokálnych premenných prostredia.

Pokračujme úpravou súboru django-polls/mysite/settings.py, aby sme nahradili pevne zakódované hodnoty premenných. Možno ich budeme chcieť aktualizovať počas behu pomocou volania os.getenv. Táto funkcia číta hodnotu nastavenú v zadanom názve premennej prostredia. Voliteľne môžete zadať druhý parameter, čo je predvolená hodnota, ktorá sa použije, ak premenná prostredia nie je nastavená.

Tu je príklad:

V riadku vyššie hovoríme Djangu, aby získalo tajný kľúč z premennej prostredia. Neposkytujeme záložnú hodnotu, pretože kľúč poskytneme externe. Ak neexistuje, aplikácia by sa nemala spustiť. Pri externom poskytovaní tajného kľúča chceme tiež zabezpečiť, aby všetky naše kontajnerizované kópie aplikácie používali rovnaký kľúč na rôznych serveroch. Tým sa predíde potenciálnym problémom, ktoré vznikajú, keď rôzne kópie aplikácie používajú rôzne kľúče.

Tu je ďalší príklad s predvolenou možnosťou:

V tomto riadku definujeme premennú prostredia DEBUG, ktorá by sa mala prečítať. Ak však nie je nastavená, poskytli sme druhý parameter, ktorý sa odovzdá premennej nastavení DEBUG. DEBUG je nastavené na False, aby sa zabezpečilo, že citlivé informácie sa nedostanú na frontend v prípade problému s aplikáciou. Ak sme však v režime vývoja, chceme, aby bolo nastavené na True, čo nám umožní vidieť informácie o chybách, aby sme ich mohli ľahšie opraviť.

Teraz, keď poznáte dôležitosť premenných prostredia, otvorte súbor django_project/django-polls/settings.py vo vašom editore. Najprv importujte modul os pridaním tohto riadku na začiatok súboru settings.py:

Potom nájdite tieto premenné a aktualizujte ich nasledovne:

V nastavení ALLOWED_HOSTS určujeme, že má získať hodnotu z DJANGO_ALLOWED_HOSTS premennej prostredia a rozdeliť ju na Python zoznam pomocou čiarky ( ,) ako oddeľovača. Ak premenná chýba, ALLOWED_HOSTS sa nastaví na 127.0.0.1.

Ďalej prejdite súborom a nájdite sekciu DATABASES, nakonfigurujte ju tak, aby tiež čítala z premenných prostredia:

Všimnite si, že sme pridali json.loads modul. Mali by ste tiež pridať import tohto modulu na začiatok súboru settings.py:

Funkcia json.loads deserializuje objekt JSON odovzdaný do DATABASES['default']['OPTIONS'] z premennej prostredia DB_OPTIONS . Určenie tejto možnosti nám umožňuje odovzdať ľubovoľnú dátovú štruktúru na definovanie konfigurácie databázy. Databázový nástroj obsahuje súbor platných možností, ktoré sa naň vzťahujú. Možnosť JSON nám poskytuje flexibilitu zakódovať objekt JSON s príslušnými parametrami pre databázový nástroj, ktorý v danom čase používame.

Nastavenie DATABASES['default']['NAME'] určuje názov databázy v systéme riadenia relačných databáz, ktorý sme nastavili. V prípade použitia databázy SQLite by ste mali uviesť cestu k súboru databázy.

Upozorňujeme, že Python ponúka niekoľko spôsobov, ako čítať externé premenné prostredia. Použili sme iba jeden z nich. Môžete preskúmať a použiť aj iné metódy. V tomto kroku ste sa naučili, ako pracovať s externými premennými prostredia. To vám dáva flexibilitu meniť premenné a upravovať správanie aplikácie bežiacej v kontajneroch. V ďalšom kroku sa naučíte, ako pracovať so službami objektového úložiska.

Krok 5: Práca s externými službami objektového úložiska

Hlavnou výhodou kontajnerizácie vašej aplikácie je jej prenosnosť, ktorá umožňuje jednoduché nasadenie viacerých kópií aplikácie pri zvýšení návštevnosti. Tým sa vytvára priestor na škálovanie. To však prináša problém s udržiavaním verzií statických súborov a prostriedkov v rôznych kontajneroch. Vďaka vylepšeniam v cloudových technológiách môžete tieto zdieľané statické prvky presunúť do externého úložiska. Potom môžete súbory sprístupniť cez sieť všetkým vašim spusteným kontajnerom. Namiesto snahy o synchronizáciu súborov v rôznych spustených kontajneroch máte jedno centrálne miesto na ich správu.

Koncept, ktorý sa snažíme vysvetliť vyššie, je použitie služieb cloudového objektového úložiska alebo Simple Storage Services (S3). Django má balík s názvom django-storages , ktoré vám umožňuje pracovať so vzdialenými backendmi úložísk. Django-storages spolupracuje s väčšinou služieb objektového úložiska kompatibilných s S3, ako sú okrem iného FTP, SFTP, Amazon AWS S3, Google Cloud Storage, Dropbox a Azure Storage. V tomto návode budeme používať MinIO. Pokojne použite akékoľvek iné služby objektového úložiska kompatibilné s S3. MinIO ponúka vysoko výkonné objektové úložisko kompatibilné s S3. S MinIO môžete vybudovať dátovú infraštruktúru kompatibilnú s S3 v akomkoľvek cloude.

Ukážeme vám, ako nastaviť službu úložiska MinIO na platforme CloudSigma. Postupujte podľa týchto krokov:

  • Začnite tým, že si vytvoríte účet na CloudSigma. Ak narazíte na akékoľvek problémy pri vytváraní úložiska MinIO, spojte sa s bezplatnou 24/7 live chat podporou CloudSigma’s, a oni vám pomôžu.

  • Pridajte svoje fakturačné údaje.

  • Ďalej požiadajte o svoj verejne prístupný bucket odtiaľto: https://blog.cloudsigma.com/xxxx. Na získanie prístupových údajov k účtu budete musieť kontaktovať podporu cez Live Chat.

  • Po vytvorení vášho prostredia objektového úložiska MinIO vám budú poskytnuté prístupové údaje a ďalšie pokyny na prístup k nemu. Prístupové údaje by mali obsahovať váš MINI_ACCESS_KEY, MINIO_SECRET_KEY, a MINIO_URL. Tieto kľúče použijete v pokynoch nižšie.

Urobme ešte niekoľko zmien v súbore mysite/settings.py, ktorý sme upravovali v predchádzajúcom kroku. V súbore pridajte aplikáciu storages do zoznamu Django INSTALLED_APPS:

INSTALLED_APPS

Aplikácia storages sa inštaluje cez django-storages, ako je definované v requirements.txt. Prejdite na koniec súboru a nahraďte premennú STATIC_URL nasledujúcim fragmentom kódu:

Všimnite si, že niektoré konfiguračné premenné sú pevne zakódované (hardcoded):

  • STATICFILES_STORAGE: definuje backend úložiska, ktorý Django použije na správu statických súborov. V našom návode používame úložisko MinIO, ale môžete použiť akýkoľvek backend kompatibilný s S3, ako je vysvetlené v dokumentácii k Django Storages.

  • AWS_S3_OBJECT_PARAMETERS: definuje hlavičky cache-control.

  • AWS_LOCATION: toto používame na nastavenie adresára v rámci bucketu úložiska, kde budú uložené všetky statické súbory. Môžete si vybrať iný názov.

  • AWS_DEFAULT_ACL: nastavuje zoznam riadenia prístupu (ACL) pre statické súbory. Nastavenie hodnoty na ‘ public-Read’ sprístupní súbory všetkým verejným používateľom.

  • STATIC_URL: Django používa základnú URL adresu nastavenú v tejto premennej na generovanie URL adries pre statické súbory. Základná URL adresa je v tomto prípade odvodená spojením URL adresy koncového bodu (endpointu) a podadresára statických súborov.

  • STATIC_ROOT: definuje, kde sa majú statické súbory zhromaždiť lokálne pred ich skopírovaním do vzdialeného objektového úložiska.

Máme tiež niekoľko externe definovaných premenných prostredia na zachovanie flexibility a prenosnosti:

  • AWS_STORAGE_BUCKET_NAME: definuje názov úložného vedra, do ktorého bude Django nahrávať prostriedky.

  • AWS_S3_ENDPOINT_URL: definuje URL adresu koncového bodu používanú na prístup k službe objektového úložiska. Toto bude URL adresa namapovaná na server, ktorý hostuje vašu službu MinIO.

Po dokončení úprav súbor uložte a zatvorte.

Keď budete mať tieto nastavenia na svojom mieste a nainštalujete deklarované závislosti Pythonu, môžete spustiť príkaz Django manage.py collectstatickedykoľvek na zhromaždenie statických súborov vášho projektu a ich nahranie do vzdialeného backendu objektového úložiska:

Zatiaľ sme však nenastavili env súbor s konfiguráciami, takže to pravdepodobne zlyhá.

Keď spustíte tento príkaz, kopírovanie vašich prostriedkov do cloudového úložiska MinIO chvíľu potrvá v závislosti od ich veľkosti a rýchlosti vášho internetu.

To je pre tento krok všetko. Pozrime sa, ako môžeme vyriešiť odosielanie logov Django do Docker Engine, aby ste si ich mohli prezrieť pomocou príkazu docker logs v nasledujúcom kroku.

Krok 6: Nastavenie logovania v aplikácii Django

V režime ladenia, keď je možnosť DEBUG nastavená na True, Django zaznamenáva informácie do štandardného výstupu a štandardnej chyby. Informácie o logoch sa zvyčajne zobrazujú v termináli, z ktorého ste spustili vývojový HTTP server.

V produkcii pravdepodobne používate iný HTTP server a možnosť DEBUG je nastavená na False. Django v tomto prípade použije inú metódu logovania. Django posiela logy s prioritou ERROR alebo CRITICAL na e-mailový účet správcu, ktorý definujete. To funguje skvele v mnohých situáciách.

V kontajnerizovaných prostrediach a prostrediach Kubernetes sa dôrazne odporúča logovanie do štandardného výstupu a štandardnej chyby. Logovacie správy sa zhromažďujú v jednom adresári v súborovom systéme uzla a sú ľahko prístupné pomocou príkazov kubectl a docker . Vďaka centralizovanému bodu logovania v súborovom systéme uzla môže operačný tím jednoducho spúšťať procesy na každom uzle na sledovanie a preposielanie logov. Preto musíme našu aplikáciu nakonfigurovať tak, aby zapisovala logy do tohto štandardného nastavenia.

Určite vás poteší, že Django využíva vysoko prispôsobiteľný modul logging zo štandardnej knižnice Pythonu. To vám umožňuje definovať slovník, ktorý prechádza cez logging.config.dictConfig na definovanie požadovaných výstupov a formátovania. Tu je skvelý článok o Django Logging, The Right Way, ktorý vám môže pomôcť zvládnuť techniky logovania v Django.

Otvorte súbor django-polls/mysite/settings.py  vo vašom editore. Pridajte import pre knižnicu Pythonu logging.config na začiatok súboru:

Doteraz, so všetkými importmi, ktoré sme pridali, by mala vaša sekcia importov v settings.py vyzerať takto:

Building a Django and Gunicorn Application with Docker on Ubuntu 3

Knižnica logging.config prijíma slovník novej konfigurácie logovania prostredníctvom funkcie dictConfig na prepísanie predvoleného správania logovania v Django.

Prejdite na koniec súboru a pridajte nasledujúci úryvok kódu konfigurácie logovania:

LOGGING_CONFIG je nastavená na None na zakázanie/vymazanie predvolených konfigurácií logovania, ktoré definuje Django. LOGLEVEL je nastavená prostredníctvom DJANGO_LOGLEVEL premennej prostredia. Ak však neexistuje, chceme ju nastaviť na ‘ info’.

Modul logging.config, ktorý sme importovali na začiatku, poskytuje funkciu dictConfig, ktorá sa používa na nastavenie nového konfiguračného slovníka. Slovník definuje formátovanie textu pomocou kľúča formatters. Výstup sa nastavuje pomocou kľúča handlers a nakoniec kľúč loggers definuje, ktorá správa má ísť do ktorého handlera.

Keď máte tieto nastavenia definované, Docker sprístupní logy prostredníctvom príkazu docker logs. Podobne v inom návode, ktorý budeme robiť pre Kubernetes, môžete logy zobraziť pomocou príkazu kubectl logs príkazu. Poďme teraz v ďalšom kroku začať proces kontajnerizácie.

Krok 7: Definovanie Dockerfile aplikácie

V tomto kroku definujeme konfiguráciu na spustenie obrazu kontajnera, v ktorom pobeží aplikácia Django obsluhovaná WSGI serverom Gunicorn. Definujeme runtime prostredie na zostavenie obrazu kontajnera, nainštalujeme aplikáciu a jej závislosti a vykonáme niekoľko záverečných konfigurácií.

  • Rodičovský obraz pre aplikáciu Django

Rozhodnutie o základnom obraze, na ktorom postavíte svoj kontajner, je úplne prvým rozhodnutím, ktoré urobíte pri riešení kontajnerizovaného nasadenia. Samozrejme, máte možnosť zostaviť svoje obrazy kontajnerov od nuly (SCRATCH), t. j. z prázdneho súborového systému, alebo ich založiť na existujúcom obraze kontajnera. Keďže nechceme znova objavovať koleso, náš obraz zostavíme zo základného obrazu. K dispozícii je mnoho open-source obrazov kontajnerov z oficiálneho repozitára obrazov kontajnerov Docker. Pokiaľ nezostavujete svoj obraz od nuly, dôrazne sa odporúča použiť obraz z oficiálneho hubu Docker. Je to preto, že Docker overuje, či obrazy dodržiavajú osvedčené postupy, a zabezpečuje pravidelné aktualizácie a bezpečnostné záplaty.

Keďže Django je framework pre Python, využijeme obraz so štandardným prostredím Pythonu, ktorý už má nainštalované nástroje a knižnice, ktoré potrebujeme. Na oficiálnej stránke pre obrazy Pythonu na Docker hube, môžete nájsť obraz založený na Pythone pre rôzne verzie Pythonu.

Z našich rôznych návodov založených na Dockeri, si všimnete, že používame obrazy založené na Alpine Linux. Alpine Linux ponúka robustné, ale štíhle prostredie operačného systému na spúšťanie kontajnerizovaných aplikácií. Hoci je jeho súborový systém malý, je rozšíriteľný a prichádza s kompletným systémom správy balíkov s možnosťou pridávania funkcií.

Pri výbere základného obrazu na Docker hube si môžete všimnúť, že pre každý obraz je k dispozícii viacero tagov. Pre Python, máme k dispozícii 3-alpine, čo odkazuje na najnovší obraz verzie Python 3 najnovšej verzie Alpine. To znamená, že v prípade, že váš projekt pracuje so staršou verziou obrazu, môže sa poškodiť, keď správcovia obrazu Docker vykonajú aktualizáciu. Aby ste sa v budúcnosti vyhli takýmto scenárom, vždy sa odporúča vybrať najšpecifickejšie tagy pre obraz, ktorý chcete použiť.

V tomto návode použijeme 3.8.12-alpine3.15 obraz ako základný obraz pre našu aplikáciu Django. Tento konkrétny tag bude špecifikovaný v Dockerfile pomocou inštrukcie FROM. Dockerfile sa bude nachádzať v hlavnom adresári projektu: django_project.

Začnite tým, že prejdete z adresára Django-polls späť do adresára django_project:

Keď sa ocitnete v adresári, otvorte pomocou svojho obľúbeného editora súbor s názvom Dockerfile :

Ďalej vložte nasledujúci riadok, ktorým nastavíte základ svojho obrazu:

Kľúčové slovo FROM  definuje počiatočný bod vlastného obrazu Docker. Po jeho definovaní môžeme pokračovať v pridávaní inštrukcií na nastavenie aplikácií. Tieto inštrukcie nainštalujú potrebné závislosti, skopírujú súbory aplikácie a nastavia prostredie pre spustenie.

Pridajte nasledujúci úryvok kódu do súboru Dockerfile:

V tomto úryvku kódu hovoríme Dockeru, aby skopíroval súbor requirements.txt  do /app/requirements.txt, aby sa zabezpečilo, že závislosti aplikácie budú dostupné v súborovom systéme obrazu. Požiadavky zahŕňajú všetky balíky Pythonu potrebné na spustenie aplikácie. Závislosti sa kopírujú ako prvé, aby Docker mohol uložiť vrstvu obrazu do vyrovnávacej pamäte. Je to preto, že Docker ukladá do vyrovnávacej pamäte každý krok v Dockerfile. Prvé zostavenie obrazu zvyčajne trvá dlhšie. Docker stiahne závislosti a potom ich uloží do vyrovnávacej pamäte. Ak sa súbor requirements.txt nezmení, Docker bude stavať z vyrovnávacej pamäte, čím sa následné zostavenia zrýchlia.

Ďalší krok obsahuje inštrukciu RUN, ktorá vykoná zoznam príkazov Linuxu, zreťazených pomocou operátora Linuxu &&. Tieto príkazy robia nasledovné:

  • Použijú nástroj na správu balíkov Alpine apk na inštaláciu vývojových súborov PostgreSQL a základných závislostí pre zostavenie.

  • Vytvoria virtuálne prostredie Pythonu.

  • Nainštalujú závislosti Pythonu definované v súbore requirements.txt pomocou pip.

  • Skompilujú potrebné balíky pre spustenie analýzou požiadaviek nainštalovaných balíkov Pythonu.

  • Odstránia všetky závislosti pre zostavenie, ktoré už nie sú potrebné.

Dôvodom zreťazenia príkazov v kroku RUN je zníženie počtu vrstiev obrazu. Docker vytvorí novú vrstvu obrazu nad existujúcim súborovým systémom zakaždým, keď narazí na ADD, COPY, alebo RUN inštrukcia v súbore Dockerfile. Komprimovanie príkazov tam, kde je to vhodné, minimalizuje počet vytvorených vrstiev obrazu.

Položky pridané do vrstiev obrazu nie je možné v nasledujúcej vrstve odstrániť. Pred prechodom na ďalšiu inštrukciu musíte deklarovať inštrukcie na vymazanie nežiaducich položiek. Je to potrebné na zmenšenie veľkosti obrazu. Mali by ste si všimnúť, že sme pridali apk del príkaz na konci RUN príkazu. To sa urobilo s cieľom odstrániť závislosti zostavenia po tom, čo sme ich použili na zostavenie balíkov aplikácie.

Ďalej tu máme ďalšiu ADD inštrukciu, ktorú používame na skopírovanie kódu aplikácie do /app adresára. Potom použijeme WORKDIR inštrukciu na nastavenie pracovného adresára obrazu na /app adresár, ktorý teraz obsahuje kód aplikácie.

Ďalej tu máme ENV inštrukcie, ktoré používame na nastavenie dvoch premenných prostredia, ktoré obraz sprístupní spusteným kontajnerom. Najprv nastavíme VIRTUAL_ENV premennú na /env. Po druhé, nastavíme PATH premennú tak, aby zahŕňala /env/bin adresár. V týchto dvoch riadkoch načítavame /env/bin/activate skript, čo je spôsob, akým aktivujeme virtuálne prostredie v prostredí Linuxu. Viac o práci s virtuálnymi prostrediami v Pythone na iných operačných systémoch. Poslednou inštrukciou je EXPOSE príkaz, ktorý nastavuje port, 8000 na ktorom bude kontajner počúvať počas spúšťania.

V tejto chvíli je váš Dockerfile takmer kompletný, okrem predvoleného príkazu, ktorý sa spustí pri štarte kontajnerov. Poďme ho definovať v nasledujúcej časti.

  • Pochopenie predvoleného príkazu obrazu Docker

Pri spúšťaní kontajnera Docker môžete zadať príkaz na vykonanie. Ak však príkaz nezadáte, predvolený príkaz obrazu Docker určí, čo sa stane po spustení kontajnera. Na definovanie predvoleného príkazu v súbore Dockerfile používame inštrukcie ENTRYPOINT alebo CMD samostatne alebo spoločne na definovanie predvoleného príkazu v súbore Dockerfile.

Ak sa rozhodnete definovať obidve inštrukcie ENTRYPOINT a CMD, v inštrukcii ENTRYPOINT definujete spustiteľný súbor, ktorý bude kontajner spúšťať. V inštrukcii CMD definujte predvolený zoznam argumentov pre spustiteľný príkaz. Predvolený zoznam argumentov môžete prepísať pridaním alternatívnych argumentov v príkazovom riadku pri spúšťaní kontajnera vo formáte:

Tento formát bráni vývojárom v jednoduchom prepísaní príkazu ENTRYPOINT. Príkaz ENTRYPOINT je definovaný tak, aby volal skript, ktorý nastaví prostredie a vykoná rôzne akcie na základe poskytnutého zoznamu argumentov.

Inštrukciu ENTRYPOINT môžete použiť aj samostatne na konfiguráciu spustiteľného súboru kontajnera. Tento formát však neumožňuje definovať predvolený zoznam argumentov. Argumenty môžete zadať pri spustení kontajnera pomocou príkazu docker run .

Ak sa rozhodnete použiť iba CMD  , Docker to interpretuje ako predvolený príkaz a zoznam argumentov, ktoré môžete prepísať počas spúšťania. Viac informácií nájdete v oficiálnej referenčnej dokumentácii k Dockerfile.

Pozrime sa, ako môžeme uplatniť informácie, ktoré ste sa dozvedeli o predvolených príkazoch, na našom príklade kontajnera. Predvolene chceme aplikáciu spúšťať pomocou servera gunicorn. Hoci zoznam argumentov odovzdaných serveru gunicorn nemusí byť konfigurovateľný počas spúšťania, chceme flexibilitu spúšťania iných príkazov na účely, ako je ladenie alebo správa konfigurácií (inicializácia databázy, zhromažďovanie statických súborov atď.). Ako vidíte, je v našom najlepšom záujme použiť CMD na definovanie predvoleného príkazu, ktorý nám umožní ho v prípade potreby prepísať.

Tu sú niektoré syntaxe, ktoré môžete použiť na definovanie príkazu CMD:

  • CMD ["command", "argument 1", "argument 2", . . . ,"argument n"]: Formát exec (odporúčaný formát) prijíma príkaz a zoznam argumentov. Vykoná príkaz priamo bez spracovania shellom.
  • CMD command "argument 1" "argument 2" . . . "argument n": Formát shell definuje príkaz a zoznam argumentov. Odovzdáva zoznam príkazov shellu na spracovanie. Môže to byť užitočné, ak chcete v príkaze nahradiť premenné prostredia, avšak nie je to úplne predvídateľné.
  • CMD ["argument 1", "argument 2", . . . ,"argument n"]: Formát zoznamu argumentov, definuje iba predvolený zoznam argumentov a používa sa spolu s ENTRYPOINT inštrukciou.

Budeme používať exec formát na definovanie našej finálnej inštrukcie v Dockerfile. Pridajte nasledujúci riadok na koniec vášho Dockerfile:

Teraz môžete uložiť a zatvoriť Dockerfile.

Keď spustíte kontajnery pomocou tohto obrazu, vykonajú gunicorn naviazaný na port localhostu 8000 s 3 workermi a zavolajú funkciu application v súbore wsgi.py nájdenom v adresári mysite . Môžete sa rozhodnúť poskytnúť iný príkaz na prepísanie predvoleného príkazu pri spustení a spustiť iný proces namiesto gunicorn. Možno sa budete chcieť dozvedieť viac o workeroch Gunicorn.

Váš Dockerfile je teraz pripravený a môžete použiť docker build na zostavenie obrazu aplikácie. Môžete použiť docker run na spustenie kontajnera na vašom lokálnom vývojovom stroji.

  • Zostavenie Docker obrazu

Príkaz docker build bude predvolene hľadať Dockerfile v aktuálnom adresári, aby našiel inštrukcie na zostavenie. Taktiež odosiela „kontext“ zostavenia (build context) démonovi Docker. kontext zostavenia je množina súborov, ktoré by mali byť dostupné počas procesu zostavovania. Predvolene je aktuálny adresár, v ktorom spúšťate príkaz docker build , nastavený ako kontext zostavenia.

Keď ste v rovnakom adresári, ktorý obsahuje váš Dockerfile, spustite príkaz docker build. Zadajte obraz a tag pomocou príznaku -t a nastavte aktuálny adresár ako kontext zostavenia pomocou bodky ( .) na konci príkazu:

V tomto príkaze sme pomenovali obraz django-polls a tag v1. Všimnite si bodku na konci príkazu, používame ju na označenie aktuálneho adresára ako kontextu zostavenia.

Po dokončení docker build by ste mali vidieť niečo podobné nasledujúcemu výstupu:

Building a Django and Gunicorn Application with Docker on Ubuntu 4

Váš Docker obraz je teraz pripravený. Ak by sme nepresunuli niektoré konfigurácie do externých premenných prostredia, mohli by ste jednoducho spustiť svoj kontajner pomocou príkazu docker run . Keďže sme však nenakonfigurovali externé premenné prostredia, ktoré sme nastavili v súbore settings.py , spustenie zlyhá. Poďme to dokončiť v ďalšom kroku.

Krok 8: Nastavenie runtime prostredia a testovanie aplikácie

Blížime sa ku koncu tohto návodu. V tomto kroku budeme konfigurovať premenné prostredia v súbore env . S premennými v súbore env na svojom mieste môžeme vytvoriť schému databázy, vygenerovať a nahrať statické súbory do externej služby úložiska objektov a nakoniec otestovať aplikáciu.

Docker prichádza s niekoľkými metódami, ktoré môžete použiť na poskytnutie premenných prostredia do kontajnera. V našom prípade chceme poskytnúť zoznam premenných prostredia prostredníctvom súboru. Preto použijeme metódu --env-file.

Pomocou vášho preferovaného editora vytvorte súbor s názvom env v adresári django_project:

Vložte nasledujúci zoznam premenných:

Premenné v zozname sú tie, ktoré ste definovali v predchádzajúcich krokoch:

  • DJANGO_SECRET_KEY: Vygenerujte jedinečnú, nepredvídateľnú hodnotu, ako je vysvetlené v Django docs. Na vygenerovanie náhodného reťazca a jeho nastavenie do premennej môžete použiť tento príkaz:

  • DEBUG: Túto hodnotu sme nastavili na True, ale pre produkčné nasadenie ju nezabudnite nastaviť na False ponechaním prázdneho miesta.

  • DJANGO_LOGLEVEL: toto sme nastavili na info, pokojne ju upravte na požadovanú úroveň.

  • DJANGO_ALLOWED_HOSTS: nastavte túto hodnotu na IP adresu servera Ubuntu, na ktorom bežia vaše Docker kontajnery. Voliteľne ju nastavte na *, zástupný znak zodpovedajúci všetkým hostiteľom, ak ste vo vývojovom režime.

  • DB_DATABASE: ak ste použili iný názov databázy, nastavte ho tu zodpovedajúcim spôsobom.

  • DB_USERNAME: nastavte toto na používateľské meno, ktoré ste si vybrali pre svoju databázu.

  • DB_PASSWORD: nastavte toto na heslo, ktoré ste si vybrali pre svoju databázu.

  • DB_HOST: nastavte toto na hostiteľa, na ktorom beží vaša databázová inštancia, ako ste to nastavili v Prvom kroku.

  • DB_PORT: nastavte toto na port vašej databázy.

  • STATIC_MINIO_BUCKET_NAME: nastavte toto na názov bucketu, ktorý ste vytvorili vo svojom účte cloudového úložiska MinIO.

Po dokončení úprav súbor uložte a zatvorte.

Konfigurácie prostredia sú teraz pripravené. Musíme spustiť kontajner s odovzdaním argumentov na prepísanie predvoleného príkazu CMD a vytvoriť schému databázy pomocou príkazov manage.py makemigrations a manage.py migrate.

Tu je príkaz:

V tomto príkaze spúšťame obraz kontajnera django-polls:v1 , pričom používame príznak env-file na odovzdanie súboru s premennými prostredia. Tiež prepíšeme predvolený príkaz CMD príkazom sh -c "python manage.py makemigrations && python manage.py migrate" Keď sa tento príkaz spustí na naštartovanie kontajnera, vytvorí schému databázy tak, ako je definovaná v kóde aplikácie.

V prípade úspechu by ste mali vidieť výstup podobný tomu nižšie:

Building a Django and Gunicorn Application with Docker on Ubuntu 4

Výstup naznačuje, že schéma databázy bola úspešne vytvorená.

Ďalším krokom je vytvorenie administrátorského používateľa pre aplikáciu Django. Spustíme kontajner a otvoríme v ňom interaktívny shell pomocou nasledujúceho príkazu:

Príkaz spustí kontajner s príkazovým riadkom shellu, ktorý môžete použiť na interakciu s Python shellom. Vytvorme používateľa:

Postupujte podľa výziev a zadajte používateľské meno, e-mailovú adresu, heslo, znova zadajte heslo a stlačením klávesu Enter vytvorte používateľa. Ukončite shell a zastavte kontajner stlačením CTRL+D.

Ďalej musíme kontajner spustiť znova, pričom prepíšeme predvolený príkaz príkazom Django collectstatic na vygenerovanie statických súborov pre aplikáciu a ich nahranie do vašej cloudovej služby úložiska MinIO:

Po dokončení by ste mali vidieť podobný výstup ako nižšie, ktorý indikuje, že váš kontajner sa úspešne pripojil k službe úložiska MinIO a nahral statické súbory:

static files

Náš úložný bucket teraz vyzerá takto, s adresármi, ktoré vytvorilo Django:

Building a Django and Gunicorn Application with Docker on Ubuntu 5

Nakoniec môžeme aplikáciu spustiť pomocou príkazu:

Tu je výstup:

output

Keď vykonáte vyššie uvedený príkaz, spustí sa predvolený príkaz CMD vo vašom obraze a sprístupní sa port 8000 tak, ako je definované. Teraz sa Ubuntu na porte 80 namapuje na 8000 port django-polls:v1 kontajnera.

Teraz môžeme aplikáciu otestovať v prehliadači. Prejdite na verejnú IP adresu vášho servera v prehliadači: http://your_server_public_ip.

Očakávajte chybu 404 Page Not Found, pretože podľa Django Tutorial, sme nedefinovali trasu pre / cestu:

page not found

Máme premennú DEBUG nastavenú na True, preto vidíme túto chybovú stránku s množstvom dôležitých informácií. Zrušme nastavenie premennej DEBUG. Najprv budete musieť zastaviť bežiaci kontajner pomocou CTRL+C. Potom otvorte env súbor:

Ďalej nájdite premennú DEBUG a zrušte jej nastavenie, alebo ju nechajte prázdnu. Necháme ju prázdnu, pretože funkcia getenv interpretuje False ako reťazec, a preto vracia true:

Uložte súbor a znova spustite kontajner pomocou príkazu:

Ak navštívite http://your_server_public_ip vo vašom prehliadači, mali by ste vidieť predvolenú stránku 404:

not found

Videli ste, ako môžete manipulovať so správaním vašej aplikácie Django počas behu pomocou premenných prostredia bez úpravy zdrojového kódu.

Prejdite na http://your_server_public_ip/polls a zobrazí sa domovská stránka Polls:

Building a Django and Gunicorn Application with Docker on Ubuntu 6

Nemáme žiadne ankety, keďže sme aplikáciu práve nasadili.

Prejdite do administračného rozhrania: http://your_server_public_ip/admin a zobrazí sa okno overenia správcu:

polls administration

Zadajte prihlasovacie údaje, ktoré ste nastavili pomocou príkazu createsuperuser na prihlásenie. Teraz by ste mali byť v rozhraní administratívnej stránky:

site administration

Upozorňujeme, že všetky statické súbory sú poskytované z externej úložnej služby, ktorú sme nastavili. Môžete kliknúť pravým tlačidlom myši v okne prehliadača a vybrať View Page Source:

external storage

Môžete pridať niekoľko otázok a možností a otestovať celkový výkon aplikácie:

questions and choices

Vráťte sa na index Polls http://your_server_public_ip/polls a skúste hlasovať o otázke:

django framework

Po otestovaní a potvrdení, že všetko funguje podľa očakávania, môžete kontajner ukončiť.

Záver

Úspešne ste nakonfigurovali webovú aplikáciu Django tak, aby dobre fungovala v prostredí založenom na kontajneroch. To zahŕňalo prispôsobenie aplikácie na prácu s externými premennými prostredia, nastavenie aplikácie na používanie cloudovej úložnej služby pre statické súbory a vytvorenie súboru Dockerfile pre obraz kontajnera. Zmeny, ktoré sme vykonali na dockerizáciu aplikácie, si môžete pozrieť vo django-polls-docker vetve django-polls GitHub repozitára.

Od tohto momentu sú možnosti obmedzené len vašou predstavivosťou. Môžete nastaviť reverzné proxy Nginx, ktoré bude stáť medzi klientmi a serverom Gunicorn. Môžete tiež pridať Certbot na získanie certifikátov TLS na zabezpečenie vášho servera Nginx. Odporúčame pridať HTTP proxy na ukladanie pomalých klientov do vyrovnávacej pamäte a ochranu vášho servera Gunicorn pred útokmi typu Denial of Service (odmietnutie služby).

Hoci sme v spúšťacom príkaze v Dockerfile definovali 3 workery, môžete si nastaviť preferovaný počet v závislosti od zdrojov dostupných na vašom serveri. Viac informácií nájdete v official Gunicorn design docs. Ak si prajete, môžete vytvorený obraz Docker odoslať do služby Docker Hub a pokúsiť sa ho nasadiť v niekoľkých prostrediach, ktoré majú nainštalovaný Docker. Ak sa chcete dozvedieť viac, sledujte náš Тutorials blog, pretože pripravujeme nadväzujúci tutoriál o zabezpečení aplikácie Django pomocou Nginx a Let’s Encrypt.

Na záver uvádzame ďalšie zdroje, ktoré vám pomôžu pri používaní Dockeru:

Príjemnú prácu!

author

Shreyas Patil

Autor · CloudSigma

Preslav Dobrev je kreatívny dizajnér v spoločnosti CloudSigma, ktorý sa zameriava na konzistentnú firemnú identitu prostredníctvom tradičných a inovatívnych marketingových kanálov. Dokáže brilantne spájať umeleckú víziu so strategickým marketingom, čím vytvára pôsobivé príbehy značky.

Komentáre

Zatiaľ žiadne komentáre. Buďte prvý.