Terug naar blog

Django opzetten met PostgreSQL, Nginx en Gunicorn op Ubuntu 20.04

Django opzetten met PostgreSQL, Nginx en Gunicorn op Ubuntu 20.04

Django is een gratis en open-source webapplicatie-framework dat is gebouwd in de Python programmeertaal. Django is supersnel, veilig en zeer schaalbaar. In de handen van een ervaren ontwikkelaar kan Django snel een krachtige website opzetten. Het kan naadloos worden geïntegreerd met populaire webservers (Apache, Nginx), en databases (MySQL, MariaDB, PostgreSQL, Oracle, en SQLite), enz. Django drijft enkele van 's werelds grootste websites aan, zoals Instagram, Mozilla en NASA. Deze gids demonstreert het opzetten van de basis van een web-app met behulp van Django met PostgreSQL, Nginx en Gunicorn op Ubuntu 20.04.

Vereisten

Deze gids vereist dat u een Ubuntu 20.04-server gebruikt die is geconfigureerd met een basis-firewall en een niet-rootgebruiker met sudo-rechten. Bekijk deze gedetailleerde gids over hoe u een Ubuntu-server instelt. Volg deze handleiding om een niet-rootgebruiker met sudo-rechten te configureren. U kunt ook een Iptables-firewall configureren door de stappen van deze gids te volgen.

We installeren Django binnen een virtuele omgeving. Een projectspecifieke omgeving maakt het eenvoudiger om meerdere projecten vanaf dezelfde server te beheren. Zodra de databases en apps zijn ingesteld, implementeren we de Gunicorn-applicatieserver. Gunicorn is de applicatie-interface die clientverzoeken vertaalt van HTTP naar Python-aanroepen die onze applicatie kan gebruiken. Vervolgens implementeren we Nginx vóór Gunicorn vanwege de snelle prestaties bij het afhandelen van verbindingen en de eenvoudig te implementeren beveiligingsfuncties.

De benodigde pakketten installeren

Begin eerst met het installeren van alle benodigde pakketten. Gelukkig zijn al deze pakketten rechtstreeks beschikbaar via de officiële Ubuntu-pakketbronnen. Open de terminal en update de APT pakketcache:

De pakketlijst hangt af van de vraag of de webapplicatie Python 2 of Python 3 gaat gebruiken. Voer de volgende opdracht uit om Django met Python 3 te installeren:

Django 1.11 LTS is de laatste release van Django die Python 2 ondersteunt. Als u van plan bent Django met Python 2 te gebruiken, installeer dan de volgende pakketten:

PostgreSQL-database en -gebruiker

Wat betreft de database-oplossing gebruiken we PostgreSQL. Het is een krachtig, open-source object-relationeel databasesysteem. PostgreSQL biedt betrouwbaarheid, robuustheid en prestaties. Voor gedetailleerde stappen over het instellen van PostgreSQL, bekijk deze gids over het instellen van PostgreSQL op de Ubuntu-server. Voor deze gids stellen we een speciale database en gebruiker in voor onze Django-applicatie.

By default, PostgreSQL implements “peer authentication” as the authentication scheme for local connections. In short, “peer authentication” will authenticate the login if the user’s operation system username matches a valid PostgreSQL username. During the installation, PostgreSQL configured an operating system user postgres die overeenkomt met de postgres PostgreSQL-beheerder. Log in op de interactieve shell-sessie van PostgreSQL als postgres met behulp van de volgende opdracht:

U komt terecht op de PostgreSQL-prompt. De eerste stap is het maken van een speciale database voor het project. Ter demonstratie krijgt de database de naam viktor_project:

De volgende stap is het maken van een speciale gebruiker voor de projectdatabase. De gebruiker moet een sterke gebruikersnaam hebben. Ter demonstratie zal de gebruikersnaam viktor_project_user:

Nu gaan we enkele parameters wijzigen:

  • Bepaalde verbindingsparameters. Kortom, het is niet nodig om telkens wanneer een verbinding tot stand wordt gebracht de juiste waarden op te vragen en in te stellen. Dit verbetert de databaseprestaties aanzienlijk.
  • Standaardcodering naar UTF-8. Het is een universele codering en Django verwacht deze.
  • Standaard transactie-isolatieschema op “read committed”. Dit blokkeert het lezen van niet-gecommitteerde transacties.
  • Tijdzone naar UTC.

Al deze parameterwijzigingen worden aanbevolen door het Django-project zelf. Voer de volgende opdrachten uit om deze wijzigingen door te voeren. Vergeet niet de gebruikersnaam van de database te wijzigen in de juiste:

