← Back to blog

Django és Gunicorn alkalmazás építése Dockerrel Ubuntu rendszeren

Category
Django és Gunicorn alkalmazás építése Dockerrel Ubuntu rendszeren

Django egy magas szintű, nyílt forráskódú Python webes keretrendszer, amely segít a Python-alkalmazás gyors felépítésében. Támogatja a gyors fejlesztést és a tiszta, pragmatikus tervezést a modell–sablon–nézet (model–template–views) építészeti minta követésével. A keretrendszer alapból tartalmazza a szükséges modern alkalmazás-összetevőket, mint például a felhasználói hitelesítés, gyorsítótárazási keretrendszer, objektum-relációs leképző, URL-irányító, sablonrendszer, és testreszabható adminisztrációs felület.

Gunicorn ‘Green Unicorn’ egy Python WSGI HTTP szerver UNIX rendszerekhez. A Gunicorn szerver kompatibilis a különböző webes keretrendszerekkel, kiváló teljesítményt nyújt, és kíméli a szerver erőforrásait. Docker egy nyílt forráskódú konténerplatform, amely már egy ideje létezik, és gyorssá, hatékonnyá és kiszámíthatóvá teszi az alkalmazásfejlesztést.

Ebben az útmutatóban Ön készségeket szerez a skálázható, konténerizált Django webalkalmazások fejlesztésében és telepítésében. Egy olyan Django Polls alkalmazást fogunk használni, amelyet a Django bevezető útmutatóit követve hoztunk létre. Az útmutató írásakor ezt a Django 3.2 verzióra alapoztuk, amelyet a Python 3.6 vagy újabb verzió támogat. Az alkalmazást konténerként fogjuk telepíteni a Docker segítségével, és a Gunicorn szerverrel fogjuk kiszolgálni. Természetesen, mielőtt a Django alkalmazást konténerben telepítené, el kell végeznie néhány módosítást a projekt kódján, hogy kezelni tudja az olyan dolgokat, mint a szabványos kimeneti folyamatokba való naplózás és a környezeti változókkal való munka. A statikus fájlok, például a CSS- és JavaScript-fájlok, valamint a képek kiszervezhetők objektumtároló szolgáltatásokba, hogy lehetővé tegyék a fájlok egyszerű kezelését egyetlen helyről egy többkonténeres környezetben.

Megmutatjuk, hogyan hajthatja végre ezeket a módosításokat a skálázható webalkalmazások építésére szolgáló, jól kidolgozott twelve-factor módszertan alapján. A módosítások elvégzése után elkészíti az alkalmazás Docker-képfájlját (image), és telepíti a konténerizált alkalmazást a Docker segítségével. Javasoljuk, hogy kövesse az útmutatóban leírt lépéseket, hogy teljes mértékben megértse a folyamatot.

Előfeltételek

Mivel ez egy gyakorlati útmutató, javasoljuk, hogy rendelkezzen az alábbi beállításokkal a követés megkönnyítése érdekében:

Ezen előfeltételek alapján két Ubuntu szerverpéldánnyal kell rendelkeznie. Az egyik példányon a Docker konténer fog futni, a másikon pedig a PostgreSQL példány. Kezdjük el!

1. lépés: A PostgreSQL adatbázis-példány konfigurálása

Ebben a szakaszban módosítani fogjuk a Postgres konfigurációit a Postgres példányt futtató Ubuntu szerveren. Ez lehetővé teszi a külső IP-címről történő csatlakozást. Miután csatlakozott, létrehozhatunk egy adatbázist és egy felhasználói szerepkört, kifejezetten az általunk telepített Django Polls alkalmazáshoz.

Először is, ha a környezetét a Prerequisites szerint állította be, akkor a PostgreSQL adatbázisában már rendelkeznie kell egy szerepkörrel a sudo felhasználója számára. Ezután be kell állítanunk egy jelszót ehhez a szerepkörhöz. Miközben a PostgreSQL-t futtató szerveren tartózkodik, jelentkezzen be a Postgres terminálba a következő paranccsal:

A Postgres terminálban adja ki a \password parancsot egy felhasználó jelszavának módosításához. A \password parancs szintaxisa a következő: \password <username>. A mi esetünkben a parancs:

Adja meg a jelszót, majd erősítse meg. Mentse el ezt a jelszót egy biztonságos helyre, mivel később a másik Ubuntu szerverről történő hitelesítéshez fogja használni. Ezután gépelje be a exit parancsot, és nyomja meg az Entert a Postgres terminálból való kilépéshez.

Ha engedélyezte a tűzfalat (ufw) a PostgreSQL szerverpéldányon, engedélyeznie kell a forgalmat a Postgres alapértelmezett portjára: 5432. Korlátozhatja a forgalmat úgy, hogy az csak a Docker konténert futtató másik Ubuntu szerverének egy adott IP-címéről érkezzen. Futtassa a következő parancsot az ufw szabály hozzáadásához, a kiemelt részen helyettesítve az IP-címét:

Ez biztosítja, hogy csak az Ön szervere tudjon csatlakozni a PostgreSQL példányhoz. Bár ez átengedi a forgalmat a tűzfalon, a PostgreSQL konfigurációs fájljait is módosítania kell, hogy engedélyezze a csatlakozást a távoli IP-címről. Alapértelmezés szerint a konfiguráció csak a localhostról történő csatlakozást engedélyezi. A PostgreSQL konfigurációs fájljai a /etc/postgresql/12/main könyvtárban találhatók. A 12 ebben az esetben a PostgreSQL azon verziója, amelyet ehhez az útmutatóhoz telepítettünk. Előfordulhat, hogy Ön más verziót telepített. Ezért átválthat a /etc/postgresql/ könyvtárba, és kilistázhatja a tartalmat a telepített PostgreSQL verziószámának megkereséséhez.

Használja a nano-t a konfigurációs fájl módosításához:

Keresse meg az alábbi sort, vegye ki a kommentjelet, és állítsa be úgy, hogy engedélyezze a csatlakozást az összes IP-címről:

Mentse és zárja be a fájlt. Ezután szerkesztenie kell a pg_hba.conf fájlt is, ez ugyanabban a könyvtárban van, mint a postgresql.conf. A pg_hba.conf lehetővé teszi annak meghatározását, hogy mely számítógépekről csatlakozhat a PostgreSQL példányhoz, valamint a hitelesítés módját. Nyissa meg a fájlt a nano segítségével:

