6a. Deploiement - Yolino/t211-dbox-fm GitHub Wiki

Résumé coaching 6.a

+ Le groupe a pu mettre en ligne l'application développée dans son état actuel.
+ Le groupe peut expliquer ce qu'il a dû faire pour héberger et déployer, et justifier les choix. 

+ Le groupe présente sur le wiki le choix qui a été posé pour héberger l'application web : fournisseur, configuration matérielle, prix, garantie, plateforme logicielle, …
+ Le groupe présente sur le wiki la configuration du serveur utilisée et la justifie. 
+ Les étudiants présentent sur le wiki la manière dont le code est déployé en production : moment, étapes, outils et protocoles utilisés, …  
+ Le groupe explique dans le wiki l'automatisation (CI/CD) qui aurait été mis en place.

1. Choix du serveur d'hébergement

Le serveur choisi est un des VPS fourni pour le cours d'administration système et réseaux II. Le VPS possède un coeur virtuel, 20 Go de stockage, hébergé chez OVH.

2. Technique de déploiement

2.1 Staging

Lorsqu'on souhaite passer les nouvelles fonctionnalités en production, on les place d'abord en staging. Pour cela, il est nécessaire d'appliquer un merge entre les branches de développement et de staging :

git checkout staging
git merge develop

Peu de conflits devraient être à déclarer, mais si nécessaire, ils doivent être résolus manuellement. Une fois le merge effectué, nous disposons d'une infrastructure Docker alternative disponible dans le compose.yaml de la branche staging. Nous n'avons qu'à la démarrer avec la commande docker compose up --build. Nous aurons donc accès à nginx, qui aura compilé les fichiers React, et sera disponible sur le port 80, faisant appel au conteneur backend exposant Gunicorn, qui servira de point d'entrée (WSGI) vers l'application Django. La base de données est intacte (si ce n'est que le conteneur est différent, et ne contient donc pas les mêmes données).

Si le site web et ses nouvelles fonctionnalités sont correctement servies sur le port HTTP, nous pouvons figer les conteneurs en de nouvelles images, et les rendre disponibles sur le repository Docker Hub :

docker commit dbox-frontend-prod slyven/dbox:frontend-x.y.z
docker commit dbox-backend-prod slyven/dbox:backend-x.y.z
docker commit dbox-db-prod slyven/dbox:db-x.y.z
docker push slyven/dbox:frontend-x.y.z
docker push slyven/dbox:backend-x.y.z
docker push slyven/dbox:db-x.y.z

NB : Il peut être nécessaire de se connecter à son compte Docker grâce à docker login.

2.2 Production

Une fois les nouvelles images des conteneurs disponibles sur Docker Hub, nous pouvons nous connecter en SSH sur le VPS de déploiement et récupérer les images :

docker pull slyven/dbox:frontend-x.y.z
docker pull slyven/dbox:backend-x.y.z
docker pull slyven/dbox:pull-x.y.z

Ensuite, il suffit de modifier le tag des images dans les fichiers Dockerfile et compose.yaml, et de relancer l'infrastructure Docker :

docker compose down
docker compose up --build -d

Le site est maintenant disponible avec les nouvelles fonctionnalités développées en amont.

NB : Dans notre cas, nous n'avons qu'un seul serveur de production, mais la branche prod nous permet de garder un tracking de l'infrastructure mise en place sur le serveur.

3. Automatisation (CI/CD)

3.1 Passage en production

Nous avons réfléchi au sujet d'automatiser la mise en production directement sur le VPS. Cependant, étant donné l'importance de la procédure, des conséquences dûes à des erreurs (mise hors ligne du site par exemple), comparées à la simplicité d'exécution amenée par la conteneurisation, notre décision finale fut de passer du staging à la production manuellement.

3.2 Génération de certificats SSL/TLS

Nous avons mis en oeuvre un système de génération automatisée de certificats Let's Encrypt via Certbot, et plus particulièrement sa version Docker. Pour cela, nous avons configurés deux bind mounts, disponibles dans le dossier ./certbot, reliés au conteneur nginx (en read-only pour récupérer et servir les certificats et les challenges ACME), et au conteneur certbot (en read-write pour générer les certificats et les challenges, et les placer sur le File System de l'hôte).

Lorsque le conteneur certbot est démarré, il analyse la validité du certificat, et s'il est nécessaire de le renouveler, va émettre les challenges ACME, qui seront placés dans le conteneur nginx par le biais des bind mounts. Ce dernier servira en HTTP ces challenges, comme indique ces lignes de configuration :

location /.well-known/acme-challenge/ {
  root /var/www/certbot;
  allow all;
  add_header Cache-Control "no-cache, no-store, must-revalidate";
}

Les challenges servis en HTTP vont être vérifiés par Let's Encrypt, et leur validation mènera à la signature d'un nouveau certificat, qui sera à son tour placé dans le conteneur nginx grâce à d'autres bind mounts.

Pour automatiser intégralement ce processus, nous avons défini un cron job, ayant pour but de lancer le conteneur certbot toutes les 6 heures :

0 */6 * * * cd /home/dev-3/t211-dbox-fm && docker run --rm -v $(pwd)/certbot/www:/var/www/certbot:rw -v $(pwd)/certbot/conf:/etc/letsencrypt:rw certbot/certbot renew --webroot -w /var/www/certbot --non-interactive >> /var/log/certbot-renewal.log 2>&1

Pour valider son fonctionnement, nous pouvons afficher le contenu du fichier de logs (après exécution manuelle ou par le cron job). Voici le résultat obtenu, nous confirmant une exécution fonctionnelle :

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/dbox-fm.be.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certificate not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certificates are not due for renewal yet:
  /etc/letsencrypt/live/dbox-fm.be/fullchain.pem expires on 2025-07-15 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

De cette façon, la génération de certificat SSL/TLS est entièrement automatisée. Une prochaine étape pourrait être d'implémenter une surveillance du fichier de logs par notre stack de monitoring, et avertir un administrateur si des problèmes se manifestent.