🦄 Gunicorn et Django#

🐍 Installation de Python#

sudo apt install python3-pip python3-dev libpq-dev curl
  • Environnement virtuel

sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.10-venv

mkdir ~/my_website
cd ~/my_website

python3.10 -m venv my_venv
source my_venv/bin/activate
python3.10 -m pip install --upgrade pip

💎 Installation de Django#

pip install django gunicorn psycopg2-binary
  • Créer un projet démo pour Django

django-admin startproject my_app ~/my_app
  • On modifie les hôtes acceptés par Django settings

import os
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']
  • On lie la base de données (attention il ne faut pas mettre ces données en clair, l’idéal est de tout passer en variables d’environnement), mais ici il s’agit juste d’une démonstration de principe

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'my_app',
        'USER': 'remi',
        'PASSWORD': 'XXXXXXXXXXX',
        'HOST': 'localhost',
        'PORT': '',
    }
}
  • Configuration du répertoire static, il faudra penser à configurer nginx pour directement distribuer ces fichiers

STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
  • Initialisation habituelle de Django

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py collectstatic
  • On ouvre le port correspondant dans le pare-feu

sudo ufw allow 8000
python manage.py runserver 0.0.0.0:8000

🦄 Configuration de Gunicorn#

cd ~/my_app
gunicorn --bind 0.0.0.0:8000 my_app.wsgi
  • Nous pouvons sortir de notre environnement virtuel

deactivate
sudo nano /etc/systemd/system/gunicorn.socket
[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target
  • On configure le service

sudo nano /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=spnet
Group=www-data
WorkingDirectory=/home/user_name/my_app
ExecStart=/home/user_name/my_app/my_venv/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          spnet.wsgi:application

[Install]
WantedBy=multi-user.target
  • Utilisation en tant que service ensuite

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
  • Verification du fichier de socket

sudo systemctl status gunicorn.socket
file /run/gunicorn.sock
sudo journalctl -u gunicorn.socket
sudo systemctl status gunicorn
curl --unix-socket /run/gunicorn.sock localhost

🗜 Nginx Proxy ➡ Gunicorn#

sudo nano /etc/nginx/sites-available/my_app
server {
    listen 80;
    listen [::]:80;
    server_name xxx.xxx.xxx.xxx;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/user_name/my_app;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled
  • On peut supprimer le site par défaut aussi

  • Si on veut une protection par passe (htpasswd)

sudo apt-get install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd remi

auth_basic "Area 51";
auth_basic_user_file /etc/nginx/.htpasswd; 
sudo nginx -t
sudo systemctl restart nginx
sudo ufw delete allow 8000
sudo ufw allow 80
sudo tail -F /var/log/nginx/error.log
sudo systemctl restart gunicorn
sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service
sudo systemctl start postgresql
sudo systemctl enable postgresql
sudo systemctl status postgresql
sudo nginx -t && sudo systemctl restart nginx
  • IP V6 sur Nginx (il suffit de rajouter) dans /etc/nginx/sites-available/myapp

# IPv4
listen :80;
# IPv6
listen [::]:80;

🔐 Ajout certificat SSL avec Let’s Encrypt#

  • Aucune difficulté particulière

sudo ufw allow 443
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d mon.site.fr