Kérjük, olvassa el a fájlban található megjegyzéseket a kulcsszavak megértéséhez. A keresett szakasz a következő:

Building a Django and Gunicorn Application with Docker on Ubuntu 1

A fókuszunk a második soron lesz, azt szeretnénk, hogy a kommentjel eltávolítása után így nézzen ki:

Kérjük, cserélje ki a kiemelt részt az Ubuntu szervere IP-címére, hogy engedélyezze a csatlakozást a PostgreSQL példányhoz. Mentse el a fájlt, ha elkészült. Indítsa újra a PostgreSQL adatbázist a változtatások érvénybe léptetéséhez:

A megadott IP-címmel rendelkező másik Ubuntu szerverünknek képesnek kell lennie csatlakozni a Postgres példányhoz.

2. lépés: Csatlakozás a PostgreSQL szerverpéldányhoz, valamint adatbázis és felhasználó létrehozása

Ebben a lépésben megpróbáljuk biztosítani, hogy a Ubuntu instance amely a Docker konténerünket kiszolgálja, csatlakozni tudjon a másik szerverhez, amelyen a PostgreSQL instance fut. Jelentkezzen be az Ubuntu példányra, amelyen a Docker található, és telepítse a postgresql-client csomagot az Ubuntu gazdagépen (még nem a konténeren belül).

Szokás szerint először frissítse az apt csomagot, majd telepítse a csomagot a következő parancsokkal:

A fent telepített csomag segíteni fog az adatbázis és a felhasználó létrehozásában az alkalmazásához. Ezután csatlakoznunk kell a PostgreSQL példányhoz a kapcsolati paraméterek átadásával a PostgreSQL kliensnek.

A kapcsolati paraméterek a következő szintaxist követik:

Ebben a parancsban a username az a felhasználó/szerepkör, amelyet hozzáadott a PostgreSQL adatbázisához. host az Ön PostgreSQL adatbázisát futtató Ubuntu példány IP-címe. port az az alapértelmezett port, amelyen a Postgres a bejövő kapcsolatokat fogadja, azaz 5432. A database helyén a postgres nevű alapértelmezett adatbázist fogjuk használni, amely a PostgreSQL telepítésével együtt jár. Helyettesítse be a saját értékeit a kiemelt részeken, majd nyomja meg az Entert. Amikor a rendszer kéri, adja meg a beállított jelszót. Ez bejelentkezteti Önt a Postgres parancssorba, ahol kezelheti az adatbázist.

Sikeresen csatlakozott a PostgreSQL példányhoz. Most már létrehozhat egy adatbázist a Django polls alkalmazáshoz. Nevezzük így: django_polls:

Győződjön meg róla, hogy az utasítás pontosvesszővel végződik a hibák elkerülése érdekében. Ezután váltson át a django_polls adatbázisra a következő paranccsal:

Ezután hozzon létre egy kifejezetten ehhez a projekthez tartozó adatbázis-felhasználót. Nevezzük a felhasználót így: django_user:

Válasszon egy biztonságos jelszót a felhasználónak. Ha kész, módosítanunk kell a most létrehozott felhasználó kapcsolati paramétereit. Ez segít felgyorsítani az adatbázis-műveleteket azáltal, hogy biztosítja, hogy a helyes értékek ne legyenek lekérdezve és beállítva minden egyes kapcsolat létrehozásakor.

Állítsa be a Django által elvárt alapértelmezett kódolást UTF-8-ra:

Ezután állítsa az alapértelmezett tranzakció-elszigetelési sémát „ read committed” értékre, ami blokkolja a nem véglegesített tranzakciókból történő olvasást:

Állítsa be az időzónát. Hogy az útmutató univerzális maradjon, az UTC:

Végül adjon adminisztrátori jogosultságokat az adatbázishoz az új felhasználónak:

Lépjen ki a PostgreSQL parancssorból, ha készen áll:

Ez minden ehhez a lépéshez. Miután megfelelően konfigurálta a Django alkalmazást, képesnek kell lennie az adatbázis kezelésére.

3. lépés: Az alkalmazás letöltése egy Git tárolóból és a függőségek meghatározása

Ebben a lépésben klónozni fogjuk a Django-polls alkalmazás tárolóját. Ez a tároló tartalmazza a kódot a Django első Django alkalmazás megírásáról szóló útmutatójához.

Jelentkezzen be a Dockert futtató Ubuntu szerverre, hozzon létre egy django_project nevű könyvtárat, és lépjen be oda:

Ezután klónozza a tárolót a könyvtárba a következő paranccsal:

Lépjen be a könyvtárba, és listázza a tartalmát:

Listázza a könyvtár tartalmát:

Building a Django and Gunicorn Application with Docker on Ubuntu 2

Vegye figyelembe a következő elemeket:

  • manage.py: ez a fájl a belépési pont a parancssori eszközhöz, amelyet a Django biztosít az alkalmazás kezeléséhez.

  • mysite: egy könyvtár a Django projekt hatókörével és kódbeállításaival.

  • polls: egy könyvtár, amely a polls alkalmazás kódját tartalmazza.

  • templates: egyedi sablonfájlokat tartalmaz az adminisztrációs oldalakhoz.

Ha többet szeretne megtudni arról, hogyan hoztuk létre valójában a projektet, kérjük, tekintse meg az Első Django alkalmazás megírása című részt a hivatalos dokumentációban. A django-polls könyvtárban szeretnénk a Python függőségeinket egy szöveges fájlban definiálni. A neve requirements.txt. Nyissa meg a fájlt a preferált szerkesztőjével:

Illessze be a következő sorokat a fájlba a függőségek deklarálásához:

Ebben a fájlban határoztuk meg a Python függőségeket a pontos verzióikkal, amelyeket az alkalmazás felépítésekor telepíteni kell. Ezek közül néhány: Django, django-storages az objektumtároló vödrökkel való interakcióhoz, a psycopg2 adapter a PostgreSQL-hez, a gunicorn WSGI szerver és egyéb további függőségek. Mentse el és zárja be a fájlt, ha végzett.

4. lépés: Környezeti változók konfigurálása egy Django alkalmazáshoz

