From c8e450f377b5d2125fc74baea9e1a3a25150658a Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Mon, 11 Oct 2021 10:37:20 +0200 Subject: [PATCH] Document installation in production --- README.md | 64 ++++++++++++++++++++++++++++++++++++++++++- docs/nginx_photos | 49 +++++++++++++++++++++++++++++++++ docs/uwsgi_photos.ini | 21 ++++++++++++++ 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 docs/nginx_photos create mode 100644 docs/uwsgi_photos.ini diff --git a/README.md b/README.md index 9b2e920..563db0c 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,69 @@ accessible depuis l'ensemble de votre réseau, pratique pour tester le rendu de la note sur un téléphone ! ## Installation d'une instance de production -TODO + +**En production on souhaite absolument utiliser les modules Python packagées +dans le gestionnaire de paquet.** Cela permet de mettre à jour facilement les +dépendances critiques telles que Django. L'installation d'une instance de +production néccessite **une installation de Debian Bullseye**. + +1. **Installation des dépendances APT.** + On tire les dépendances le plus possible à partir des dépôts de Debian. + + ``` + $ sudo apt install nginx git gettext uwsgi python3-venv \ + python3-certbot-nginx python3-django python3-django-crispy-forms \ + python3-django-taggit python3-pil python3-exifread + ``` + +2. **Clonage du dépot dans `/var/www/photos/photo21`** + + ``` + # on se place dans /var/www/photos/ + $ sudo git clone https://gitlab.crans.org/bde/photo21.git && cd photo21 + $ sudo mkdir static media + $ sudo chown www-data:www-data -R static media + $ sudo chmod g+rwx -R static media + ``` + +3. **Création d'un environment de travail Python décorrélé du système.** + + ```bash + $ python3 -m venv venv --system-site-packages + $ source venv/bin/activate # entrer dans l'environnement + (env)$ pip3 install -r requirements.txt + (env)$ deactivate # sortir de l'environnement + ``` + + +4. **Configuration de UWSGI et NGINX.** + + ```bash + $ sudo cp docs/uwsgi_photos.ini /etc/uwsgi/apps-available/uwsgi_photos.ini + $ sudo ln -s /etc/uwsgi/apps-available/uwsgi_photos.ini /etc/uwsgi/apps-enabled/ + $ sudo cp docs/nginx_photos /etc/nginx/sites-available/photos.crans.org + $ sudo ln -s /etc/nginx/sites-available/photos.crans.org /etc/nginx/sites-enabled/ + ``` + +5. **Base de données.** + En production on utilise PostgreSQL. + + ```bash + $ sudo apt install postgresql postgresql-contrib + $ sudo -u postgres psql + postgres=# CREATE USER photo21 WITH PASSWORD 'un_mot_de_passe_sur'; + postgres=# CREATE DATABASE photo21 OWNER photo21; + ``` + +6. **Migrations et collecte des fichiers statiques**, + + ``` + $ sudo -u www-data ./venv/bin/python ./manage.py collectstatic + $ sudo -u www-data ./venv/bin/python ./manage.py check + $ sudo -u www-data ./venv/bin/python ./manage.py migrate + ``` + +7. *Enjoy \o/* ## Documentation diff --git a/docs/nginx_photos b/docs/nginx_photos new file mode 100644 index 0000000..ef3f65c --- /dev/null +++ b/docs/nginx_photos @@ -0,0 +1,49 @@ +server { + listen 80; + listen [::]:80; + server_name photos.crans.org; + location / { + return 302 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + + server_name photos.crans.org; + + # Keep the TCP connection open a bit for faster browsing + keepalive_timeout 70; + + ssl_certificate /etc/letsencrypt/live/photos.crans.org/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/photos.crans.org/privkey.pem; + ssl_session_timeout 1d; + ssl_session_cache shared:MozSSL:10m; + ssl_session_tickets off; + ssl_dhparam /etc/letsencrypt/dhparam; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + + # Enable OCSP Stapling, point to certificate chain + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate /etc/letsencrypt/live/photos.crans.org/chain.pem; + + error_log /var/log/nginx/photos.crans.org_error.log; + access_log /var/log/nginx/photos.crans.org_access.log; + + # Django statics and media + location /media { + alias /var/www/photos/photo21/media; + } + location /static { + alias /var/www/photos/photo21/static; + } + + location / { + uwsgi_pass unix:///var/www/photos/photos21/photos21.sock; + include /etc/nginx/uwsgi_params; + } +} diff --git a/docs/uwsgi_photos.ini b/docs/uwsgi_photos.ini new file mode 100644 index 0000000..644217e --- /dev/null +++ b/docs/uwsgi_photos.ini @@ -0,0 +1,21 @@ +[uwsgi] +# www-data can write media +uid = www-data +gid = www-data +# Django-related settings +# the base directory (full path) +chdir = /var/www/photos/photo21 +# the virtualenv (full path) +home = /var/www/photos/photo21/venv +wsgi-file = /var/www/photos/photo21/photo21/wsgi.py +plugin = python3 +# process-related settings +master = true +# maximum number of worker processes +processes = 10 +# the socket (use the full path to be safe +socket = /var/www/photos/photos21/photos21.sock +# ... with appropriate permissions - may be needed +chmod-socket = 664 +# clear environment on exit +vacuum = true