Django
Das open-source Webframework Django ist in Python geschrieben und wird von der Django Software Foundation betreut. Es folgt dem Model View Presenter (MVP) Paradigma.
Wie schon erwähnt werden wir mit dem python3-venv
Modul eine virtuelle Umgebung anlegen, um die Applikation darin zu kapseln. So können mehrere Django Installationen unabhängig voneinander laufen, ohne dass sie oder deren Abhängigkeiten sich gegenseitig beeinflussen.
Als Datenbank verwenden wir PostgreSQL.
Das Projektverzeichnis ist in meinem Beispiel /var/www/com.linuxserversetup.dev
.
Nächsten Schritte:
Virtuelle Umgebung erstellen
Eine virtuelle Umgebung erstellen wir mit dem Befehl python3
gefolgt von dem Parameter -m
(Modul Name), also venv
und einem Ordnernamen oder einem Pfad:
__$ python3 -m venv /var/www/com.linuxserversetup.dev/vm1
Der Ordner vm1
wird automatisch angelegt und darin auch weitere Ordner und Dateien.
Schauen wir kurz nach:
__$ ls -la /var/www/com.linuxserversetup.dev/vm1
Ausgabe:
drwxrwxr-x 6 tom tom 4096 Jan 4 13:08 .
drwxr-xr-x 7 tom tom 4096 Jan 3 20:52 ..
drwxrwxr-x 2 tom tom 4096 Jan 4 13:08 bin
drwxrwxr-x 2 tom tom 4096 Jan 4 13:08 include
-rw-rw-r-- 1 tom tom 143 Jan 3 20:05 index.htm
drwxrwxr-x 3 tom tom 4096 Jan 4 13:08 lib
lrwxrwxrwx 1 tom tom 3 Jan 4 13:08 lib64 -> lib
-rw-rw-r-- 1 tom tom 70 Jan 4 13:08 pyvenv.cfg
drwxrwxr-x 3 tom tom 4096 Jan 4 13:08 share
Virtuelle Umgebung starten und deaktivieren
Aktivieren
Der Befehl activate
wurde in dem Unterverzeichnis bin
als ausführbare Datei angelegt. Um in der virtuellen Umgebung arbeiten zu können, muss sie erst gestartet werden:
__$ source /var/www/com.linuxserversetup.dev/vm1/bin/activate
Nach der Aktivierung erscheint der Name der virtuellen Umgebung in Klammern vor dem Benutzernamen:
(vm1) tom@srv1:~$
Deaktivieren
Im aktivierten Zustand kann die virtuelle Umgebung mit dem Befehl deactivate
beendet bzw. verlassen werden:
(vm1) tom@srv1:~$ deactivate
Die Symbolik für den aktivierten Zustand (vm1) tom@srv1:~$
lasse ich von nun an weg, damit die Befehle ohne Aufwand kopiert werden können!
Django installieren
Für die Installation von Django müssen wir uns in einer aktivierten virtuellen Umgebung befinden:
__$ source /var/www/com.linuxserversetup.dev/vm1/bin/activate
Für die Installation benötigen wir die Paketverwaltung pip, was wir schon auf dieser Python, pip, PostgreSQL installiert hatten.
Im aktivierten Zustand installieren wir die neueste Version von Django:
__$ python3 -m pip install django
Wir können eine Modulliste mit freeze
erstellen lassen. Ohne Angabe eines Dateinamens wird die Datei requirements.txt
erzeugt. Um eine optische Zuordnung zur virtuellen Umgebung erkennbar zu machen, gebe ich den Dateinamen vm1.pip
vor:
__$ python3 -m pip freeze > /var/www/com.linuxserversetup.dev/vm1.pip
Diese Datei liegt nun neben dem Ordner mit der virtuellen Umgebung:
__$ ls -la /var/www/com.linuxserversetup.dev
Ausgabe:
drwxrwxr-x 3 tom tom 4096 Jan 4 14:59 .
drwxr-xr-x 7 tom tom 4096 Jan 3 20:52 ..
drwxrwxr-x 7 tom tom 4096 Jan 4 15:00 vm1
-rw-rw-r-- 1 tom tom 69 Jan 4 14:59 vm1.pip
Lassen wir uns noch kurz den Inhalt von vm1.pip
ausgeben:
__$ less /var/www/com.linuxserversetup.dev/vm1.pip
Installierte Module und Abhängigkeiten der Django Applikation (erstellt mit freeze
):
/var/www/com.linuxserversetup.dev/vm1.pip
asgiref==3.4.1
backports.zoneinfo==0.2.1
Django==4.0
sqlparse==0.4.2
Django wäre damit in der virtuellen Umgebung installiert, aber noch nicht lauffähig. Dazu müssen wir erst ein Django Projekt erstellen.
Django Projekt erzeugen
Django stellt ein paar Python Skripte zur Verfügung, die uns helfen eine Django Instanz zu erzeugen. Wir bekommen dadurch eine Verzeichnisstruktur und Konfigurationsdateien, die wir Schritt für Schritt editieren werden.
Wechseln wir der Einfachheit halber mit cd
in das entsprechende Verzeichnis:
__$ cd /var/www/com.linuxserversetup.dev/vm1
Die Shell nach dem Verzeichniswechsel:
tom@srv1:/var/www/com.linuxserversetup.dev/vm1$
Auch diese Vorzeichen tom@srv1:/var/www/com.linuxserversetup.dev/vm1$
aus der Shell lasse ich fortan weg!
Ein Projekt erstellen wir mit startproject
gefolgt von einem frei zu wählenden Instanznamen. In meinem Fall app1
:
__$ django-admin startproject app1
Das hat uns den Ordner app1
erzeugt. Schauen wir kurz hinein:
__$ ls -la app1
Inhalt von /var/www/com.linuxserversetup.dev/vm1/app1
:
drwxrwxr-x 2 tom tom 4096 Jan 4 15:00 app1
-rwxrwxr-x 1 tom tom 660 Jan 4 15:00 manage.py
Werfen wir auch einen Blick in den Ordner app1/app1
:
__$ ls -la app1/app1
Inhalt von /var/www/com.linuxserversetup.dev/vm1/app1/app1
:
-rw-rw-r-- 1 tom tom 385 Jan 4 15:00 asgi.py
-rw-rw-r-- 1 tom tom 0 Jan 4 15:00 __init__.py
-rw-rw-r-- 1 tom tom 3213 Jan 4 15:00 settings.py
-rw-rw-r-- 1 tom tom 746 Jan 4 15:00 urls.py
-rw-rw-r-- 1 tom tom 385 Jan 4 15:00 wsgi.py
ALLOWED_HOSTS konfigurieren
In der settings.py
im Abschnitt ALLOWED_HOSTS
müssen wir den Domainnamen und die interne Adresse hinterlegen:
__$ nano /var/www/com.linuxserversetup.dev/vm1/app1/app1/settings.py
Dieser Abschnitt sieht bei mir dann so aus:
Auszug von /var/www/com.linuxserversetup.dev/vm1/app1/app1/settings.py
. . .
ALLOWED_HOSTS = ['127.0.0.1', 'dev.linuxserversetup.com']
. . .
Speichern und schließen (STRG+s
, STRG+x
).
Datenbank konfigurieren
Für die Unterstützung von PostgreSQL benötigt Django das Modul Psycopg. Wir installieren den Adapter mit pip:
__$ pip install psycopg2-binary
Anschließend editieren wir die settings.py
im Abschnitt DATABASES
:
__$ nano /var/www/com.linuxserversetup.dev/vm1/app1/app1/settings.py
Und geben die Verbindungsdaten zu unserer PostgreSQL Datenbank ein. Dieser Abschnitt sollte dann so aussehen:
Auszug von /var/www/com.linuxserversetup.dev/vm1/app1/app1/settings.py
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'django_db',
'USER': 'tom',
'Password': 'tom123',
'HOST': 'localhost',
'PORT': '5432',
}
}
. . .
Speichern und schließen (STRG+s
, STRG+x
).
Django Instanz testen
Mit dem Skript manage.py
können wir die Django App starten und die bisherige Konfiguration überprüfen. Falls die virtuelle Umgebung zwischenzeitlich deaktivert wurde, kannst Du sie mit (source bin/activate
) wieder aktivieren.
__$ python app1/manage.py runserver
Ausgabe:
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
January 20, 2022 - 20:50:57
Django version 4.0, using settings 'app1.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Du solltest die Meldung System check identified no issues (0 silenced)
sehen, denn die besagt, dass es zu keinem unerwarteten Systemfehler gekommen ist. Es sind allerdings Bestandteile des Webframeworks noch nicht in die Datenbank migriert worden (unapplied migration(s)
). Das erledigen wir im nächsten Abschnitt. Vorher beenden wir den Dienst mit STRG+c
.
Daten migrieren
Wir führen erneut manage.py
mit dem Parameter migrate
aus:
__$ python app1/manage.py migrate
Ausgabe:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
Jetzt sollte der Django Dienst korrekt laufen. Wir starten den Dienst erneut:
__$ python app1/manage.py runserver
Die Ausgabe sollte dann so aussehen:
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
January 20, 2022 - 21:20:24
Django version 4.0, using settings 'app1.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Django läuft jetzt als interner Dienst auf 127.0.0.1:8000
. Als nächstes müssen wir unseren Nginx Server (Reverse Proxy) dahin kommunizieren lassen.
Nginx für Django konfigurieren
Den Nginx Serverblock für die Subdomain dev.linuxserversetup.com
hatten wir bereits in dem Kapitel Subdomain Server Block (dev) angelegt.
Nginx ist an dieser Stelle dafür verantwortlich HTTPS zu erzwingen und die Verbindung für die Subdomain zu verschlüsseln. Nun müssen wir den Server Block so abändern, dass die Kommunikation über die Domain zum Django Dienst hin- und auch zurückgeleitet wird.
__$ sudo nano /etc/nginx/sites-available/com.linuxserversetup.dev.conf
Die Nginx Konfiguration soll schließlich so aussehen:
/etc/nginx/sites-available/com.linuxserversetup.dev.conf
# force https
server {
listen 80;
server_name dev.linuxserversetup.com;
return 301 https://$server_name$request_uri;
}
# main block
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name dev.linuxserversetup.com;
root /var/www/com.linuxserversetup.dev/;
index index.htm;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header x-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Referer $http_referer;
proxy_pass_header content-security-policy;
}
ssl_certificate /etc/letsencrypt/live/dev.linuxserversetup.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dev.linuxserversetup.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/dev.linuxserversetup.com/chain.pem;
# dhparam
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# HSTS
add_header Strict-Transport-Security "max-age=31536000";
}
Es wurde hauptsächlich der location
Block geändert. Einige Proxy Direktiven sind dort hinzugekommen. Ganz entscheidend ist hier proxy_pass http://127.0.0.1:8000
.
Damit die Konfiguration von Nginx übernommen wird, überprüfen wir die neuen Einstellungen und starten den Dienst neu:
__$ sudo nginx -t
__$ sudo systemctl restart nginx
Wenn die Nginx Konfiguration in Ordnung ist, sollte diese Rückmeldung kommen:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Django App starten und testen
Wir starten die Django App erneut:
__$ python app1/manage.py runserver
Jetzt können wir die Domain dev.linuxserversetup.com
über einen Browser aufrufen und es sollte die Django Debug Seite erscheinen.
Virtuelle Umgebung löschen
Wie eine venv Umgebung gelöscht wird, soll hier nur der Vollständigkeit halber erwähnt werden.
Falls noch aktiviert, verlassen wir die virtuelle Umgebung deactivate
:
__$ deactivate
Anschließend genügt es den Ordner mit rm
zu löschen:
__$ rm -rf /var/www/com.linuxserversetup.dev/vm1