gwift-book/source/part-2-deployment/centos+debian.adoc

9.4 KiB
Raw Blame History

Déploiement sur CentOS

yum update
groupadd --system webapps (1)
groupadd --system gunicorn_sockets (2)
useradd --system --gid webapps --shell /bin/bash --home /home/gwift gwift (3)
mkdir -p /home/gwift (4)
chown gwift:webapps /home/gwift (5)
  1. On ajoute un groupe intitulé webapps

  2. On crée un groupe pour les communications via sockets

  3. On crée notre utilisateur applicatif; ses applications seront placées dans le répertoire /home/gwift

  4. On crée le répertoire home/gwift

  5. On pourrait sans doute fusioner les étapes 3, 4 et 5.

Installation des dépendances systèmes

La version 3.6 de Python se trouve dans les dépôts officiels de CentOS. Si vous souhaitez utiliser une version ultérieure, il suffit de linstaller en parallèle de la version officiellement supportée par votre distribution.

Pour CentOS, vous avez donc deux possibilités :

yum install python36 -y

# CentOS 7 ne dispose que de la version 3.7 d'SQLite. On a besoin d'une version 3.8 au minimum:
wget https://kojipkgs.fedoraproject.org//packages/sqlite/3.8.11/1.fc21/x86_64/sqlite-devel-3.8.11-1.fc21.x86_64.rpm
wget https://kojipkgs.fedoraproject.org//packages/sqlite/3.8.11/1.fc21/x86_64/sqlite-3.8.11-1.fc21.x86_64.rpm
sudo yum install sqlite-3.8.11-1.fc21.x86_64.rpm sqlite-devel-3.8.11-1.fc21.x86_64.rpm -y

Ou passer par une installation alternative:

sudo yum -y groupinstall "Development Tools"
sudo yum -y install openssl-devel bzip2-devel libffi-devel

wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tgz
cd Python-3.8*/
./configure --enable-optimizations
sudo make altinstall (1)
  1. Attention ! Le paramètre altinstall est primordial. Sans lui, vous écraserez linterpréteur initialement supporté par la distribution, et cela pourrait avoir des effets de bord non souhaités.

Préparation de lenvironnement utilisateur

su - gwift
cp /etc/skel/.bashrc .
cp /etc/skel/.bash_profile .
ssh-keygen
mkdir bin
mkdir .venvs
mkdir webapps
python3.6 -m venv .venvs/gwift
source .venvs/gwift/bin/activate
cd /home/gwift/webapps
git clone ...

La clé SSH doit ensuite être renseignée au niveau du dépôt, afin de pouvoir y accéder.

A ce stade, on devrait déjà avoir quelque chose de fonctionnel en démarrant les commandes suivantes:

# en tant qu'utilisateur 'gwift'

source .venvs/gwift/bin/activate
pip install -U pip
pip install -r requirements/base.txt
pip install gunicorn
cd webapps/gwift
gunicorn config.wsgi:application --bind localhost:3000 --settings=config.settings_production

Configuration de lapplication

SECRET_KEY=<set your secret key here> (1)
ALLOWED_HOSTS=*
STATIC_ROOT=/var/www/gwift/static
DATABASE= (2)
  1. La variable SECRET_KEY est notamment utilisée pour le chiffrement des sessions.

  2. On fait confiance à django_environ pour traduire la chaîne de connexion à la base de données.

Création des répertoires de logs

mkdir -p /var/www/gwift/static

Création du répertoire pour le socket

Dans le fichier /etc/tmpfiles.d/gwift.conf:

D /var/run/webapps 0775 gwift gunicorn_sockets -

Suivi de la création par systemd :

systemd-tmpfiles --create

Gunicorn

#!/bin/bash

# defines settings for gunicorn
NAME="gwift"
DJANGODIR=/home/gwift/webapps/gwift
SOCKFILE=/var/run/webapps/gunicorn_gwift.sock
USER=gwift
GROUP=gunicorn_sockets
NUM_WORKERS=5
DJANGO_SETTINGS_MODULE=config.settings_production
DJANGO_WSGI_MODULE=config.wsgi

echo "Starting $NAME as `whoami`"

source /home/gwift/.venvs/gwift/bin/activate
cd $DJANGODIR
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH

exec gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user $USER \
--bind=unix:$SOCKFILE \
--log-level=debug \
--log-file=-

Supervision, keep-alive et autoreload

Pour la supervision, on passe par Supervisor. Il existe dautres superviseurs,

yum install supervisor -y

On crée ensuite le fichier /etc/supervisord.d/gwift.ini:

[program:gwift]
command=/home/gwift/bin/start_gunicorn.sh
user=gwift
stdout_logfile=/var/log/gwift/gwift.log
autostart=true
autorestart=unexpected
redirect_stdout=true
redirect_stderr=true

Et on crée les répertoires de logs, on démarre supervisord et on vérifie quil tourne correctement:

mkdir /var/log/gwift
chown gwift:nagios /var/log/gwift

systemctl enable supervisord
systemctl start supervisord.service
systemctl status supervisord.service
● supervisord.service - Process Monitoring and Control Daemon
   Loaded: loaded (/usr/lib/systemd/system/supervisord.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2019-12-24 10:08:09 CET; 10s ago
  Process: 2304 ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf (code=exited, status=0/SUCCESS)
 Main PID: 2310 (supervisord)
   CGroup: /system.slice/supervisord.service
           ├─2310 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
           ├─2313 /home/gwift/.venvs/gwift/bin/python3 /home/gwift/.venvs/gwift/bin/gunicorn config.wsgi:...
           ├─2317 /home/gwift/.venvs/gwift/bin/python3 /home/gwift/.venvs/gwift/bin/gunicorn config.wsgi:...
           ├─2318 /home/gwift/.venvs/gwift/bin/python3 /home/gwift/.venvs/gwift/bin/gunicorn config.wsgi:...
           ├─2321 /home/gwift/.venvs/gwift/bin/python3 /home/gwift/.venvs/gwift/bin/gunicorn config.wsgi:...
           ├─2322 /home/gwift/.venvs/gwift/bin/python3 /home/gwift/.venvs/gwift/bin/gunicorn config.wsgi:...
           └─2323 /home/gwift/.venvs/gwift/bin/python3 /home/gwift/.venvs/gwift/bin/gunicorn config.wsgi:...
ls /var/run/webapps/

On peut aussi vérifier que lapplication est en train de tourner, à laide de la commande supervisorctl:

$$$ supervisorctl status gwift
gwift                            RUNNING    pid 31983, uptime 0:01:00

Et pour gérer le démarrage ou larrêt, on peut passer par les commandes suivantes:

$$$ supervisorctl stop gwift
gwift: stopped
root@ks3353535:/etc/supervisor/conf.d# supervisorctl start gwift
gwift: started
root@ks3353535:/etc/supervisor/conf.d# supervisorctl restart gwift
gwift: stopped
gwift: started

Ouverture des ports

et 443 (HTTPS).
firewall-cmd --permanent --zone=public --add-service=http (1)
firewall-cmd --permanent --zone=public --add-service=https (2)
firewall-cmd --reload
  1. On ouvre le port 80, uniquement pour autoriser une connexion HTTP, mais qui sera immédiatement redirigée vers HTTPS

  2. Et le port 443 (forcément).

Installation dNginx

yum install nginx -y
usermod -a -G gunicorn_sockets nginx

On configure ensuite le fichier /etc/nginx/conf.d/gwift.conf:

upstream gwift_app {
        server unix:/var/run/webapps/gunicorn_gwift.sock fail_timeout=0;
}

server {
        listen 80;
        server_name <server_name>;
        root /var/www/gwift;
        error_log /var/log/nginx/gwift_error.log;
        access_log /var/log/nginx/gwift_access.log;

        client_max_body_size 4G;
        keepalive_timeout 5;

        gzip on;
        gzip_comp_level 7;
        gzip_proxied any;
        gzip_types gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;


        location /static/ { (2)
                access_log off;
                expires 30d;
                add_header Pragma public;
                add_header Cache-Control "public";
                add_header Vary "Accept-Encoding";
                try_files $uri $uri/ =404;
        }

        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; (3)
                proxy_set_header Host $http_host;
                proxy_redirect off;

                proxy_pass http://gwift_app;
        }
}
  1. Ce répertoire sera complété par la commande collectstatic que lon verra plus tard. Lobjectif est que les fichiers ne demandant aucune intelligence soit directement servis par Nginx. Cela évite davoir un processus Python (relativement lent) qui doive être instancié pour servir un simple fichier statique.

  2. Afin déviter que Django ne reçoive uniquement des requêtes provenant de 127.0.0.1

Déploiement sur Debian

Installation des dépendances systèmes

Préparation de lenvironnement utilisateur

Configuration de lapplication

Création des répertoires de logs

Création du répertoire pour le socket

Gunicorn

Supervision, keep-alive et autoreload

Ouverture des ports

Installation dNginx

Configuration des sauvegardes

Les sauvegardes ont été configurées avec borg: yum install borgbackup.

Cest lutilisateur gwift qui sen occupe.

mkdir -p /home/gwift/borg-backups/
cd /home/gwift/borg-backups/
borg init gwift.borg -e=none
borg create gwift.borg::{now} ~/bin ~/webapps

Et dans le fichier crontab :

0 23 * * * /home/gwift/bin/backup.sh

Rotation des jounaux

/var/log/gwift/* {
        weekly
        rotate 3
        size 10M
        compress
        delaycompress
}

Puis on démarre logrotate avec # logrotate -d /etc/logrotate.d/gwift pour vérifier que cela fonctionne correctement.