Wijzig de databasebeheerder naar de specifieke databasegebruiker:

Ons werk met PostgreSQL is voor nu klaar. Sluit de interactieve shell van PostgreSQL af:

Exit the PostgreSQL interactive shell

Virtuele Python-omgeving

Nu de database is voorbereid, kunnen we ons richten op het opzetten van de rest van de projectvereisten. Voor eenvoudiger beheer richten we een virtuele omgeving in en installeren we daar alle Python-vereisten. Om een virtuele omgeving te genereren, hebben we virtualenv nodig. Dit kan eenvoudig worden geïnstalleerd met pip.

De volgende opdrachten zullen pip upgraden en virtualenv installeren. Voer voor Python 3 de volgende opdrachten uit:

Voer in plaats daarvan voor Python 2 de volgende opdrachten uit:

Zodra virtualenv is geïnstalleerd, is het tijd om een virtuele omgeving aan te maken. Maak vervolgens een specifieke map aan voor de virtuele omgeving:

Wijzig daarna de huidige actieve map naar de specifieke map voor de virtuele omgeving:

Voer binnen de map de volgende opdracht uit. De virtualenv-tool zal een virtuele omgeving maken met de projectnaam:

Er wordt een submap gemaakt met de projectnaam. De submap bevat een lokale versie van Python en pip. Dit biedt flexibiliteit om een geïsoleerde Python-omgeving voor het project te installeren en te configureren.

De volgende opdracht activeert de virtuele omgeving:

activate the virtual environment

De terminalprompt verandert om aan te geven dat u binnen een virtuele Python-omgeving werkt. Nu we ons in de virtuele omgeving bevinden, installeren we de benodigde Python-vereisten. We hebben Django, Gunicorn en psycopg2 (PostgreSQL-adapter) nodig. De volgende opdracht geeft de lokale pip de opdracht om de componenten te installeren:

Zelfs als u Python 3 gebruikt, is pip de juiste opdracht. Dit komt omdat binnen de virtuele omgeving pip3 is hernoemd naar pip.

Nieuw Django-project

Nu de Python-componenten aanwezig zijn, kunnen we aan de slag met de daadwerkelijke Django-projectbestanden.

  • Een Django-project maken

De projectmap is al aangemaakt. We vertellen Django om de bestanden daar te installeren. Deze procedure genereert een map op het tweede niveau die de daadwerkelijke code bevat. De map bevat ook een beheerscript. Het belangrijkste is dat we Django expliciet de doelmap vertellen in plaats van het de map te laten bepalen ten opzichte van de huidige:

Django zal het project dienovereenkomstig aanmaken. Hier zijn enkele van de belangrijke bestanden en mappen waar we ons op zullen richten. De map- en bestandsnamen worden gebruikt volgens de demonstratie.

  • ~/viktor_project/manage.py: Het projectbeheerscript van Django.
  • ~/viktor_project/viktor_project/: Dit is het pakket dat het Django-project bevat. Het moet de bestanden __init__.py, settings.py, urls.py, asgi.py en wsgi.py bevatten.
  • Projectinstellingen aanpassen

Nadat het project is aangemaakt, is het eerste wat u moet doen de configuratie ervan aanpassen. Open settings.py in een teksteditor:

De eerste richtlijn waarnaar we op zoek zijn is ALLOWED_HOSTS. Deze definieert de servers of domeinnamen die verbinding kunnen maken met de Django-instantie. Als een binnenkomend verzoek met een Host-header niet overeenkomt met de lijst van ALLOWED_HOSTS, zal dit een uitzondering veroorzaken. Dit wordt door Django aanbevolen om bepaalde soorten beveiligingslekken te voorkomen:

ALLOWED_HOSTS

De volgende sectie waar we ons op zullen richten is DATABASE. Deze beheert de toegang tot de database. Standaard bevat deze de configuratie voor de SQLite-database-engine. We gaan echter de PostgreSQL-database gebruiken voor het project. Django zal de psycopg2-adapter gebruiken om met PostgreSQL te communiceren:

django 1

Ga nu naar de onderkant van het bestand. Voeg de volgende regels toe om de locatie van statische bestanden aan te geven. Dit helpt Nginx om verzoeken voor deze items af te handelen:

static

Ons werk met settings.py is voor nu klaar. Sla het bestand op en sluit de editor.

  • Eerste projectconfiguratie afronden

We kunnen nu het initiële databaseschema migreren naar de toegewijde PostgreSQL-database. Voer de volgende opdracht uit:

Vervolgens moeten we een superuser aanmaken voor het project. Voer de volgende opdracht uit om een superuser te genereren:

viktor_project

Verzamel alle statische bestanden op de locatie die we in settings.py hebben opgegeven. De statische bestanden worden verzameld in een aparte map genaamd “static” onder de projectmap:

Nu moeten we aan de slag met de serverfirewall. Als u de handleiding voor serverconfiguratie hebt gevolgd, is UFW al geconfigureerd en geactiveerd. We maken een uitzondering voor poort 8000. Dit is de standaardpoort die Django gebruikt. Bekijk deze handleiding voor meer informatie over de basisprincipes en het gebruik van de UFW-firewall.

Controleer vervolgens de actie:

Tenslotte kunnen we de server in actie testen. Start de Django-ontwikkelingsserver:

Als de configuratie is geslaagd, zou de Django-ontwikkelingsserver moeten starten en binnenkomende verzoeken moeten accepteren. Open een browser en ga naar het IP-adres of domein van uw server op poort 8000:

django 2

U zou op de standaard indexpagina van Django moeten terechtkomen. Om toegang te krijgen tot het beheerderspaneel, voegt u /admin toe aan de URL. Het beheerderspaneel is alleen toegankelijk voor de superuser die we vooraf hebben aangemaakt:

Na het inloggen kom je op de standaard Django-beheerinterface terecht:

django 3

We zijn voor nu klaar met testen. Om de server te stoppen, druk je op “Ctrl + C” in het terminalvenster.

  • Gunicorn testen

Voordat we de virtuele omgeving verlaten, willen we er zeker van zijn dat Gunicorn de applicaties kan serveren. De manier om dit te testen is door Gunicorn te gebruiken om de WSGI-module van het project te laden.

Het Gunicorn-commando bevindt zich in de projectmap:

Dit start Gunicorn op dezelfde interface als waarop Django draaide. We kunnen de app opnieuw testen vanuit een normale webbrowser. Let op dat de beheerinterface geen styling heeft, omdat Gunicorn nog niet weet hoe het de statische CSS-inhoud moet vinden:

Wanneer je klaar bent, druk je op “Ctrl + C” in het terminalvenster om de Gunicorn-server te stoppen.

  • Virtuele omgeving verlassen

De configuratie van de Django-applicatie is voltooid. Voer het volgende commando uit om de virtuele omgeving te verlaten:

Gunicorn socket- en servicebestanden

We hebben geverifieerd dat Gunicorn kan communiceren met de Django-applicatie. We hebben echter een robuustere manier nodig om de applicatieserver te beheren. Hier komt systemd in beeld. Systemd is een van de meest populaire init-systemen die beschikbaar zijn op Linux. Hier is een diepgaande handleiding over hoe je systemd-services en -units beheert.

We kunnen socket- en servicebestanden maken voor Gunicorn om systemd dit te laten beheren alsof het een service is. Bij het opstarten wordt de Gunicorn-socket gegenereerd. De socket luistert naar inkomende verbindingen. Wanneer er een verbinding tot stand komt, start systemd Gunicorn-processen om de verbinding af te handelen.

  • Gunicorn-socket

Laten we beginnen met het maken van een Gunicorn-socket. Het bestand moet worden gemaakt met sudo-rechten:

Voer de volgende code in het bestand in:

Zoals je kunt zien, bestaat de code uit drie secties.

  • [Unit]: Deze sectie beschrijft de socket.
  • [Socket]: Dit definieert de locatie van de socket.
  • [Install]: Dit deel zorgt ervoor dat systemd de socket op het juiste moment aanmaakt.

Sla het bestand op en sluit de editor.

  • Gunicorn-service

Vervolgens maken we een servicebestand voor Gunicorn. Net als het socketbestand moet dit ook met sudo-rechten worden gemaakt:

Voer de volgende code in:

De code bevat meerdere secties:

  • [Unit]: Deze sectie specificeert metadata en afhankelijkheden. Het beschrijft ook dat er pas gestart mag worden nadat het netwerkdoel is bereikt.
  • [Service]: Deze sectie specificeert de gebruiker en groep waaronder het proces zal draaien. Het eigendom van de groep is ingesteld op “www-data” zodat Nginx kan communiceren met Gunicorn. Het brengt ook de werkmappen in kaart en specificeert de startcommando's.
  • [Install]: Deze sectie vertelt systemd waaraan deze service moet worden gekoppeld als deze bij het opstarten is ingeschakeld. Het zou moeten starten nadat het reguliere multi-user systeem begint te draaien.