A twelve-factor app módszertan azt javasolja, hogy a hardkódolt konfigurációkat emelje ki az alkalmazás kódjából. Ezzel szabadságot kap arra, hogy futásidőben módosítsa az alkalmazás viselkedését a környezeti változók megváltoztatásával, anélkül, hogy hozzáérne a kódhoz. A Docker működik ezzel a beállítással, így módosítani fogjuk a beállítási fájlt, hogy környezeti változókkal működjön. Kubernetes szintén működik ezzel a konfigurációs beállítással. Egy másik útmutatót is meg fogunk osztani a Kubernetes segítségével történő telepítésről a CloudSigma blogon.

A settings.py a Django projekt fő beállítási fájlja. Ez egy Python modul, amely natív adatstruktúrákat használ az alkalmazás konfigurálásához. A mi alkalmazásunk esetében a fájl a következő helyen található: django-polls/mysite/settings.py. A legtöbb értéke hardkódolt. Ez megköveteli, hogy módosítsa a konfigurációs fájlt a kódbázisban, ha megváltoztatja az alkalmazás viselkedését. Ezen változtatni szeretnénk. Szerencsére a Python kínálja a getenv függvényt az os modulban. Ezzel beállíthatjuk a Django-t, hogy a konfigurációs paramétereket a helyi környezeti változókból olvassa be helyette.

Folytassuk a django-polls/mysite/settings.py fájl módosításával, hogy lecseréljük a változók hardkódolt értékeit. Lehetséges, hogy futásidőben szeretnénk frissíteni azokat az os.getenv hívásával. Ez a függvény beolvassa a megadott környezeti változó névben beállított értéket. Opcionálisan megadhat egy második paramétert is, amely egy alapértelmezett érték, amelyet akkor használ, ha a környezeti változó nincs beállítva.

Íme egy példa:

A fenti sorban arra utasítjuk a Django-t, hogy a titkos kulcsot a környezeti változóból kérje le. Nem adunk meg tartalék értéket, mivel a kulcsot kívülről fogjuk biztosítani. Ha nem létezik, az alkalmazás elindítása sikertelen lesz. Miközben a titkos kulcsot kívülről biztosítjuk, azt is szeretnénk biztosítani, hogy az alkalmazás összes konténerizált másolata ugyanazt a kulcsot használja a különböző szervereken. Ez elkerüli azokat a lehetséges problémákat, amelyek akkor merülnek fel, ha az alkalmazás különböző másolatai eltérő kulcsokat használnak.

Íme egy másik példa egy alapértelmezett opcióval:

Ebben a sorban meghatározunk egy DEBUG környezeti változót, amelyet be kell olvasni. Ha azonban nincs beállítva, megadtunk egy második paramétert, amely átadásra kerül a DEBUG beállítási változónak. A DEBUG értéke False-ra van állítva, hogy biztosítsuk, hogy érzékeny információk ne kerüljenek a frontendre, ha probléma adódna az alkalmazással. Ha azonban fejlesztői módban vagyunk, azt szeretnénk, hogy True legyen, hogy láthassuk a hibaüzeneteket, megkönnyítve a hibák javítását.

Most, hogy már ismeri a környezeti változók fontosságát, nyissa meg a django_project/django-polls/settings.py fájlt a szerkesztőjében. Először importálja az os modult a következő sor hozzáadásával a settings.py fájl tetején:

Ezután keresse meg ezeket a változókat, és frissítse őket az alábbiak szerint:

A ALLOWED_HOSTS beállításban megadjuk, hogy az értéket a DJANGO_ALLOWED_HOSTS környezeti változóból kapja, és bontsa azt egy Python listává vessző ( ,) mint elválasztó karakter használatával. Ha a változó hiányzik, a ALLOWED_HOSTS értéke a következő lesz: 127.0.0.1.

Ezután görgessen végig a fájlon, és keresse meg a DATABASES szakaszt, majd konfigurálja úgy, hogy az is környezeti változókból olvasson:

Vegye figyelembe, hogy hozzáadtuk a json.loads modult. Emellett importálnia kell ezt a modult a settings.py fájl tetején:

A json.loads függvény deszerializálja a DATABASES['default']['OPTIONS'] részbe átadott JSON objektumot a DB_OPTIONS környezeti változóból. Ennek az opciónak a megadása lehetővé teszi, hogy tetszőleges adatstruktúrát adjunk át az adatbázis-konfiguráció meghatározásához. Egy adatbázis-motor az arra alkalmazható érvényes opciók készletét tartalmazza. A JSON opció rugalmasságot biztosít számunkra, hogy egy JSON objektumot kódoljunk az éppen használt adatbázis-motor megfelelő paramétereivel.

A DATABASES['default']['NAME'] határozza meg az adatbázis nevét a beállított relációs adatbázis-kezelő rendszerben. SQLite adatbázis használata esetén az adatbázisfájl elérési útját kell megadnia.

Vegye figyelembe, hogy a Python számos módszert kínál a külső környezeti változók beolvasására. Mi csak az egyiket használtuk ezek közül. Nyugodtan kutathat és használhat más módszereket is. Ebben a lépésben megtanulta, hogyan dolgozhat külső környezeti változókkal. Ez rugalmasságot biztosít a változók módosításához és a konténerekben futó alkalmazás viselkedésének megváltoztatásához. A következő lépésben megtanulja, hogyan dolgozhat objektumtárolási szolgáltatásokkal.

5. lépés: Külső objektumtárolási szolgáltatások használata

Az alkalmazás konténerizálásának egyik fő előnye, hogy hordozhatóvá teszi azt, így a forgalom növekedésekor könnyen telepíthető az alkalmazás több példánya is. Ezáltal lehetőség nyílik a skálázásra. Ez azonban felveti a statikus fájlok és eszközök verzióinak kezelését a különböző konténerek között. A felhőtechnológia fejlődésének köszönhetően ezeket a megosztott statikus elemeket kiszervezheti egy külső tárolóba. Ezután a fájlokat hálózaton keresztül elérhetővé teheti az összes futó konténer számára. Ahelyett, hogy megpróbálná szinkronizálni a fájlokat a különböző futó konténerek között, egyetlen központi helyen kezelheti őket.

