NGINX als Reverse Proxy - Django in Produktion Teil 6
Published: 2024-05-29 21:22:45

## Vorwort
Jetzt, da unsere App mit Gunicorn als Applikations - Server läuft, müssen wir sie nur noch über nginx in das Öffentliche Internet bringen. nginx wird unsere Statischen Dateien bereitstellen, und alles andere als reverse proxy an Gunicorn weiterleiten. nginx wird von Firmen wie Netflix und Dropbox genutzt um Seiten mit vielen Besuchern online zu halten. Ebenso werden wir unsere https - Verschlüsselung mit certbot aufbauen.

## nginx Set-Up 
Zuerst kannst du nun nginx installieren.

```
sudo apt install nginx
sudo service enable nginx
sudo service start nginx
```

Hier liegt die Konfigurationsdatei für nginx:
```
cat /etc/nginx/nginx.conf
```
Dort sind alle wichtigen Einstellungen. Jetzt kannst du auf deine Domain gehen, dort solltest du nun von der Standard nginx - Webseite begrüßt werden. Hurra! dein Server ist nun offiziell im offenen Internet erreichbar.

## optional - nginx config als softlink
Um die Änderungen in deine Konfiguration zu speichern, kannst du die config - Datei bei dir in deine git - repository einchecken. Bei einer Produktiven Website am besten nicht 'public', also für alle einsehbar machen. Falls deine git - repo public ist, erstelle dir eine neue repo mit deinen Konfigurationsdateien. Nach dem einchecken kannst du einen Softlink von deiner Repo zur config - Datei erstellen. So kann sich nginx immer die Updates von deiner Repository holen.
```
cp /etc/nginx/nginx.conf srv/www/meine_app/produktion/nginx.conf
git commit -m "nginx.conf" && git push

rm /etc/nginx/nginx.conf
ln -s /srv/www/meine_app/produktion/nginx.conf /etc/nginx/nginx.conf

# Deine Datei kann nun in deiner repository geupdated werden:
ls -l /etc/nginx/nginx.conf
lrwxrwxrwx 1 root root 40 May 29 20:48 /etc/nginx/nginx.conf -> /srv/www/meine_app/produktion/nginx.conf
```


## certbot Set-Up
Um deine Web - App mit https zu verschlüsseln, brauchst du ein Zertifikat. Ein kostenloses Zertifikat bekommst du von Let's encrypt. Diese Zertifikat läuft aber nach 12 Monaten ab, deswegen nutzen wir `certbot` um das Zertifikat automatisch alle 12 Monate zu erneuern.

**So kannst du certbot auf Debian installieren:**

```
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx
```

Jetzt sollte certbot deine `nginx.conf` angepasst haben. Schau dir die Änderungen mit `git status` an
```
cd /srv/www/meine_app
git status
git add produktion/nginx.conf
git commit -m "certbot setup"
```
[Falls du eine andere Architektur benutzt, kannst du hier auf certbots Webseite mehr Infos bekommen.](https://certbot.eff.org/instructions)

## Weitere nginx.conf Anpassungen.
Das ganze ist aber noch nicht genug. Jetzt musst du deine .conf für den launch vorbereiten. Das ganze sieht dann etwa so aus:

```
worker_processes 1;
user www-data;

# Hier sind deine error logs - für alle Zugriffe gibt es auch ein access.log am gleichen Ort:
error_log  /var/log/nginx/error.log info;
pid /var/run/nginx.pid;

# events kannst du so lassen:
events {
  worker_connections 1024; # increase if you have lots of clients
  accept_mutex off; # set to 'on' if nginx worker_processes > 1
}


# Mehrere Voreinstellungen für django:
http {
  include mime.types;
  # fallback in case we can't determine a type
  default_type application/octet-stream;
  access_log /var/log/nginx/access.log combined;
  sendfile on;

  upstream app_server {
    # fail_timeout=0 means we always retry an upstream even if it failed
    # to return a good HTTP response

    # for UNIX domain socket setups
    server unix:/tmp/gunicorn.sock fail_timeout=0;
  }


# Das ist dein HTTP - Server:
  server {
    listen 80;

    server_name meine_domain.de;

    return 301 https://$server_name$request_uri;
  }

  # Das ist dein HTTPS - Server:
  server {

    listen 443 ssl;
    client_max_body_size 75M;

    server_name meine_domain.de;

    # Hier sind deine ssl - Zertifikate, die du dir mit certbot geholt hast:
    ssl_certificate     /etc/letsencrypt/live/meine_domain.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/meine_domain.de/privkey.pem;

    keepalive_timeout 5;

    # Hier sind deine Statischen Dateien. Sie werden in Produktion 
    # direkt von nginx gehosted. In deinen django settings 
    # musst du STATIC_ROOT = "/srv/www/static" hinzufügen
    location /static {
        alias /srv/www/static;
    }

    # Das hier ist deine Proxy - Server Weiterleitung. Dein lokaler 
    # Gunicorn wird so an das offene Internet weitergeleitet. 
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # Hier kanst du deine error - Seiten bereitstellen. Da diese 
    # Statisch sind, werden sie direkt von nginx bereitgestellt
    error_page 500 502 503 504 /500.html;
    location = /500.html {
      root /srv/www/meine_repository/meine_app/static;
    }

  }
}
```

## Starte deine Webapp mit Gunicorn
Jetzt fehlt nur noch eine Sache, deine eigene App!
Du kannst sie, wie beim letzten mal - mit Gunicorn starten.
```
# Exportiere dein Produktions - env, damit deine Richtigen Einstellungen geladen werden.
export ENV_NAME=production

# Starte dein Gunicorn - Die Applikation befindet sich im venv in deiner Repository
# Deine .wsgi ist im Verzeichnis deiner App
# und mit -b kannst du deine lokale ip bestimmen - Diese leitest du an nginx weiter.
/srv/www/meine_repository/venv/bin/gunicorn /srv/www/meine_repository/meine_app/meine_app.wsgi -b 127.0.0.1:8000
```

Lade deine neue Konfiguration:
```
sudo systemctl daemon-reload
sudo systemctl restart nginx.service
```


Jetzt solltest du deinen Browser öffnen und unter deiner domain deine App sehen können!

Im nächsten Teil werden wir deine .service Dateien für systemd anlegen, damit auch nach einem `reboot` alle deine wichtigen Applikationen laufen.

PS: Viel Spaß beim Coden,
Dein Ruben

[Mein Blog](rubenvoss.de)