Sla vervolgens het bestand op en sluit de editor.

  • Gunicorn-socket inschakelen

De Gunicorn-socket is klaar voor gebruik. Daarom kunt u de volgende commando's uitvoeren. Het zal de socket starten en inschakelen. Het socketbestand zal worden aangemaakt op /run/gunicorn.sock bij het opstarten. Wanneer er verbinding wordt gemaakt met de socket, zal systemd de Gunicorn-service starten om deze af te handelen:

Controleer de status van de Gunicorn-socket:

Controleer nu het bestaan van het socketbestand:

Als de status van systemctl een fout aangeeft of het gunicorn.sock-bestand niet is gevonden, geeft dit aan dat de socket niet correct is aangemaakt. Bekijk het gedetailleerde logboek voor aanwijzingen:

gunicorn.socket

Vergeet niet om nog eens te kijken naar het gunicorn.socket bestand voor mogelijke fouten.

  • Socket-activering

We hebben tot nu toe de gunicorn.socket gestart. Zonder een verbindingsverzoek zal gunicorn.service echter niet activeren. Controleer vervolgens de status van Gunicorn:

We kunnen het socket-activeringsmechanisme testen door een verbindingsverzoek te sturen met behulp van curl:

Je zou een HTML-output van de applicatie moeten krijgen. Dit geeft aan dat Gunicorn succesvol is gestart en de Django-applicatie kon bedienen. Controleer de huidige status van de Gunicorn-service:

Als er onverwacht gedrag of onverwachte output is (wat duidt op een fout), bekijk dan de gedetailleerde logboeken voor aanwijzingen:

Als er wijzigingen zijn aangebracht in het gunicorn.service-bestand, moet u de daemon herladen om de service-definitie opnieuw te lezen. Dit vereist ook het herstarten van de Gunicorn-service:

Nginx configureren

Nu gaan we Nginx configureren om inkomend verkeer door te sturen naar het proces. Maak eerst een nieuw serverblok aan in Nginx:

Voer vervolgens de volgende code in:

 

Hier zijn meerdere blokken in de configuratie:

  • service: Dit blok definieert dat de server normaal gesproken op poort 80 moet luisteren en moet reageren op de domeinnaam of het IP-adres van de server.
  • location: Dit is de eerste location-invoer. Het definieert waar de statische bestanden te vinden zijn.
  • location: Dit is de tweede location-invoer. Dit blok definieert standaard proxy-parameters en hoe het verkeer naar de Gunicorn-socket moet worden doorgestuurd.

Sla het bestand op en sluit de editor. Koppel het bestand aan de map “sites-enabled” om het te activeren:

Test daarna of er syntaxfouten zijn in de Nginx-configuratie:

Als u geen fout heeft gevonden, start Nginx dan opnieuw op om de wijziging door te voeren:

We moeten de UFW-regels opnieuw aanpassen. We hebben geen toegang meer nodig tot de ontwikkelserver, dus we kunnen de uitzondering voor poort 8000 verwijderen. Daarnaast willen we poort 80 openstellen voor normaal verkeer:

Controleer deze wijzigingen in de firewallregels:

De server zou nu toegankelijk moeten zijn via een normale webbrowser.

Probleemoplossingsprocedures

Als alle stappen correct zijn gevolgd, zou de Django-applicatie via internet toegankelijk moeten zijn. Als dat niet het geval is, geeft dit aan dat de installatie niet is verlopen zoals gepland. We moeten problemen oplossen om de oorzaak van het probleem te achterhalen.

  • Nginx toont de standaardpagina

Als Nginx de standaardpagina weergeeft in plaats van de applicatieproxy, betekent dit meestal dat de server_name verkeerd was geconfigureerd in het serverblok.

In dit voorbeeld is het serverblok opgeslagen op de volgende locatie:

De server_name invoer bepaalt welk serverblok Nginx zal gebruiken om op verzoeken te reageren. Als de standaardpagina wordt weergegeven, kon Nginx het verzoek waarschijnlijk niet koppelen aan een expliciet serverblok, waardoor het in plaats daarvan terugvalt op het standaardblok:

Controleer of het serverblok van uw Django-project een geldige server_name.

  • 502 Bad Gateway

Fout 502 geeft aan dat Nginx het verzoek niet succesvol kon proxyen. Er is een breed scala aan mogelijke configuratieproblemen die kunnen leiden tot fout 502, dus we hebben aanwijzingen nodig om het probleem goed op te lossen.