A fentiekben bemutatott koncepció a felhőalapú objektumtárolási szolgáltatások, vagyis a Simple Storage Services (S3) használata. A Django rendelkezik egy úgynevezett django-storages, amely lehetővé teszi a távoli tároló-háttérrendszerekkel való munkát. Django-storages a legtöbb S3-kompatibilis objektumtároló szolgáltatással működik, mint például az FTP, SFTP, az Amazon AWS S3, a Google Cloud Storage, a Dropbox és az Azure Storage, többek között. Ebben az útmutatóban a MinIO szolgáltatást fogjuk használni. Nyugodtan használjon bármilyen más S3-kompatibilis objektumtároló szolgáltatást. MinIO nagy teljesítményű, S3-kompatibilis objektumtárolást kínál. A MinIO segítségével S3-kompatibilis adatinfrastruktúrát építhet fel bármely felhőben.

Megmutatjuk, hogyan állíthat be MinIO tárolási szolgáltatást a CloudSigma platformon. Kérjük, kövesse az alábbi lépéseket:

  • Kezdje azzal, hogy létrehoz egy fiókot a CloudSigma-n. Ha bármilyen problémába ütközik a MinIO tároló létrehozása során, kérjük, lépjen kapcsolatba a CloudSigma’s free 24/7 live chat support, és ők segíteni fognak Önnek.

  • Adja meg a számlázási adatait.

  • Ezután igényelje a nyilvánosan elérhető bucketet innen: https://blog.cloudsigma.com/xxxx. Kapcsolatba kell lépnie az élő chat ügyfélszolgálattal, hogy megkapja a fiók hozzáférési adatait.

  • Miután a MinIO objektumtároló környezete létrejött, megkapja a hozzáférési adatokat és a hozzáféréshez szükséges egyéb utasításokat. A hitelesítő adatoknak tartalmazniuk kell a MINI_ACCESS_KEY, MINIO_SECRET_KEY és MINIO_URL kulcsokat. Ezeket a kulcsokat fogja használni az alábbi utasításokban.

Végezzünk még néhány módosítást a mysite/settings.py fájlon, amelyet az előző lépésben módosítottunk. A fájlban adja hozzá a storages alkalmazást a Django INSTALLED_APPS listájához:

INSTALLED_APPS

A storages alkalmazás a django-storages segítségével van telepítve, ahogy az a requirements.txt fájlban meg van határozva. Görgessen a fájl aljára, és cserélje ki a STATIC_URL változót a következő kódrészlettel:

Vegye figyelembe, hogy néhány konfigurációs változó be van égetve (hard-coded):

  • STATICFILES_STORAGE: meghatározza azt a tároló-háttérrendszert, amelyet a Django a statikus fájlok kezelésére fog használni. Útmutatónkban MinIO tárolót használunk, de bármilyen S3-kompatibilis háttérrendszert használhat, a Django Storages dokumentációjában leírtak szerint.

  • AWS_S3_OBJECT_PARAMETERS: meghatározza a cache-control fejléceket.

  • AWS_LOCATION: ezt arra használjuk, hogy beállítsunk egy könyvtárat a tároló bucketen belül, ahol az összes statikus fájl tárolásra kerül. Nyugodtan választhat más nevet is.

  • AWS_DEFAULT_ACL: beállítja a statikus fájlok hozzáférés-vezérlési listáját (ACL). Ha az értéket ‘ public-Read’ értékre állítja, a fájlok minden nyilvános felhasználó számára elérhetővé válnak.

  • STATIC_URL: A Django az ebben a változóban beállított bázis URL-t használja a statikus fájlok URL-jeinek generálásához. A bázis URL ebben az esetben a végpont URL-jének és a statikus fájlok alkönyvtárának kombinálásából származik.

  • STATIC_ROOT: meghatározza, hogy hova kell helyileg összegyűjteni a statikus fájlokat, mielőtt átmásolná őket a távoli objektumtárolóba.

Néhány kívülről definiált környezeti változóval is rendelkezünk a rugalmasság és a hordozhatóság fenntartása érdekében:

  • AWS_STORAGE_BUCKET_NAME: meghatározza annak a tároló gyűjtőnek (bucket) a nevét, amelybe a Django feltölti az eszközöket.

  • AWS_S3_ENDPOINT_URL: meghatározza az objektumtároló szolgáltatás eléréséhez használt végpont URL-t. Ez lesz a MinIO szolgáltatást kiszolgáló szerverhez rendelt URL.

Mentse és zárja be a fájlt, ha végzett a szerkesztéssel.

Miután elvégezte ezeket a beállításokat, és telepítette a deklarált Python függőségeket, bármikor futtathatja a Django manage.py collectstatic parancsot a projekt statikus fájljainak összegyűjtéséhez és a távoli objektumtároló háttérrendszerbe történő feltöltéséhez:

Azonban még nem állítottuk be az env fájlt a konfigurációkkal, így ez valószínűleg sikertelen lesz.

A parancs futtatásakor a méretüktől és az internetsebességétől függően eltarthat egy ideig, amíg az eszközök átmásolódnak a MinIO Cloud Storage-ba.

Ennyi volt ez a lépés. Lássuk, hogyan kezelhetjük a Django naplók Docker Engine-be történő küldését, hogy a következő lépésben megtekinthesse őket a docker logs paranccsal.

6. lépés: A naplózás beállítása egy Django alkalmazásban

Debug módban, amikor a DEBUG opció értéke True, a Django a standard kimenetre és a standard hibacsatornára naplózza az információkat. A naplóinformációk általában azon a terminálon jelennek meg, amelyről a fejlesztői HTTP-szervert elindította.

Éles környezetben valószínűleg más HTTP-szervert használ, és a DEBUG opció értéke False. Ebben az esetben a Django más naplózási módszert fog használni. A Django a ERROR vagy CRITICAL prioritású naplókat az Ön által meghatározott adminisztrátori e-mail fiókba küldi. Ez sok helyzetben kiválóan működik.

Konténerizált és Kubernetes környezetekben erősen ajánlott a standard kimenetre és a standard hibacsatornára történő naplózás. A naplóüzenetek a Node fájlrendszerének egyetlen könyvtárában gyűlnek össze, és könnyen elérhetők a kubectl és docker parancsokkal. A Node fájlrendszerén lévő központosított naplózási ponttal az üzemeltető csapat könnyen futtathat folyamatokat az egyes csomópontokon a naplók figyelésére és továbbítására. Ezért konfigurálnunk kell az alkalmazásunkat, hogy ebbe a standard elrendezésbe írja a naplókat.

