Django is een high-level open-source Python webframework dat u kan helpen uw Python-applicatie snel te bouwen. Het stimuleert snelle ontwikkeling en een schoon, pragmatisch ontwerp door het model-template-views architectuurpatroon te volgen. Standaard wordt het framework geleverd met de benodigde moderne applicatiecomponenten zoals gebruikersauthenticatie, caching-framework, object-relationele mapper, URL-dispatcher, templatesysteem, en een aanpasbare administratieve interface.
Gunicorn ‘Green Unicorn’ is een Python WSGI HTTP-server voor UNIX-systemen. De Gunicorn-server is compatibel met verschillende webframeworks, biedt geweldige prestaties en is zuinig met serverbronnen. Docker is een open-source containerplatform dat al een tijdje bestaat en applicatieontwikkeling snel, efficiënt en voorspelbaar maakt.
In deze handleiding zult u vaardigheden opdoen in het ontwikkelen en implementeren van schaalbare, gecontaineriseerde Django-webapps. We maken gebruik van een Django Polls-app die is gemaakt door de introductiehandleidingen voor het starten met Django te volgen. Op het moment van schrijven van de handleiding hebben we deze gebaseerd op Django 3.2 ondersteund door Python 3.6 of nieuwer. We zullen de app implementeren als een container met Docker en deze serveren met de Gunicorn-server. Natuurlijk moet u, voordat u de Django-app in een container implementeert, enkele wijzigingen aanbrengen in de projectcode om zaken als loggen naar standaard outputstromen en het werken met omgevingsvariabelen af te handelen. Statische bestanden zoals CSS- en JavaScript-afbeeldingen kunnen worden overgedragen naar objectopslagdiensten om eenvoudig beheer van de bestanden vanaf één locatie in een multi-containeromgeving mogelijk te maken.
We laten u zien hoe u deze wijzigingen kunt implementeren op basis van de goed omschreven twelve-factor-methodologie voor het bouwen van schaalbare webapplicaties. Zodra u de wijzigingen hebt voltooid, bouwt u een Docker-image van de applicatie en implementeert u de gecontaineriseerde app met Docker. We raden u aan de stappen in de handleiding te volgen om een volledig begrip van de handleiding te krijgen.
Vereisten
Aangezien dit een praktische handleiding is, raden we u aan de onderstaande configuratie te gebruiken om de stappen te kunnen volgen:
-
Een Ubuntu 20.04-server. U kunt stappen 1 tot en met 4 van deze stapsgewijze handleiding volgen om u te helpen uw Ubuntu-server in te richten op CloudSigma.
-
Zorg ervoor dat u een gebruiker met sudo-privileges toevoegt op beide nodes die we zullen gebruiken om de opdrachten uit te voeren zoals beschreven in de bovenstaande handleiding.
-
Installeer Docker op de server. U kunt stappen 1, 2 en 3 van onze handleiding over het installeren en bedienen van Docker volgen. Vergeet niet de hierboven aangemaakte sudo-gebruiker toe te voegen aan de Docker-groep.
-
Een compatibele objectopslagruimte. Django ondersteunt verschillende opslagdiensten zoals vermeld in de django-storages-documentatie. U kunt er een kiezen die uw voorkeur heeft en de documentatie volgen om deze in te richten. Voor deze handleiding gebruiken we MinIO wat een S3-compatibele cloudopslagdienst is.
-
Een SQL-database-instantie. Django ondersteunt verschillende SQL-databases die u vrij kunt kiezen. Voor deze handleiding gebruiken we PostgreSQL. De PostgreSQL-database wordt niet in een container geïmplementeerd. We richten een aparte Ubuntu-server in om de PostgreSQL-instantie te hosten om ervoor te zorgen dat we onze multi-containerconfiguratie en gegevenspersistentie bereiken. U kunt een andere Ubuntu 20.04-instantie aanmaken en deze handleiding volgen om een PostgreSQL-database-instantie op te zetten op Ubuntu. Vergeet niet een rol in de PostgreSQL-database toe te voegen voor uw sudo-gebruiker, zoals uitgelegd in stappen 2 en 3. Met deze rol kunt u verbinding maken met de database vanaf de andere servers die uw containers hosten.
Volgens deze vereisten moet u twee Ubuntu-serverinstanties hebben. De ene instantie draait uw Docker-container en de andere instantie draait de PostgreSQL-instantie. Laten we beginnen!
Stap 1: De PostgreSQL-database-instantie configureren
In deze sectie zullen we de Postgres-configuraties aanpassen op de Ubuntu-server waarop de Postgres-instantie draait. Dit maakt verbindingen vanaf een extern IP-adres mogelijk. Zodra de verbinding tot stand is gebracht, kunnen we een database en een gebruikersrol aanmaken, specifiek voor de Django Polls-app die we implementeren.
Ten eerste, als u uw omgeving had ingericht volgens de Vereisten, zou u een rol in uw PostgreSQL-database moeten hebben voor uw sudo-gebruiker. Vervolgens moeten we een wachtwoord instellen voor deze rol. Terwijl u op de server bent waarop PostgreSQL draait, logt u in op de Postgres-terminal met het volgende commando:
|
1 |
sudo -u postgres psql |
Zodra u zich in de Postgres-terminal bevindt, voert u het \password-commando uit om het wachtwoord van een gebruiker te wijzigen. De syntaxis voor het \password-commando is \password <username>. In ons geval is het commando:
|
1 |
\password cloudsigma |
Voer het wachtwoord in en bevestig het. Sla dit wachtwoord op een veilige plaats op, want u zult het later gebruiken om te verifiëren vanaf de andere Ubuntu-server. Typ daarna exit en druk op Enter om de Postgres-terminal te verlaten.
Als u de firewall (ufw) had ingeschakeld op de PostgreSQL-serverinstantie, moet u verkeer toestaan naar de standaard Postgres-poort 5432. U kunt het verkeer beperken tot alleen afkomstig van een specifiek IP-adres van uw andere Ubuntu-server die de Docker-container zal draaien. Voer het volgende commando uit om de ufw-regel toe te voegen, waarbij u uw IP-adres vervangt waar dit is gemarkeerd:
|
1 |
sudo ufw allow from ubuntu_server_ip_address to any port 5432 |
Dit zorgt ervoor dat alleen uw server verbinding kan maken met de PostgreSQL-instantie. Hoewel dat verkeer door de firewall toestaat, moet u ook de PostgreSQL-configuratiebestanden aanpassen om verbinding vanaf het externe IP-adres toe te staan. Standaard staat de configuratie alleen verbinding vanaf localhost toe. De configuratiebestanden voor PostgreSQL bevinden zich in de map /etc/postgresql/12/main-map. 12 is in dit geval de versie van PostgreSQL die we voor deze handleiding hebben geïnstalleerd. Mogelijk hebt u een andere versie geïnstalleerd. Daarom kunt u naar de map gaan/etc/postgresql/ en de inhoud weergeven om het versienummer te vinden van de PostgreSQL die u hebt geïnstalleerd.
Gebruik nano om het configuratiebestand te bewerken:
|
1 |
sudo nano /etc/postgresql/12/main/postgresql.conf |
Zoek de onderstaande regel, verwijder het commentaarteken (#) en stel deze in om verbindingen van alle IP's toe te staan:
|
1 |
listen_addresses = '*' |
Sla het bestand op en sluit het. Vervolgens moet u ook het -bestandpg_hba.conf bewerken, dit bevindt zich in dezelfde map als postgresql.conf. Het pg_hba.conf-bestand stelt u in staat om te definiëren vanaf welke computers u verbinding kunt maken met de PostgreSQL-instantie, evenals de authenticatiemethode. Open het bestand met nano:
|
1 |
sudo nano /etc/postgresql/12/main/pg_hba.conf |
Lees de opmerkingen in dit bestand om de trefwoorden te begrijpen. De sectie die we zoeken is deze:

Onze focus ligt op de tweede regel, u wilt dat deze er na het weghalen van het commentaarteken uitziet als de onderstaande regel:
|
1 |
host all all your_ubuntu_server_ip/24 md5 |
Vervang het gemarkeerde deel door het IP-adres van uw Ubuntu-server om deze verbinding te laten maken met de PostgreSQL-instantie. Sla het bestand op zodra u klaar bent. Start de PostgreSQL-database opnieuw op om de wijzigingen door te voeren:
|
1 |
sudo service postgresql restart |
Onze andere Ubuntu-server met het opgegeven IP-adres zou nu verbinding moeten kunnen maken met de Postgres-instantie.
Stap 2: Verbinding maken met de PostgreSQL-serverinstantie en een database en gebruiker aanmaken
In deze stap proberen we ervoor te zorgen dat de Ubuntu-instantie die onze Docker-container host, verbinding kan maken met de andere server waarop de PostgreSQL-instantie draait. Log in op de Ubuntu-instantie met Docker en installeer het pakket postgresql-client op de Ubuntu-hostmachine (nog niet in de container).
Werk zoals gebruikelijk eerst het apt-pakket bij en installeer vervolgens het pakket met de volgende commando's:
|
1 |
sudo apt update |
|
1 |
sudo apt install postgresql-client |
Het hierboven geïnstalleerde pakket helpt u bij het maken van een database en een gebruiker voor uw applicatie. Vervolgens moeten we verbinding maken met de PostgreSQL-instantie door verbindingsparameters door te geven aan de PostgreSQL-client.
De verbindingsparameters volgen deze syntaxis:
|
1 |
psql -U username -h host -p port -d database --set=sslmode=require |
In deze opdracht is de username de gebruiker/rol die u hebt toegevoegd aan uw PostgreSQL-database. host het IP-adres van de Ubuntu-instantie waarop uw PostgreSQL-database draait. port de standaardpoort waarop Postgres luistert naar inkomende verbindingen, d.w.z. 5432. In de plaats van de database, gebruiken we de standaarddatabase genaamd postgres die bij de PostgreSQL-installatie wordt geleverd. Vervang uw waarden in de gemarkeerde delen op de juiste manier en druk op Enter. Voer desgevraagd het wachtwoord in dat u had ingesteld. Hiermee logt u in op de Postgres-prompt waar u de database kunt beheren.
U bent succesvol verbonden met de PostgreSQL-instantie. U kunt nu een database maken voor de Django polls-app. Laten we deze django_polls:
|
1 |
CREATE DATABASE django_polls; |
Zorg ervoor dat uw instructie eindigt met een puntkomma om fouten te voorkomen. Schakel vervolgens over naar de django_polls database met de opdracht:
|
1 |
\c django_polls; |
Maak vervolgens een databasegebruiker aan die specifiek is voor dit project. Laten we de gebruiker django_user:
|
1 |
CREATE USER django_user WITH PASSWORD 'password'; |
Kies een veilig wachtwoord voor uw gebruiker. Als dat is gebeurd, moeten we de verbindingsparameters wijzigen voor de gebruiker die we zojuist hebben gemaakt. Dit helpt databasebewerkingen te versnellen door ervoor te zorgen dat de juiste waarden niet telkens worden opgevraagd en ingesteld wanneer een verbinding tot stand wordt gebracht.
Stel de standaardcodering die Django verwacht in op UTF-8:
|
1 |
ALTER ROLE django_user SET client_encoding TO 'utf8'; |
Stel vervolgens het standaard transactie-isolatieschema in op “ read committed”, wat het lezen van niet-gecommitteerde transacties blokkeert:
|
1 |
ALTER ROLE django_user SET default_transaction_isolation TO 'read committed'; |
Stel uw tijdzone in. Om de tutorial universeel te houden, gebruiken we de UTC:
|
1 |
ALTER ROLE django_user SET timezone TO 'UTC'; |
Verleen ten slotte beheerdersrechten van de database aan de nieuwe gebruiker:
|
1 |
GRANT ALL PRIVILEGES ON DATABASE django_polls TO django_user; |
Verlaat de PostgreSQL-prompt wanneer u klaar bent:
|
1 |
\q |
Dat is alles voor deze stap. Zodra u uw Django-app correct configureert, zou deze uw database moeten kunnen beheren.
Stap 3: De app ophalen uit een Git-repository en afhankelijkheden definiëren
In deze stap klonen we de Django-polls app-repository. Deze repo bevat de code voor Django's de tutorial 'Je eerste Django-app schrijven'.
Log in op de Ubuntu-server waarop Docker draait, maak een map aan genaamd django_project en navigeer er naartoe:
|
1 2 |
mkdir django_project cd django_project |
Kloon vervolgens de repo in de map met de volgende opdracht:
|
1 |
git clone https://github.com/jaymoh/django-polls.git |
Navigeer naar de map en toon de inhoud:
|
1 |
cd django-polls |
Toon de inhoud van de map:
|
1 |
ls |

Let op de volgende items:
-
manage.py: dit bestand is de toegang tot het opdrachtregelprogramma dat Django biedt om uw app te beheren.
-
mysite: een map met de Django-projectomvang en code-instellingen.
-
polls: een map met de polls applicatiecode.
-
templates: bevat aangepaste sjabloonbestanden voor de beheerpagina's.
Voor meer informatie over hoe we het project daadwerkelijk hebben gemaakt, raadpleegt u Writing your first Django app in de officiële documentatie. Binnen de django-polls map, willen we onze Python-afhankelijkheden gedefinieerd hebben in een tekstbestand. We noemen het requirements.txt. Open het bestand met de editor van uw voorkeur:
|
1 |
nano requirements.txt |
Plak de volgende regels in het bestand om de afhankelijkheden te declareren:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Django==3.2.9 gunicorn==20.1.0 docutils==0.18.1 sqlparse==0.4.2 jmespath==0.10.0 psycopg2==2.9.2 python-dateutil==2.8.2 pytz==2021.3 six==1.16.0 urllib3==1.26.7 django-storages==1.12.2 minio==7.1.6 django-minio-backend==3.3.2 django-dotenv==1.4.2 boto3==1.21.38 |
In dit bestand hebben we Python-afhankelijkheden gedefinieerd met hun exacte versies die moeten worden geïnstalleerd wanneer u de app bouwt. Sommige daarvan zijn Django, django-storages voor interactie met object storage buckets, de psycopg2 adapter voor PostgreSQL, gunicorn WSGI-server en andere aanvullende afhankelijkheden. Sla het bestand op en sluit het als u klaar bent.
Stap 4: Omgevingsvariabelen configureren voor een Django-app
De twelve-factor app methodologie raadt aan om hardgecodeerde configuraties uit de codebase van uw applicatie te extraheren. Hierdoor krijgt u de vrijheid om het gedrag van de applicatie tijdens runtime te wijzigen door omgevingsvariabelen aan te passen zonder de codebase aan te raken. Docker werkt met deze opzet, dus we zullen het instellingenbestand aanpassen om met omgevingsvariabelen te werken. Kubernetes werkt ook met deze configuratie-opzet. We zullen nog een handleiding delen over het implementeren met Kubernetes op de CloudSigma blog.
Het settings.py is het belangrijkste instellingenbestand voor een Django-project. Het is een Python-module die native datastructuren gebruikt om de applicatie te configureren. Voor onze applicatie bevindt het bestand zich op de locatie django-polls/mysite/settings.py. De meeste waarden zijn hardgecodeerd. Dit vereist dat u het configuratiebestand in de codebase wijzigt als u het gedrag van de applicatie verandert. Dat willen we veranderen. Gelukkig biedt Python de getenv functie in de os module. We kunnen dit gebruiken om Django zo te configureren dat het configuratieparameters uit lokale omgevingsvariabelen leest.
Laten we doorgaan met het wijzigen van het django-polls/mysite/settings.py bestand om de hardgecodeerde waarden van de variabelen te vervangen. Mogelijk willen we deze tijdens runtime bijwerken met een aanroep naar os.getenv. Deze functie leest de waarde die is ingesteld in de opgegeven naam van de omgevingsvariabele. Optioneel kunt u een tweede parameter opgeven, wat een standaardwaarde is die wordt gebruikt als de omgevingsvariabele niet is ingesteld.
Hier is een voorbeeld:
|
1 |
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY') |
In de bovenstaande regel vertellen we Django om de geheime sleutel uit de omgevingsvariabele op te halen. We bieden geen fallback-waarde omdat we de sleutel extern zullen aanleveren. Als deze niet bestaat, mag de applicatie niet starten. Terwijl we de geheime sleutel extern aanleveren, willen we er ook voor zorgen dat al onze gecontaineriseerde kopieën van de app dezelfde sleutel gebruiken op de verschillende servers. Dit voorkomt mogelijke problemen die ontstaan wanneer de verschillende kopieën van de app verschillende sleutels gebruiken.
Hier is nog een voorbeeld met een standaardoptie:
|
1 |
DEBUG = os.getenv('DEBUG', False) |
In deze regel definiëren we een omgevingsvariabele DEBUG die moet worden gelezen. Als deze echter niet is ingesteld, hebben we een tweede parameter opgegeven die wordt doorgegeven aan de DEBUG instellingsvariabele. DEBUG is ingesteld op False om ervoor te zorgen dat er geen gevoelige informatie naar de frontend wordt gestuurd als er een probleem is met de applicatie. Als we ons echter in de ontwikkelingsmodus bevinden, willen we dat deze is ingesteld op True om ons in staat te stellen de foutinformatie te zien, zodat we fouten gemakkelijker kunnen oplossen.
Nu u het belang van de omgevingsvariabelen kent, opent u de django_project/django-polls/settings.py in uw editor. Importeer eerst de os module door deze regel toe te voegen aan de bovenkant van het settings.py bestand:
|
1 |
import os |
Zoek vervolgens deze variabelen en werk ze als volgt bij:
|
1 2 3 |
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY') DEBUG = os.getenv('DEBUG', False) ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '127.0.0.1').split(',') |
In de ALLOWED_HOSTS-instelling specificeren we dat deze de waarde moet ophalen uit de DJANGO_ALLOWED_HOSTS omgevingsvariabele, en deze moet splitsen in een Python-lijst met behulp van een komma ( ,) als scheidingsteken. Als de variabele ontbreekt, wordt ALLOWED_HOSTS ingesteld op 127.0.0.1.
Blader vervolgens door het bestand en zoek de sectie DATABASES, en configureer deze om ook uit omgevingsvariabelen te lezen:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.{}'.format( os.getenv('DB_ENGINE', 'sqlite3') ), 'NAME': os.getenv('DB_DATABASE', 'django_polls'), 'USER': os.getenv('DB_USERNAME', 'your_db_username'), 'PASSWORD': os.getenv('DB_PASSWORD', 'your_secure_default_password'), 'HOST': os.getenv('DB_HOST', '127.0.0.1'), 'PORT': os.getenv('DB_PORT', 5432), 'OPTIONS': json.loads( os.getenv('DB_OPTIONS', '{}') ), } } |
Merk op dat we de module json.loads hebben toegevoegd. Je moet ook een import van de module toevoegen bovenaan het settings.py-bestand:
|
1 |
import json |
De functie json.loads deserialiseert een JSON-object dat is doorgegeven aan de DATABASES['default']['OPTIONS'] vanuit de DB_OPTIONS omgevingsvariabele. Door deze optie op te geven, kunnen we een willekeurige datastructuur doorgeven om de databaseconfiguratie te definiëren. Een database-engine bevat een reeks geldige opties die erop van toepassing zijn. De JSON-optie geeft ons de flexibiliteit om een JSON-object te coderen met de juiste parameters voor de database-engine die we op dat moment gebruiken.
De DATABASES['default']['NAME'] specificeert de databasenaam in het relationele databasemanagementsysteem dat we hebben opgezet. In het geval van het gebruik van een SQLite-database, moet je het pad naar het databasebestand opgeven.
Merk op dat Python verschillende methoden biedt om externe omgevingsvariabelen te lezen. We hebben er slechts één van gebruikt. Het staat je vrij om andere methoden te onderzoeken en te gebruiken. In deze stap heb je geleerd hoe je met externe omgevingsvariabelen werkt. Dit geeft je de flexibiliteit om de variabelen te wijzigen en het gedrag van de app die in containers draait aan te passen. In de volgende stap leer je hoe je met objectopslagdiensten werkt.
Stap 5: Werken met externe objectopslagdiensten
Een groot voordeel van het containeriseren van je applicatie is dat deze draagbaar wordt, zodat je eenvoudig meerdere kopieën van de app kunt implementeren wanneer het verkeer toeneemt. Dit biedt ruimte voor schalen. Dit brengt echter het probleem met zich mee van het onderhouden van versies van statische bestanden en assets over verschillende containers heen. Dankzij verbeteringen in cloudtechnologie kun je deze gedeelde statische elementen verplaatsen naar externe opslag. Vervolgens kun je de bestanden via een netwerk toegankelijk maken voor al je actieve containers. In plaats van te proberen de bestanden te synchroniseren over de verschillende actieve containers, heb je één centrale plek om ze te beheren.
Het concept dat we hierboven proberen uit te leggen is het gebruik van cloud-objectopslagdiensten, of Simple Storage Services (S3). Django heeft een pakket genaamd django-storages waarmee u met externe opslagbackends kunt werken. Django-storages werken met de meeste S3-compatibele objectopslagdiensten zoals onder andere FTP, SFTP, Amazon's AWS S3, Google Cloud Storage, Dropbox en Azure Storage. In deze handleiding gebruiken we MinIO. Voel u vrij om een andere S3-compatibele objectopslagdiensten. MinIO biedt krachtige, S3-compatibele objectopslag. Met MinIO kunt u op elke cloud een S3-compatibele datainfrastructuur bouwen.
We laten u zien hoe u een MinIO-opslagdienst opzet op het CloudSigma-platform. Volg deze stappen:
-
Begin met het aanmaken van een account op CloudSigma. Als u problemen ondervindt bij het maken van de MinIO-opslag, neem dan contact op met de gratis 24/7 live chat-ondersteuning van CloudSigma, en zij zullen u helpen.
-
Voeg uw factureringsgegevens toe.
-
Vraag vervolgens hier uw openbaar toegankelijke bucket aan: https://blog.cloudsigma.com/xxxx. U moet contact opnemen met de Live Chat-ondersteuning om de inloggegevens voor uw account te verkrijgen.
-
Zodra uw MinIO-objectopslagomgeving is gemaakt, ontvangt u inloggegevens en andere instructies om toegang te krijgen. De inloggegevens moeten uw MINI_ACCESS_KEY, MINIO_SECRET_KEY, en MINIO_URL. U gebruikt deze sleutels in de onderstaande instructies.
Laten we nog wat wijzigingen aanbrengen in het bestand mysite/settings.py dat we in de vorige stap hebben gewijzigd. Voeg in het bestand de app storages toe aan de lijst met INSTALLED_APPS:

De storages app wordt geïnstalleerd via django-storages zoals gedefinieerd in requirements.txt. Scrol naar de onderkant van het bestand en vervang de variabele STATIC_URL door het volgende codefragment:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Statische bestanden (CSS, JavaScript, Afbeeldingen) # https://docs.djangoproject.com/en/3.2/howto/static-files/ DEFAULT_FILE_STORAGE = os.getenv('STATIC_DEFAULT_FILE_STORAGE', 'storages.backends.s3boto3.S3Boto3Storage') AWS_S3_ENDPOINT_URL = os.getenv('MINIO_URL') AWS_ACCESS_KEY_ID = os.getenv('MINIO_ACCESS_KEY') AWS_SECRET_ACCESS_KEY = os.getenv('MINIO_SECRET_KEY') AWS_STORAGE_BUCKET_NAME = os.getenv('STATIC_MINIO_BUCKET_NAME') AWS_S3_OBJECT_PARAMETERS = { 'CacheControl': 'max-age=86400', } AWS_LOCATION = 'static' AWS_DEFAULT_ACL = 'public-read' STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' STATIC_URL = '{}/{}/'.format(AWS_S3_ENDPOINT_URL, AWS_LOCATION) STATIC_ROOT = "static/" |
Merk op dat sommige configuratievariabelen hardcoded zijn:
-
STATICFILES_STORAGE: definieert de opslagbackend die Django zal gebruiken om statische bestanden te verwerken. In onze handleiding gebruiken we MinIO-opslag, maar u kunt elke S3-compatibele backend gebruiken, zoals uitgelegd in de Django Storages-documentatie.
-
AWS_S3_OBJECT_PARAMETERS: definieert de cache-control headers.
-
AWS_LOCATION: we gebruiken dit om een map in de opslagbucket in te stellen waarin alle statische bestanden worden opgeslagen. Het staat u vrij om een andere naam te kiezen.
-
AWS_DEFAULT_ACL: stelt de toegangscontrolelijst (ACL) in voor statische bestanden. Door de waarde in te stellen op ‘ public-Read’ worden de bestanden toegankelijk voor alle openbare gebruikers.
-
STATIC_URL: Django gebruikt de basis-URL die in deze variabele is ingesteld om URL's voor statische bestanden te genereren. De basis-URL in dit geval is afgeleid van het combineren van de endpoint-URL en de submap voor statische bestanden.
-
STATIC_ROOT: definieert waar statische bestanden lokaal moeten worden verzameld voordat ze naar de externe objectopslag worden gekopieerd.
We hebben ook enkele extern gedefinieerde omgevingsvariabelen om de flexibiliteit en portabiliteit te behouden:
-
AWS_STORAGE_BUCKET_NAME: definieert de naam van de storage-bucket waarnaar Django de assets zal uploaden.
-
AWS_S3_ENDPOINT_URL: definieert de endpoint-URL die wordt gebruikt om toegang te krijgen tot de objectopslagdienst. Dit is de URL die is gekoppeld aan de server die je MinIO-dienst host.
Sla het bestand op en sluit het wanneer je klaar bent met bewerken.
Zodra je die instellingen hebt toegepast en de gedeclareerde Python-afhankelijkheden hebt geïnstalleerd, kun je het Django-commando manage.py collectstatic op elk moment uitvoeren om de statische bestanden van je project te verzamelen en ze te uploaden naar de externe objectopslag-backend:
|
1 |
python manage.py collectstatic |
We hebben echter het env-bestand nog niet geconfigureerd, dus het zal waarschijnlijk mislukken.
Wanneer je het commando uitvoert, duurt het even om je assets naar MinIO Cloud Storage te kopiëren, afhankelijk van hun grootte en je internetsnelheid.
Dat is alles voor deze stap. Laten we kijken hoe we het doorsturen van Django-logs naar de Docker Engine kunnen aanpakken, zodat je ze kunt bekijken met het docker logs-commando in de volgende stap.
Stap 6: Logging instellen in een Django-app
In de Debug-modus, wanneer de DEBUG-optie is ingesteld op True, logt Django informatie naar de standaarduitvoer en standaardfout. De loginformatie verschijnt meestal in de terminal van waaruit je de ontwikkelings-HTTP-server hebt gestart.
In productie gebruik je waarschijnlijk een andere HTTP-server, en is de DEBUG-optie ingesteld op False. Django zal in dit geval een andere logging-methode gebruiken. Django stuurt logs met prioriteit ERROR of CRITICAL naar een door jou gedefinieerd e-mailaccount voor beheerders. Dit werkt uitstekend voor veel situaties.
In gecontaineriseerde en Kubernetes-omgevingen wordt loggen naar standaarduitvoer en standaardfout ten zeerste aanbevolen. Logberichten worden verzameld in een enkele map op het bestandssysteem van de Node en zijn eenvoudig toegankelijk met behulp van kubectl en docker-commando's. Met een gecentraliseerd logging-punt op het bestandssysteem van de Node kan het operationele team eenvoudig processen op elke node uitvoeren om logs te bekijken en door te sturen. Daarom moeten we onze applicatie configureren om logs naar deze standaardopstelling te schrijven.
Je zult blij zijn te horen dat Django gebruikmaakt van de zeer aanpasbare logging-module uit de Python-standaardbibliotheek. Hiermee kun je een dictionary definiëren die wordt doorgegeven aan logging.config.dictConfig om de gewenste uitvoer en opmaak te definiëren. Hier is een goed artikel over Django Logging, The Right Way dat je kan helpen technieken voor Django-logging onder de knie te krijgen.
Open het django-polls/mysite/settings.py -bestand in je editor. Voeg bovenaan het bestand een import toe voor de Python logging.config-bibliotheek:
|
1 |
import logging.config |
Tot nu toe, met alle imports die we hebben toegevoegd, zou je imports-sectie in settings.py er als volgt uit moeten zien:

De logging.config-bibliotheek accepteert een dictionary met nieuwe logging-configuratie via de dictConfig-functie om het standaard logging-gedrag van Django te overschrijven.
Scrol naar de onderkant van het bestand og voeg het volgende codefragment voor de logging-configuratie toe:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# Logging-configuratie # Schakel vorige configuratie uit LOGGING_CONFIG = None # Haal logniveau op uit omgeving LOGLEVEL = os.getenv('DJANGO_LOGLEVEL', 'info').upper() logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'console': { 'format': '%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(module)s %(process)d %(thread)d %(message)s', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'formatter': 'console', }, }, 'loggers': { '': { 'level': LOGLEVEL, 'handlers': ['console',], }, }, }) |
LOGGING_CONFIG is ingesteld op None om standaard loggingconfiguraties die Django definieert uit te schakelen/te wissen. LOGLEVEL wordt ingesteld door de DJANGO_LOGLEVEL omgevingsvariabele. Als deze echter niet bestaat, willen we dat deze wordt ingesteld op ‘ info’.
De logging.config module die we bovenaan hebben geïmporteerd, biedt een functie dictConfig die wordt gebruikt om een nieuw configuratiewoordenboek in te stellen. Het woordenboek definieert tekstopmaak met behulp van de formatters sleutel. De uitvoer wordt ingesteld met de handlers sleutel, en tot slot definieert de loggers sleutel welk bericht naar welke handler moet gaan.
Zodra je die instellingen hebt gedefinieerd, Docker zal de logs beschikbaar maken via het docker logs commando. Op vergelijkbare wijze kun je, in een andere handleiding die we voor Kubernetes zullen maken, de logs bekijken met het kubectl logs commando. Laten we nu beginnen met het containerisatieproces in de volgende stap.
Stap 7: De Dockerfile van de applicatie definiëren
In deze stap definiëren we de configuratie om de container-image op te starten die de Django-app zal draaien, geleverd door de Guincorn WSGI-server. We definiëren de runtime-omgeving voor het bouwen van een container-image, installeren de applicatie en de bijbehorende afhankelijkheden, en voeren enkele definitieve configuraties uit.
-
De parent-image voor een Django-app
Het bepalen van de basis-image waarop je je container baseert, is de allereerste beslissing die je neemt bij het werken met gecontaineriseerde implementaties. Natuurlijk heb je de optie om je container-images vanaf SCRATCH op te bouwen, d.w.z. een leeg bestandssysteem, of deze te baseren op een bestaande container-image. Omdat we het wiel niet opnieuw willen uitvinden, bouwen we onze image op basis van een base-image. Er zijn veel open-source container-images beschikbaar via Docker's officiële container-image repository. Tenzij je je image vanaf nul opbouwt, wordt het ten zeerste aanbevolen om een image uit de officiële hub van Docker te gebruiken. Dat komt omdat Docker de images verifieert om te controleren of ze de best practices volgen, en zorgt voor regelmatige updates en beveiligingspatches.
Aangezien Django een Python-framework is, maken we gebruik van een image met een standaard Python-omgeving waarin de tools en bibliotheken die we nodig hebben al zijn geïnstalleerd. Vanaf de officiële pagina voor Python-images op Docker Hub, kun je een op Python gebaseerde image vinden voor verschillende versies van Python.
In onze verschillende op Docker gebaseerde handleidingen, zul je merken dat we images gebruiken die gebaseerd zijn op Alpine Linux. Alpine Linux biedt een robuuste maar slanke besturingssysteemomgeving voor het draaien van gecontaineriseerde applicaties. Hoewel het bestandssysteem klein is, is het uitbreidbaar en wordt het geleverd met een compleet pakketbeheersysteem met de mogelijkheid om functionaliteiten toe te voegen.
Bij het kiezen van een base-image op de Docker Hub, zul je merken dat er meerdere tags beschikbaar zijn voor elke image. Met het oog op Python, hebben we 3-alpine, wat verwijst naar de nieuwste Python 3-versie-image van de nieuwste Alpine-versie. Dit betekent dat als je project met een oudere image-versie werkt, dit kan stoppen met werken wanneer de beheerders van de Docker-image een update uitvoeren. Om dergelijke scenario's in de toekomst te voorkomen, wordt het altijd aanbevolen om de meest specifieke tags te kiezen voor de image die je wilt gebruiken.
In deze handleiding gebruiken we de 3.8.12-alpine3.15 image als de basis-image voor onze Django-applicatie. Deze specifieke tag wordt gespecificeerd in de Dockerfile met behulp van de FROM instructie. De Dockerfile bevindt zich in de hoofdprojectmap: django_project.
Begin door te navigeren uit de Django-polls map terug naar de django_project map:
|
1 |
cd .. |
Zodra u in de map bent, gebruikt u uw favoriete editor om een bestand te openen genaamd Dockerfile :
|
1 |
nano Dockerfile |
Plak vervolgens de volgende regel om de basis van uw image in te stellen:
|
1 |
FROM python:3.8.12-alpine3.15 |
Het FROM trefwoord definieert het startpunt van een aangepaste Docker-image. Nu dat is gedefinieerd, kunnen we doorgaan met het toevoegen van instructies om de applicaties in te richten. Deze instructies installeren de benodigde afhankelijkheden, kopiëren de applicatiebestanden en richten de runtime-omgeving in.
Voeg het volgende codefragment toe in de Dockerfile:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
ADD django-polls/requirements.txt /app/requirements.txt RUN set -ex \ && apk add --no-cache --virtual .build-deps postgresql-dev build-base \ && python -m venv /env \ && /env/bin/pip install --upgrade pip \ && /env/bin/pip install --no-cache-dir -r /app/requirements.txt \ && runDeps="$(scanelf --needed --nobanner --recursive /env \ | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ | sort -u \ | xargs -r apk info --installed \ | sort -u)" \ && apk add --virtual rundeps $runDeps \ && apk del .build-deps ADD django-polls /app WORKDIR /app ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH EXPOSE 8000 |
In dit codefragment vertellen we Docker om het requirements.txt -bestand te kopiëren naar /app/requirements.txt om ervoor te zorgen dat de afhankelijkheden van de applicatie beschikbaar zijn op het bestandssysteem van de image. De vereisten omvatten alle Python-pakketten die nodig zijn om de applicatie uit te voeren. De afhankelijkheden worden eerst gekopieerd, zodat Docker de image-laag kan cachen. Dat komt omdat Docker elke stap in de Dockerfile cachet. De eerste build van de image duurt meestal langer. Docker downloadt de afhankelijkheden en slaat ze vervolgens op in de cache. Als het requirements.txt-bestand niet verandert, zal Docker bouwen vanuit de cache, waardoor volgende builds sneller verlopen.
De volgende stap bevat de RUN instructie die een lijst met Linux-commando's uitvoert, gekoppeld aan de Linux && operator. De commando's doen het volgende:
-
Gebruik Alpine's apk pakketbeheertool om PostgreSQL-ontwikkelingsbestanden en basis-build-afhankelijkheden te installeren.
-
Maak een virtuele Python-omgeving aan.
-
Installeer de Python-afhankelijkheden zoals gedefinieerd in het requirements.txt-bestand met behulp van pip.
-
Compileer de benodigde runtime-pakketten door de vereisten van de geïnstalleerde Python-pakketten te analyseren.
-
Verwijder eventuele build-afhankelijkheden die niet langer nodig zijn.
De reden voor het koppelen van de commando's in de RUN stap is het verminderen van image-lagen. Docker maakt telkens wanneer het ADD, COPY, of RUN instructie in de Dockerfile. Het comprimeren van commando's waar van toepassing zal het aantal gemaakte imagelagen minimaliseren.
Items die aan imagelagen zijn toegevoegd, kunnen in een volgende laag niet worden verwijderd. Je moet instructies declareren om ongewenste items te verwijderen voordat je doorgaat naar de volgende instructie. Dit is nodig om de omvang van de image te verkleinen. Je hebt waarschijnlijk gemerkt dat we de apk del opdracht aan het einde van de RUN opdracht hebben toegevoegd. Dat is gedaan om de build-afhankelijkheden te verwijderen nadat we ze hadden gebruikt om de pakketten van de app te bouwen.
Vervolgens hebben we nog een ADD instructie die we gebruiken om de applicatiecode te kopiëren naar de /app map. Vervolgens gebruiken we de WORKDIR instructie om de werkmap van de image in te stellen op de /app map, die nu de code van de applicatie bevat.
Vervolgens hebben we de ENV instructies die we gebruiken om twee omgevingsvariabelen in te stellen die de image beschikbaar zal maken voor de actieve containers. Eerst stellen we de VIRTUAL_ENV variabele in op /env. Ten tweede stellen we de PATH variabele in om de /env/bin map op te nemen. In deze twee regels sourcen we het /env/bin/activate script, wat de manier is waarop we een virtuele omgeving activeren in een Linux-omgeving. Je kunt meer lezen over het werken met virtuele omgevingen in Python op andere besturingssystemen. De laatste instructie is de EXPOSE opdracht die de poort instelt 8000 waarop de container tijdens runtime zal luisteren.
Inmiddels is je Dockerfile bijna compleet, afgezien van het standaardcommando dat wordt uitgevoerd wanneer je de containers start. Laten we dat in de volgende sectie definiëren.
-
Het standaard Docker-imagecommando begrijpen
Bij het opstarten van een Docker-container kun je een uit te voeren commando opgeven. Als je echter geen commando opgeeft, bepaalt het standaardcommando van de Docker-image wat er gebeurt als de container start. We gebruiken de ENTRYPOINT of CMD instructies afzonderlijk of samen om een standaardcommando te definiëren binnen de Dockerfile.
Als je ervoor kiest om zowel ENTRYPOINT als CMD, in de ENTRYPOINT instructie, definieer je het uitvoerbare bestand dat door de container zal worden uitgevoerd. In de CMD instructie definieer je de standaard argumentenlijst voor het uitvoerbare commando. Je kunt de standaard argumentenlijst overschrijven door alternatieve argumenten toe te voegen aan de opdrachtregel bij het starten van de container in de indeling:
|
1 |
docker run <image> <arguments> |
Deze indeling voorkomt dat ontwikkelaars eenvoudig het ENTRYPOINT commando overschrijven. Het ENTRYPOINT commando is gedefinieerd om een script aan te roepen dat de omgeving instelt en verschillende acties uitvoert op basis van de opgegeven argumentenlijst.
Je kunt de ENTRYPOINT instructie alleen gebruiken om het uitvoerbare bestand van de container te configureren. Deze indeling staat echter niet toe om een standaard argumentenlijst te definiëren. Je kunt argumenten opgeven wanneer je de container uitvoert met het docker run commando.
Als je ervoor kiest om alleen CMD te gebruiken, interpreteert Docker dit als het standaardcommando en de argumentenlijst, die je tijdens runtime kunt overschrijven. Je kunt meer informatie vinden in de officiële Dockerfile-referentiedocumentatie.
Laten we kijken hoe we de informatie die je hebt geleerd over standaardcommando's kunnen toepassen op ons container-voorbeeld. We willen de applicatie standaard serveren met behulp van de gunicorn server. Hoewel de argumentenlijst die aan de gunicorn server wordt doorgegeven niet configureerbaar hoeft te zijn tijdens runtime, willen we de flexibiliteit om andere commando's uit te voeren voor doeleinden zoals debuggen of het beheren van configuraties (de database initialiseren, statische bestanden verzamelen, enz.). Zoals je kunt zien, is het in ons belang om de CMD te gebruiken om een standaardcommando te definiëren, waardoor we dit indien nodig kunnen overschrijven.
Hier zijn enkele syntaxen die je kunt gebruiken om het CMD commando te definiëren:
- CMD ["command", "argument 1", "argument 2", . . . ,"argument n"]: De exec indeling (aanbevolen indeling) neemt een commando en een lijst met argumenten. Het voert het commando rechtstreeks uit zonder shell-verwerking.
- CMD command "argument 1" "argument 2" . . . "argument n": De shell-indeling definieert een opdracht en een lijst met argumenten. Het geeft de lijst met opdrachten door aan de shell voor verwerking. Dit kan handig zijn als u omgevingsvariabelen in een opdracht wilt vervangen, maar het is niet helemaal voorspelbaar.
- CMD ["argument 1", "argument 2", . . . ,"argument n"]: De argumentenlijst-indeling, deze definieert alleen de standaard argumentenlijst en wordt gebruikt in combinatie met een ENTRYPOINT instructie.
We zullen de exec indeling gebruiken om onze definitieve instructie te definiëren in de Dockerfile. Voeg de volgende regel toe aan het einde van uw Dockerfile:
|
1 |
CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi:application"] |
U kunt nu overgaan tot het opslaan en sluiten van de Dockerfile.
Wanneer u containers opstart met deze image, zullen ze gunicorn uitvoeren, gekoppeld aan localhost-poort 8000 met 3 workers, en de application-functie aanroepen in het wsgi.py-bestand dat te vinden is in de mysite map. U kunt er ook voor kiezen om een andere opdracht op te geven om de standaardopdracht tijdens runtime te overschrijven en een ander proces uit te voeren in plaats van gunicorn. Misschien wilt u meer lezen over Gunicorn-workers.
Uw Dockerfile is nu gereed en u kunt docker build gebruiken om de app-image te bouwen. U kunt docker run gebruiken om de container op te starten op uw lokale ontwikkelmachine.
-
De Docker-image bouwen
De docker build-opdracht zoekt standaard naar een Dockerfile in de huidige map om de bouwinstructies te vinden. Het stuurt ook de bouwcontext (“context”) naar de Docker-daemon. Een bouwcontext is een set bestanden die beschikbaar moet zijn tijdens het bouwproces. Standaard is de huidige map waarin u de docker build opdracht uitvoert, ingesteld als de bouwcontext.
Voer, terwijl u zich in dezelfde map bevindt als uw Dockerfile, de volgende opdracht uit: docker build. Geef een image en tag op met de -t-vlag, en stel de huidige map in als bouwcontext met behulp van de ( .) punt aan het einde van de opdracht:
|
1 |
docker build -t django-polls:v1 . |
In deze opdracht hebben we de image django-polls genoemd en de tag v1. Let op de punt aan het einde van de opdracht; we gebruiken deze om de huidige map aan te duiden als de bouwcontext.
Wanneer de docker build is voltooid, zou u een uitvoer moeten zien die lijkt op het volgende:

Uw Docker-image is nu gereed. Als we een deel van de configuraties niet naar externe omgevingsvariabelen hadden verplaatst, had u uw container eenvoudig kunnen uitvoeren met de docker run-opdracht. Omdat we de externe omgevingsvariabelen die we in het settings.py-bestand hebben ingesteld echter niet hebben geconfigureerd, zal het uitvoeren mislukken. Laten we dat in de volgende stap afronden.
Stap 8: De runtime-omgeving instellen en de app testen
We naderen het einde van deze handleiding. In deze stap configureren we de omgevingsvariabelen in het env bestand. Met de variabelen uit het env bestand op hun plaats, kunnen we het databaseschema maken, de statische bestanden genereren en uploaden naar de externe objectopslagdienst, en ten slotte de app testen.
Docker biedt verschillende methoden die u kunt gebruiken om omgevingsvariabelen aan te bieden aan de container. In ons geval willen we een lijst met omgevingsvariabelen aanbieden via een bestand. Daarom gebruiken we de --env-file-methode.
Maak met de editor van uw voorkeur een bestand genaamd env in de django_project-map:
|
1 |
nano env |
Plak de volgende lijst met variabelen erin:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
DJANGO_SECRET_KEY=your_secret_key DEBUG= DJANGO_LOGLEVEL=info DJANGO_ALLOWED_HOSTS=jouw_server_IP_adres DB_ENGINE=postgresql_psycopg2 DB_DATABASE=polls_db DB_USERNAME=hackins DB_PASSWORD=jouw_database_wachtwoord DB_HOST=jouw_database_host DB_PORT=jouw_database_poort STATIC_DEFAULT_FILE_STORAGE=storages.backends.s3boto3.S3Boto3Storage STATIC_MINIO_BUCKET_NAME=test-bucket MINIO_ACCESS_KEY=jouw_minio_access_key MINIO_SECRET_KEY=jouw_minio_secret_key MINIO_URL=jouw_minio_url:jouw_minio_poort |
De variabelen in de lijst zijn de variabelen die je in de vorige stappen hebt gedefinieerd:
-
DJANGO_SECRET_KEY: Genereer een unieke, onvoorspelbare waarde zoals uitgelegd in de Django-documentatie. Je kunt dit commando gebruiken om een willekeurige tekenreeks te genereren en deze aan de variabele toe te wijzen:
|
1 |
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())' |
-
DEBUG: We hebben deze waarde ingesteld op True, maar vergeet niet om deze voor een productie-implementatie in te stellen op False door deze leeg te laten.
-
DJANGO_LOGLEVEL: we hebben dit ingesteld op info, pas dit gerust aan naar het gewenste niveau.
-
DJANGO_ALLOWED_HOSTS: stel deze waarde in op het IP-adres van de Ubuntu-server waarop je Docker-containers draaien. Stel deze optioneel in op *, wildcard die overeenkomt met alle hosts in de ontwikkelingsmodus.
-
DB_DATABASE: als je een andere databasenaam hebt gebruikt, stel deze dan hier op de juiste manier in.
-
DB_USERNAME: stel dit in op de gebruikersnaam die je voor je database hebt gekozen.
-
DB_PASSWORD: stel dit in op het wachtwoord dat je voor je database hebt gekozen.
-
DB_HOST: stel dit in op de host waarop je database-instantie draait, zoals je had ingesteld in Stap één.
-
DB_PORT: stel dit in op de poort van je database.
-
STATIC_MINIO_BUCKET_NAME: stel dit in op de bucketnaam die je hebt aangemaakt in je MinIO Cloud Storage-account.
Sla het bestand op en sluit het wanneer je klaar bent met bewerken.
De omgevingsconfiguraties zijn nu klaar. We moeten de container uitvoeren en argumenten doorgeven om het standaard CMD-commando te overschrijven en het databaseschema te maken met behulp van de manage.py makemigrations en manage.py migrate commando's.
Hier is het commando:
|
1 |
docker run --env-file env django-polls:v1 sh -c "python manage.py makemigrations && python manage.py migrate" |
In dit commando voeren we de django-polls:v1 container-image uit, waarbij we de –env-file vlag gebruiken om het omgevingsvariabelebestand door te geven. We overschrijven ook het standaard CMD-commando met sh -c "python manage.py makemigrations && python manage.py migrate" Wanneer dit commando wordt uitgevoerd om de container te starten, zal het het databaseschema maken zoals gedefinieerd in de applicatiecode.
Als dit lukt, zou je een uitvoer moeten zien die vergelijkbaar is met de onderstaande:

De uitvoer geeft aan dat het databaseschema succesvol is gemaakt.
De volgende stap is het maken van een administratieve gebruiker voor de Django-app. We starten de container op en openen een interactieve shell daarin met het volgende commando:
|
1 |
docker run -i -t --env-file env django-polls:v1 sh |
Het commando start de container met een shell-prompt die je kunt gebruiken om te communiceren met de Python-shell. Laten we een gebruiker maken:
|
1 |
python manage.py createsuperuser |
Volg de aanwijzingen om een gebruikersnaam, e-mailadres en wachtwoord op te geven, typ het wachtwoord opnieuw en druk op enter om de gebruiker aan te maken. Verlaat de shell en sluit de container af door te drukken op CTRL+D.
Vervolgens moeten we de container opnieuw uitvoeren, waarbij we het standaardcommando overschrijven met het collectstatic Django-commando om de statische bestanden voor de app te genereren en ze te uploaden naar je MinIO Cloud Storage-service:
|
1 |
docker run --env-file env django-polls:v1 sh -c "python manage.py collectstatic --noinput" |
Wanneer dit is voltooid, zou je een vergelijkbare uitvoer moeten zien als hieronder, wat aangeeft dat je container succesvol verbinding heeft gemaakt met de MinIO-opslagservice en de statische bestanden heeft geüpload:
![]()
Onze storage bucket ziet er nu zo uit, met de mappen die Django heeft gemaakt:

Ten slotte kunnen we de app nu uitvoeren met het commando:
|
1 |
docker run --env-file env -p 80:8000 django-polls:v1 |
Hier is de uitvoer:

Wanneer u het bovenstaande commando uitvoert, voert het de standaard CMD-opdracht in uw image uit en stelt poort 8000 in zoals gedefinieerd. Nu wordt Ubuntu op poort 80 gekoppeld aan de 8000 poort van de django-polls:v1 container.
We kunnen de applicatie nu testen in de browser. Ga naar het openbare IP-adres van uw server in de browser: http://your_server_public_ip.
Verwacht een 404 Pagina Niet Gevonden-fout, aangezien we volgens de Django Tutorial, we geen route hebben gedefinieerd voor / pad:

We hebben de DEBUG ingesteld op True, daarom zien we deze foutpagina met veel cruciale informatie. Laten we de DEBUG uitschakelen. Eerst moet u de actieve container stoppen met CTRL+C. Open vervolgens de env bestand:
|
1 |
nano env |
Zoek vervolgens de DEBUG en schakel deze uit, of laat deze leeg. We laten deze leeg omdat de getenv-functie interpreteert False als een string, waardoor deze true retourneert:
|
1 |
DEBUG= |
Sla het bestand op en voer de container opnieuw uit met het commando:
|
1 |
docker run --env-file env -p 80:8000 django-polls:v1 |
Als u http://your_server_public_ip bezoekt in uw browser, zou u de standaard 404-pagina moeten zien:

U hebt gezien hoe u het runtime-gedrag van uw Django-app kunt manipuleren met behulp van omgevingsvariabelen, zonder de broncode te wijzigen.
Navigeer naar http://your_server_public_ip/polls om de startpagina van Polls te zien:

We hebben nog geen peilingen omdat we de app net hebben geïmplementeerd.
Navigeer naar de beheerdersinterface: http://your_server_public_ip/admin om het beheerdersauthenticatievenster te bekijken:

Voer de inloggegevens in die u had ingesteld met het createsuperuser-commando om in te loggen. U zou zich nu op de beheerpagina-interface moeten bevinden:

Merk op dat alle statische bestanden worden geserveerd vanaf de externe opslagdienst die we hebben ingesteld. U kunt met de rechtermuisknop klikken in uw browservenster en selecteer Paginabron weergeven:

U kunt enkele vragen en keuzes toevoegen en de algehele prestaties van de app testen:

Ga terug naar de Polls-index http://your_server_public_ip/polls en probeer op de vraag te stemmen:

Nadat u alles hebt getest en bevestigd dat alles naar verwachting werkt, kunt u de container beëindigen.
Conclusie
U hebt met succes een Django-web-app geconfigureerd om goed te werken in een op containers gebaseerde omgeving. Dit omvatte het aanpassen van de app om te werken met externe omgevingsvariabelen, het instellen van de app om een cloudopslagdienst te gebruiken voor de statische bestanden, en het maken van een Dockerfile voor de container-image. U kunt de wijzigingen bekijken die we hebben aangebracht om de app te Dockeriseren op de django-polls-docker branch van de django-polls GitHub-repository.
Vanaf hier worden de mogelijkheden alleen beperkt door uw verbeelding. U kunt een Nginx reverse proxy instellen tussen clients en de Gunicorn-server. U kunt ook Certbot toevoegen om TLS-certificaten te verkrijgen om uw Nginx-server te beveiligen. We raden aan om een HTTP-proxy toe te voegen om trage clients te bufferen en uw Gunicorn-server te beschermen tegen denial-of-service-aanvallen.
Hoewel we 3 workers hebben gedefinieerd in het opstartcommando van de Dockerfile, kunt u het aantal van uw voorkeur instellen, afhankelijk van de beschikbare bronnen op uw server. U kunt meer informatie vinden in de officiële Gunicorn-ontwerpdocumentatie. Als u wilt, kunt u de Docker-image die u hebt gebouwd naar Docker Hub pushen en proberen deze te implementeren op verschillende omgevingen waarop Docker is geïnstalleerd. Als u meer wilt weten, blijf dan onze Tutorials-blog in de gaten houden, want we zullen een vervolghandleiding maken om de Django-app te beveiligen met Nginx en Let's Encrypt.
Tot slot zijn hier nog meer bronnen die u zullen helpen Docker te gebruiken:
- Hoe u een Docker-image-repository host en Docker-images bouwt met een GitLab Self-Managed-instantie op Ubuntu 20.04
- Werken met Docker-datavolumes op Ubuntu 20.04
- Een Flask-applicatie bouwen en implementeren met Docker op Ubuntu 20.04
- Hoe u WordPress implementeert met Docker-containers op Ubuntu 20.04
Veel computerplezier!
Reacties
Nog geen reacties. Wees de eerste.