De belangrijkste bron van aanwijzingen zijn de Nginx-foutenlogboeken. Over het algemeen geeft dit een indicatie van de omstandigheden die de problemen tijdens de proxy hebben veroorzaat. Controleer het Nginx-foutenlogboek met de volgende opdracht:

Zodra het logboek is geopend, probeert u de server nogmaals te openen. Dit zou een nieuw foutbericht in het logboek moeten genereren. Dit kan helpen het probleem te verduidelijken. Hier zijn een paar mogelijke berichten:

  • connect() to unix:/run/gunicorn.sock failed (2: No such file or directory)

Dit geeft aan dat Nginx gunicorn.sock niet kon vinden op de locatie die in de configuratie is gedefinieerd. De locatie wordt beschreven door de proxy_pass richtlijn onder het siteblok. Controleer of proxy_pass de juiste locatie aangeeft van gunicorn.sock gegenereerd door de gunicorn.socket systemd-unit:

Als gunicorn.sock niet werd gevonden onder de /run map, betekent dit dat systemd deze niet kon genereren. U moet de configuratiestappen voor het Gunicorn-socketbestand opnieuw controleren.

  • connect() to unix:/run/gunicorn.sock failed (13: Permission denied)

Dit geeft aan dat Nginx geen verbinding kon maken met de Gunicorn-socket vanwege machtigingsproblemen. Dit kan gebeuren als het proces is uitgevoerd als de root-gebruiker in plaats van een sudo-gebruiker. Hoewel systemd gunicorn.sock succesvol heeft gegenereerd, kan Nginx deze niet gebruiken.

Een mogelijke boosdoener kan beperkte machtigingen zijn tussen de hoofdmap (/) en het gunicorn.sock bestand. Controleer de machtigingen en het eigendom van het socketbestand en elk van de bovenliggende mappen:

De eerste kolom beschrijft de bestandsmachtigingen. De tweede kolom beschrijft de eigenaar-gebruiker en de derde kolom de eigenaar-groep. Als een van de mappen die leiden naar gunicorn.sock geen juiste lees- en uitvoermachtigingen heeft, zal Nginx geen toegang kunnen krijgen tot de socket.

  • Django toont “could not connect to the server: Connection refused”

Dit geeft aan dat Django geen verbinding kon maken met de PostgreSQL-server. Zorg ervoor dat de PostgreSQL-server actief is en draait:

Als het niet actief is, voer dan de volgende commando's uit om het te starten en in te schakelen:

sudo systemctl enable postgresql

Als u deze foutmelding nog steeds krijgt, controleer dan of de database-inloggegevens correct zijn gedefinieerd onder settings.py:

Meer probleemoplossing

Voor aanvullende probleemoplossing zijn er verschillende logs beschikbaar. Deze logs kunnen helpen om de oorzaken van de problemen te achterhalen.

Hier is een lijst met logs die kunnen helpen:

  • Nginx-logs
  • Toegangslogs-Nginx
  • Foutlogs-Nginx
  •  Applicatielogs-Gunicorn
  •  Socketlogs-Gunicorn
Na het bijwerken van de configuratie of applicatie moet u mogelijk de processen herstarten om de wijzigingen toe te passen. Als de Django-applicatie is bijgewerkt, herstart dan het Gunicorn-proces om de wijzigingen door te voeren:
Als er wijzigingen zijn aangebracht in de Gunicorn-socket- of servicebestanden, herlaad dan de daemon en herstart de processen:
Als er wijzigingen zijn aangebracht in de Nginx-serverblokconfiguratie, moet deze worden getest voordat deze in gebruik wordt genomen. Ook moet Nginx opnieuw worden opgestart:

Tot slot

Deze handleiding laat succesvol zien hoe u de basis legt voor Django. Django biedt veel van de veelvoorkomende componenten van een webapplicatie, zodat u zich kunt concentreren op de unieke elementen. Het Django-project zal binnen de virtuele omgeving draaien. Gunicorn beheert de communicatie tussen clientverzoeken en Django. Tot slot fungeert Nginx als een reverse proxy voor het afhandelen van clientverbindingen.

Veel plezier met computeren!

author

Hark Labs

Auteur · CloudSigma

Preslav Dobrev is een creatief ontwerper bij CloudSigma, met de nadruk op een consistente bedrijfsidentiteit door middel van traditionele en innovatieve marketingkanalen. Hij is bedreven in het samenvoegen van artistieke visie met strategische marketing om impactvolle merkverhalen te creëren.

Reacties

Nog geen reacties. Wees de eerste.