Örömmel fogja tapasztalni, hogy a Django a Python standard könyvtár rendkívül testreszabható logging modulját használja. Ez lehetővé teszi egy olyan szótár meghatározását, amely átadásra kerül a logging.config.dictConfig metódusnak a kívánt kimenetek és formázás meghatározásához. Itt egy remek cikk a Django Logging, The Right Way témában, amely segíthet elsajátítani a Django naplózási technikáit.

Nyissa meg a django-polls/mysite/settings.py  fájlt a szerkesztőjében. Adja hozzá a Python logging.config könyvtár importálását a fájl tetején:

Az eddig hozzáadott importálásokkal az importálási szekciónak a settings.py fájlban így kell kinéznie:

Building a Django and Gunicorn Application with Docker on Ubuntu 3

A logging.config könyvtár egy új naplózási konfigurációt tartalmazó szótárat fogad a dictConfig függvényen keresztül, hogy felülírja a Django alapértelmezett naplózási viselkedését.

Görgessen a fájl aljára, és adja hozzá a következő naplózási konfigurációs kódrészletet:

LOGGING_CONFIG értéke None-ra van állítva, hogy letiltsuk/töröljük a Django által meghatározott alapértelmezett naplózási konfigurációkat. LOGLEVEL értékét a DJANGO_LOGLEVEL környezeti változó határozza meg. Ha azonban ez nem létezik, akkor azt szeretnénk, hogy az értéke ‘ info’.

A logging.config modul, amelyet a tetején importáltunk, egy dictConfig függvényt biztosít, amely egy új konfigurációs szótár beállítására szolgál. A szótár a szövegformázást a formatters kulcs segítségével határozza meg. A kimenet a handlers kulccsal van beállítva, és végül a loggers kulcs határozza meg, hogy melyik üzenet melyik kezelőhöz (handler) kerüljön.

Miután meghatározta ezeket a beállításokat, a Docker a naplókat a docker logs paranccsal teszi elérhetővé. Hasonlóképpen, egy másik, Kubernetes-ről szóló oktatóanyagunkban a naplókat a kubectl logs paranccsal tekintheti meg. Most pedig kezdjük el a konténerizációs folyamatot a következő lépésben.

7. lépés: Az alkalmazás Dockerfile-jának meghatározása

Ebben a lépésben meghatározzuk azt a konfigurációt, amellyel elindítható a konténerkép (container image), amely a Gunicorn WSGI szerver által kiszolgált Django alkalmazást fogja futtatni. Meghatározzuk a futtatókörnyezetet a konténerkép felépítéséhez, telepítjük az alkalmazást és annak függőségeit, valamint elvégzünk néhány végső konfigurációt.

  • A Django alkalmazás szülőképe (parent image)

A konténer alapjául szolgáló báziskép kiválasztása a legelső döntés, amelyet a konténeres telepítések során meg kell hoznia. Természetesen lehetősége van arra is, hogy a konténerképeket a SCRATCH-ből, azaz egy üres fájlrendszerből építse fel, vagy egy már meglévő konténerképre alapozza. Mivel nem akarjuk újra feltalálni a spanyolviaszt, a képünket egy bázisképből fogjuk felépíteni. Számos nyílt forráskódú konténerkép érhető el a Docker hivatalos konténerkép-tárhelyén. Hacsak nem a semmiből építi fel a képét, erősen ajánlott a Docker hivatalos hubjáról származó képet használni. Ez azért van, mert a Docker ellenőrzi, hogy a képek követik-e a legjobb gyakorlatokat, és biztosítja a rendszeres frissítéseket és biztonsági javításokat.

Mivel a Django egy Python keretrendszer, ki fogjuk használni egy olyan, szabványos Python-környezettel rendelkező kép előnyeit, amelyben a szükséges eszközök és könyvtárak már telepítve vannak. A Docker hubon található Python-képek hivatalos oldalán, különböző Python-verziókhoz találhat Python-alapú képeket.

A különböző Docker-alapú oktatóanyagainkból észreveheti, hogy mi Alpine Linux alapú képeket használunk. Az Alpine Linux robusztus, de karcsú operációs rendszer környezetet biztosít a konténerizált alkalmazások futtatásához. Bár a fájlrendszere kicsi, bővíthető, és egy teljes csomagkezelő rendszerrel rendelkezik, amely lehetőséget nyújt további funkciók hozzáadására.

Amikor bázisképet választ a Docker hubon, észreveheti, hogy minden képhez több címke is elérhető. A Python esetében a 3-alpine címke a legújabb Alpine verzió legfrissebb Python 3-as verziójú képére mutat. Ez azt jelenti, hogy ha a projektje egy régebbi képverzióval működik, akkor az meghibásodhat, amikor a Docker-kép karbantartói frissítést hajtanak végre. Az ilyen forgatókönyvek elkerülése érdekében a jövőben mindig ajánlott a legspecifikusabb címkéket választani a használni kívánt képhez.

Ebben az oktatóanyagban az 3.8.12-alpine3.15 képet alapként a Django alkalmazásunkhoz. Ez a konkrét tag a Dockerfile fájlban lesz megadva a FROM utasítás használatával. A Dockerfile a fő projektkönyvtárban lesz: django_project.

Kezdje azzal, hogy kilép a Django-polls könyvtárból vissza a django_project könyvtárba:

Ha már a könyvtárban van, nyissa meg a kedvenc szerkesztőjével a következő nevű fájlt: Dockerfile :

Ezután illessze be a következő sort a kép alapjának beállításához:

A FROM  kulcsszó határozza meg az egyedi Docker-kép kiindulópontját. Ennek meghatározása után folytathatjuk az utasítások hozzáadását az alkalmazások beállításához. Ezek az utasítások telepítik a szükséges függőségeket, átmásolják az alkalmazásfájlokat, és beállítják a futtatókörnyezetet.

Adja hozzá a következő kódrészletet a Dockerfile-hoz:

Ebben a kódrészletben arra utasítjuk a Dockert, hogy másolja át a requirements.txt  fájlt a /app/requirements.txt helyre, hogy az alkalmazás függőségei elérhetőek legyenek a kép fájlrendszerében. A követelmények tartalmazzák az alkalmazás futtatásához szükséges összes Python-csomagot. A függőségek másolása történik először, hogy a Docker gyorsítótárazni tudja a képréteget. Ez azért van, mert a Docker a Dockerfile minden lépését gyorsítótárazza. A kép első felépítése általában hosszabb ideig tart. A Docker letölti a függőségeket, majd gyorsítótárazza azokat. Ha a requirements.txt fájl nem változik, a Docker a gyorsítótárból fog építkezni, így a későbbi buildelések gyorsabbak lesznek.

A következő lépés tartalmazza a RUN utasítást, amely végrehajtja a Linux-parancsok listáját, a Linux && operátorral összeláncolva. A parancsok a következőket teszik:

  • Az Alpine apk csomagkezelő eszközének használata a PostgreSQL fejlesztői fájlok és az alapvető buildelési függőségek telepítéséhez.

  • Python virtuális környezet létrehozása.

  • A Python függőségek telepítése a requirements.txt fájlban meghatározottak szerint, a pip.

  • használatával.

  • A már szükségtelen buildelési függőségek eltávolítása.

A parancsok láncolásának oka a RUN lépésben a képrétegek számának csökkentése. A Docker minden alkalommal új képréteget hoz létre a meglévő fájlrendszer tetején, amikor a ADD, COPY, vagy RUN utasítás a Dockerfile-ban. A parancsok tömörítése, ahol lehetséges, minimalizálja a létrehozott képrétegek számát.

A képrétegekhez hozzáadott elemeket egy későbbi rétegben nem lehet eltávolítani. A nem kívánt elemek törlésére vonatkozó utasításokat még azelőtt kell deklarálnia, hogy a következő utasításra lépne. Ez a kép méretének csökkentése érdekében szükséges. Észreveheti, hogy hozzáadtuk a apk del parancsot a RUN parancs végén. Ez azért történt, hogy eltávolítsuk a build függőségeket, miután felhasználtuk őket az alkalmazás csomagjainak felépítéséhez.

Ezután van egy másik ADD utasításunk, amellyel az alkalmazás kódját a /app könyvtárba másoljuk. Ezután a WORKDIR utasítást használjuk a kép munkakönyvtárának beállítására a /app könyvtárra, amely most már tartalmazza az alkalmazás kódját.

Ezután következnek az ENV utasítások, amelyekkel két olyan környezeti változót állítunk be, amelyeket a kép elérhetővé tesz a futó konténerek számára. Először a VIRTUAL_ENV változót a /env értékre állítjuk. Másodszor, a PATH változót úgy állítjuk be, hogy tartalmazza az /env/bin könyvtárat. Ebben a két sorban az /env/bin/activate szkriptet olvassuk be, amellyel aktiváljuk a virtuális környezetet Linux környezetben. További információkat olvashat a Python virtuális környezetekkel való munkáról más operációs rendszereken oldalon. Az utolsó utasítás az EXPOSE parancs, amely beállítja azt a portot, 8000 amelyen a konténer futás közben figyelni fog.

Mostanra a Dockerfile-ja már majdnem kész, eltekintve attól az alapértelmezett parancstól, amely a konténerek indításakor fut le. Definiáljuk ezt a következő szakaszban.

  • Az alapértelmezett Docker kép-parancs megértése

Egy Docker konténer indításakor megadhat egy végrehajtandó parancsot. Ha azonban nem ad meg parancsot, a Docker kép alapértelmezett parancsa határozza meg, hogy mi történjen a konténer indulásakor. Az ENTRYPOINT vagy CMD utasításokat külön-külön vagy együtt használjuk az alapértelmezett parancs meghatározására a Dockerfile-on belül.

Ha mind az ENTRYPOINT mind a CMD utasítást definiálja, az ENTRYPOINT utasításban határozza meg a konténer által futtatandó végrehajtható fájlt. A CMD utasításban pedig adja meg a végrehajtható parancs alapértelmezett argumentumlistáját. Az alapértelmezett argumentumlistát felülírhatja alternatív argumentumok hozzáfűzésével a parancssorban a konténer indításakor, a következő formátumban:

Ez a formátum megakadályozza, hogy a fejlesztők könnyen felülírják az ENTRYPOINT parancsot. Az ENTRYPOINT parancs úgy van meghatározva, hogy meghívjon egy szkriptet, amely beállítja a környezetet, és különböző műveleteket hajt végre a megadott argumentumlista alapján.

Az ENTRYPOINT utasítást önmagában is használhatja a konténer végrehajtható fájljának konfigurálására. Ez a formátum azonban nem teszi lehetővé alapértelmezett argumentumlista meghatározását. Argumentumokat a konténer futtatásakor adhat meg a docker run paranccsal.

Ha csak a CMD  utasítást választja, a Docker ezt alapértelmezett parancsként és argumentumlistaként értelmezi, amelyet futás közben felülírhat. További információt talál a hivatalos Dockerfile referencia-dokumentációban.

Lássuk, hogyan alkalmazhatjuk az alapértelmezett parancsokról tanult információkat a konténerpéldánkra. Alapértelmezés szerint a gunicorn szerverrel szeretnénk kiszolgálni az alkalmazást. Bár a gunicorn szervernek átadott argumentumlistának nem kell futás közben konfigurálhatónak lennie, szeretnénk megőrizni a rugalmasságot más parancsok futtatására olyan célokra, mint a hibakeresés vagy a konfigurációk kezelése (adatbázis inicializálása, statikus elemek gyűjtése stb.). Amint látható, a leginkább az szolgálja az érdekeinket, ha a CMD utasítást használjuk egy alapértelmezett parancs meghatározására, amely lehetővé teszi számunkra, hogy szükség esetén felülírjuk azt.

Íme néhány szintaxis, amelyet a CMD parancs meghatározásához használhat:

  • CMD ["command", "argument 1", "argument 2", . . . ,"argument n"]: Az exec formátum (ajánlott formátum) egy parancsot és egy argumentumlistát fogad el. A parancsot közvetlenül hajtja végre, shell-feldolgozás nélkül.
  • CMD command "argument 1" "argument 2" . . . "argumentum n": A shell formátum egy parancsot és az argumentumok listáját határozza meg. A parancsok listáját átadja a shellnek feldolgozásra. Ez hasznos lehet, ha környezeti változókat szeretne behelyettesíteni egy parancsba, azonban nem teljesen kiszámítható.
  • CMD ["argumentum 1", "argumentum 2", . . . ,"argumentum n"]: Az argumentumlista formátum, ez csak az alapértelmezett argumentumlistát határozza meg, és együttesen használatos egy ENTRYPOINT utasítással.

Az exec formátumot fogjuk használni a végső utasításunk meghatározásához a Dockerfile-ban. Adja hozzá a következő sort a Dockerfile:

Most már elmentheti és bezárhatja a Dockerfile.

Amikor konténereket indít el ebből a képfájlból, azok a gunicorn parancsot a localhost 8000 porthoz kötve futtatják, 3 workerrel, és meghívják a application függvényt a wsgi.py fájlban, amely a mysite könyvtárban található. Dönthet úgy is, hogy futásidőben egy másik parancsot ad meg az alapértelmezett parancs felülbírálására, és a gunicorn helyett egy másik folyamatot hajt végre. Ha többet szeretne megtudni a következőről: Gunicorn workers.

A Dockerfile most már készen áll, és használhatja a docker build parancsot az alkalmazás képfájljának felépítéséhez. Használhatja a docker run parancsot a konténer elindításához a helyi fejlesztői gépén.

  • A Docker képfájl felépítése

A docker build parancs alapértelmezés szerint egy Dockerfile fájlt keres az aktuális könyvtárban a felépítési utasítások megtalálásához. Emellett elküldi a felépítési „kontextust” (context) a Docker démonnak. A build context olyan fájlok összessége, amelyeknek elérhetőnek kell lenniük a felépítési folyamat során. Alapértelmezés szerint az az aktuális könyvtár, amelyben a docker build parancsot futtatja, van beállítva felépítési kontextusként.

Miközben ugyanabban a könyvtárban tartózkodik, amely a Dockerfile-t tartalmazza, futtassa a docker build parancsot. Adjon meg egy képfájlt és egy taget a -t jelzővel (flag), és állítsa be az aktuális könyvtárat felépítési kontextusként a parancs végén lévő ( .) pont segítségével:

Ebben a parancsban a képfájlt django-polls névvel, a taget pedig v1 névvel láttuk el. Vegye figyelembe a parancs végén lévő pontot, ezt használjuk az aktuális könyvtár felépítési kontextusként való jelölésére.

Amikor a docker build befejeződik, a következőhöz hasonló kimenetet kell látnia:

Building a Django and Gunicorn Application with Docker on Ubuntu 4

A Docker képfájlja most már készen áll. Ha nem helyeztünk volna át néhány konfigurációt külső környezeti változókba, könnyen futtathatná a konténert a docker run paranccsal. Mivel azonban még nem konfiguráltuk a settings.py fájlban beállított külső környezeti változókat, a futtatás sikertelen lesz. Végezzük el ennek a véglegesítését a következő lépésben.

8. lépés: A futtatókörnyezet beállítása és az alkalmazás tesztelése

Közeledünk a bemutató végéhez. Ebben a lépésben a környezeti változókat fogjuk konfigurálni az env fájlban. Az env fájl változóinak beállításával létrehozhatjuk az adatbázis-sémát, generálhatjuk és feltölthetjük a statikus fájlokat a külső objektumtároló szolgáltatásba, és végül tesztelhetjük az alkalmazást.

A Docker számos módszert kínál, amelyekkel környezeti változókat biztosíthat a konténer számára. Esetünkben a környezeti változók listáját egy fájlon keresztül szeretnénk megadni. Ezért az --env-file módszert fogjuk használni.

A preferált szerkesztőjével hozzon létre egy env nevű fájlt a django_project könyvtárban:

Illessze be a következő változólistát:

A listában szereplő változók azok, amelyeket az előző lépésekben határozott meg:

  • DJANGO_SECRET_KEY: Generáljon egy egyedi, kiszámíthatatlan értéket, ahogy azt a Django dokumentáció magyarázza. Ezzel a paranccsal generálhat egy véletlenszerű karakterláncot, és beállíthatja azt a változóhoz:

  • DEBUG: Ezt az értéket a következőre állítottuk be: True, de éles környezetben ne felejtse el a következőre állítani: False azáltal, hogy üresen hagyja.

  • DJANGO_LOGLEVEL: ezt a következőre állítottuk be: info, nyugodtan módosítsa a kívánt szintre.

  • DJANGO_ALLOWED_HOSTS: állítsa ezt az értéket a Docker-konténereket futtató Ubuntu szerver IP-címére. Opcionálisan beállíthatja a következőre: *, ami egy helyettesítő karakter, amely minden hosztra illeszkedik fejlesztői módban.

  • DB_DATABASE: ha más adatbázisnevet használt, állítsa be itt megfelelően.

  • DB_USERNAME: állítsa be ezt az adatbázishoz választott felhasználónévre.

  • DB_PASSWORD: állítsa be ezt az adatbázishoz választott jelszóra.

  • DB_HOST: állítsa be ezt az adatbázis-példányt futtató hosztra, ahogyan azt a Első lépésben.

  • DB_PORT: állítsa be ezt az adatbázis portjára.

  • STATIC_MINIO_BUCKET_NAME: állítsa be ezt a MinIO Cloud Storage fiókjában létrehozott bucket nevére.

Mentse el és zárja be a fájlt, ha végzett a szerkesztéssel.

A környezeti konfigurációk elkészültek. Futtatnunk kell a konténert, átadva az argumentumokat az alapértelmezett CMD parancs felülírásához, és létre kell hoznunk az adatbázis-sémát a manage.py makemigrations és a manage.py migrate parancsok használatával.

Íme a parancs:

Ebben a parancsban a django-polls:v1 konténerképet futtatjuk, az env-file jelzőt használva a környezeti változó fájl átadásához. Az alapértelmezett CMD parancsot is felülírjuk a következővel: sh -c "python manage.py makemigrations && python manage.py migrate" Amikor ezt a parancsot futtatja a konténer elindításához, az létrehozza az alkalmazáskódban meghatározott adatbázis-sémát.

Sikeres futás esetén a következőhöz hasonló kimenetet kell látnia:

Building a Django and Gunicorn Application with Docker on Ubuntu 4

A kimenet azt jelzi, hogy az adatbázis-séma sikeresen létrejött.

A következő lépés egy adminisztrátori felhasználó létrehozása a Django alkalmazáshoz. Elindítjuk a konténert, és elindítunk benne egy interaktív shellt a következő paranccsal:

A parancs elindítja a konténert egy shell parancssorral, amelyet a Python shell-lel való interakcióra használhat. Hozzunk létre egy felhasználót:

Kövesse az utasításokat a felhasználónév, e-mail cím, jelszó megadásához, gépelje be újra a jelszót, majd nyomja meg az Entert a felhasználó létrehozásához. Lépjen ki a shellből, és állítsa le a konténert a CTRL+D.

Ezután újra le kell futtatnunk a konténert, felülírva az alapértelmezett parancsot a collectstatic Django paranccsal, hogy legeneráljuk az alkalmazás statikus fájljait, és feltöltsük őket a MinIO felhőtárhely-szolgáltatásába:

Amikor befejeződik, a lentiekhez hasonló kimenetet kell látnia, ami azt jelzi, hogy a konténer sikeresen csatlakozott a MinIO tárhelyszolgáltatáshoz, és feltöltötte a statikus fájlokat:

static files

A tárhely-bucketünk most így néz ki, a Django által létrehozott könyvtárakkal:

Building a Django and Gunicorn Application with Docker on Ubuntu 5

Végül most már futtathatjuk az alkalmazást a következő paranccsal:

Íme a kimenet:

output

Amikor végrehajtja a fenti parancsot, az futtatja az alapértelmezett CMD parancsot a képfájlban, és elérhetővé teszi a portot 8000 a meghatározottak szerint. Most az Ubuntu a porton 80 hozzárendelésre kerül a 8000 porthoz a django-polls:v1 konténerben.

Most már tesztelhetjük az alkalmazást a böngészőben. Nyissa meg a szervere nyilvános IP-címét a böngészőben: http://your_server_public_ip.

Egy 404-es Oldal nem található hibaüzenetre számítson, mivel a Django Tutorial alapján nem határoztunk meg útvonalat a / útvonalhoz:

page not found

A DEBUG változó értéke True, ezért látjuk ezt a hibaoldalt rengeteg fontos információval. Távolítsuk el a DEBUG változót. Először le kell állítania a futó konténert a CTRL+C billentyűkombinációval. Ezután nyissa meg a env fájlt:

Ezután keresse meg a DEBUG változót, és törölje az értékét, vagy hagyja üresen. Azért hagyjuk üresen, mert a getenv függvény a False értéket karakterláncként értelmezi, így igaz (true) értéket ad vissza:

Mentse el a fájlt, és futtassa újra a konténert a következő paranccsal:

Ha megnyitja ezt: http://your_server_public_ip a böngészőjében, az alapértelmezett 404-es oldalt kell látnia:

not found

Láthatta, hogyan módosíthatja a Django alkalmazás futásidejű viselkedését környezeti változók segítségével, a forráskód módosítása nélkül.

Navigáljon ide: http://your_server_public_ip/polls a Polls (Szavazások) kezdőlapjának megtekintéséhez:

Building a Django and Gunicorn Application with Docker on Ubuntu 6

Még nincsenek szavazások, mivel épp most telepítettük az alkalmazást.

Navigáljon az adminisztrációs felületre: http://your_server_public_ip/admin az adminisztrátori bejelentkezési ablak megtekintéséhez:

polls administration

Adja meg a createsuperuser paranccsal beállított hitelesítési adatokat a bejelentkezéshez. Ekkor az adminisztrációs oldal felületére kell jutnia:

site administration

Vegye figyelembe, hogy az összes statikus fájlt a beállított külső tárhelyszolgáltatás szolgálja ki. Kattintson a jobb gombbal a böngészőablakban, és válassza az Oldalforrás megtekintése:

external storage

Hozzáadhat néhány kérdést és választ, és tesztelheti az alkalmazás általános működését:

questions and choices

Menjen vissza a Polls főoldalára http://your_server_public_ip/polls és próbáljon meg szavazni a kérdésre:

django framework

Miután letesztelte és megbizonyosodott arról, hogy minden a várt módon működik, leállíthatja a konténert.

Összegzés

Sikeresen konfigurált egy Django webalkalmazást, hogy megfelelően működjön konténeralapú környezetben. Ez magában foglalta az alkalmazás felkészítését a külső környezeti változókkal való működésre, a felhőalapú tárhelyszolgáltatás beállítását a statikus fájlokhoz, valamint egy Dockerfile létrehozását a konténerképfájlhoz. Az alkalmazás dockerizálása érdekében végrehajtott módosításokat megtekintheti a django-polls-docker ágán a django-polls GitHub-tárhelynek.

Innentől kezdve a lehetőségeknek csak a képzelet szab határt. Beállíthat egy Nginx fordított proxyt a kliensek és a Gunicorn szerver közé. Hozzáadhatja a Certbotot is, hogy TLS-tanúsítványokat szerezzen az Nginx szerver biztosításához. Javasoljuk egy HTTP proxy hozzáadását a lassú kliensek pufferelésére és a Gunicorn szerver védelmére a szolgáltatásmegtagadási (DoS) támadásokkal szemben.

Bár a Dockerfile indítási parancsában 3 munkamenetet (worker) határoztunk meg, beállíthatja a kívánt számot a szerverén elérhető erőforrásoktól függően. További információt talál a hivatalos Gunicorn tervezési dokumentációban. Ha szeretné, a felépített Docker-képfájlt feltöltheti a Docker Hubra, és megpróbálhatja telepíteni több olyan környezetben, amelyre telepítve van a Docker. Ha többet szeretne megtudni, kövesse figyelemmel a Tutorials blogunkat, mivel egy következő útmutatóban bemutatjuk, hogyan teheti biztonságossá a Django alkalmazást az Nginx és a Let’s Encrypt segítségével.

Végezetül íme néhány további erőforrás, amely segít a Docker használatában:

Kellemes számítógépezést!

Shreyas Patil

Szerző · CloudSigma

Hozzászólások

Még nincsenek hozzászólások. Legyen Ön az első.