Continuing... :)

This commit is contained in:
Fred Pauchet 2022-01-05 16:32:45 +01:00
parent ea1f1e8925
commit bd9417f65a
14 changed files with 80 additions and 107 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

@ -1,62 +0,0 @@
== Intégration continue avec Jenkins
Le but de l'intégration est continue est de nous permettre de tester automatiquement notre développement chaque fois que le code est mis à jour et ainsi éviter les régressions.
Ceci nécessite de mettre à jour régulièrement les tests et d'utiliser un serveur d'intégration. Dans notre cas, nous allons utiliser jenkins.
Nous considérons aussi que le code est hébergé sur Gitlab.
=== Installation de Jenkins
Jenkins fournit des paquets d'installation pour presque tous les systèmes d'exploitation sur leur site: `https://jenkins-ci.org/ <https://jenkins-ci.org/>`_.
Par exemple, dans le cas de debian, il suffit de suivre les instructions sur `http://pkg.jenkins-ci.org/debian/ <http://pkg.jenkins-ci.org/debian/>`_
Comme nous utilisons git, il faut veiller à activer le plugin correspondant: `Git plugin <https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin>`_.
Ce dernier peut directement être installé depuis le panneau de gestion des plugins de jenkins.
=== Création d'un projet
Depuis la page principale de jenkins, on crée un nouveau projet en cliquant sur *Nouveau Item* et on donne un nom à notre nouveau projet:
.. image:: integration/jenkins_new_project.png
:align: center
Ensuite, on spécifie que le projet provient de git:
.. image:: integration/jenkins_git.png
:align: center
Finalement, on écrit le petit script permettant de lancer le build:
.. image:: integration/jenkins_build_script.png
:align: center
Et on sauve le tout.
=== Lien gitlab - jenkins
Pour que le build du projet que nous avons créé dans jenkins soit exécuté automatiquement, il est nécessaire d'autoriser le lancement du build via une url sur jenkins, cette dernière étant appelée depuis gitlab.
Dans jenkins, on se rend dans les propriétés du projet et on active le déclanchement du build à distance:
.. image:: integration/jenkins_build_with_url.png
:align: center
Attention à générer un jeton d'authentification suffisamment aléatoire pour éviter que n'importe qui ne lance le build. Par exemple avec uuid en python:
.. code-block:: python
>>> import uuid
>>> uuid.uuid4()
UUID('097e547c-08b4-4d4f-a8e8-2a1cf03b8463')
>>>
Ensuite, on crée un web hook dans gitlab:
.. image:: integration/gitlab_web_hook.png
:align: center
Voilà, à chaque push sur gitlab, jenkins lancera le build du projet et exécutera les tests associés.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View File

@ -12,3 +12,9 @@ ORM:: _Object Relational Mapper_, où une instance est directement (ou à proxim
PaaS:: _Platform as a Service_, qui consiste à proposer les composants d'une plateforme (Redis, PostgreSQL, ...) en libre service et disponibles à la demande (quoiqu'après avoir communiqué son numéro de carte de crédit...).
POO:: La _Programmation Orientée Objet_ est un paradigme de programmation informatique. Elle consiste en la définition et l'interaction de briques logicielles appelées objets ; un objet représente un concept, une idée ou toute entité du monde physique, comme une voiture, une personne ou encore une page d'un livre. Il possède une structure interne et un comportement, et il sait interagir avec ses pairs. Il s'agit donc de représenter ces objets et leurs relations ; l'interaction entre les objets via leurs relations permet de concevoir et réaliser les fonctionnalités attendues, de mieux résoudre le ou les problèmes. Dès lors, l'étape de modélisation revêt une importance majeure et nécessaire pour la POO. C'est elle qui permet de transcrire les éléments du réel sous forme virtuelle. https://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_objet[Wikipédia]
S3:: Amazon _Simple Storage Service_ consiste en un système d'hébergement de fichiers, quels qu'ils soient.
Il peut s'agir de fichiers de logs, de données applications, de fichiers média envoyés par vos utilisateurs, de vidéos et images ou de données de sauvegardes.
.https://aws.amazon.com/fr/s3/
image:images/amazon-s3-arch.png[]

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

View File

@ -39,12 +39,12 @@ L'idée du texte ci-dessous est de jeter les bases d'un bon développement, en s
Ces idées ne s'appliquent pas uniquement à Django et à son cadre de travail, ni même au langage Python.
Ces deux sujets sont cependant de bons candidats et leur cadre de travail est bien défini, documenté et suffisamment flexible.
Django se présente comme un "link:https://www.djangoproject.com/[Framework Web pour perfectionnistes ayant des deadlines]" et suit https://docs.djangoproject.com/en/dev/misc/design-philosophies/[ces quelques principes]:
Django se présente comme un _Framework Web pour perfectionnistes ayant des deadlines_ cite:[django] et suit ces quelques principes cite:[django_design_philosophies]:
* Faible couplage et forte cohésion, pour que chaque composant dispose de son indépendance,
* Plus de fonctionnalités avec moins de code,
* https://fr.wikipedia.org/wiki/Ne_vous_r%C3%A9p%C3%A9tez_pas[Don't repeat yourself],
* Rapidité du développement, après une petite courbe d'apprentissage un peu ardue.
* Faible couplage et forte cohésion, pour que chaque composant dispose de son indépendance, en n'ayant aucune connaissance des autres couches applicatives. Ainsi, le moteur de rendu ne connait absolument rien l'existence du moteur de base de données, tout comme le système de vues ne sait pas quel moteur de rendu est utilisé.
* Plus de fonctionnalités avec moins de code: chaque application Django doit utiliser le moins de code possible
* _Don't repeat yourself_, chaque concept ou morceau de code ne doit être présent qu'à un et un seul endroit de vos dépôts.
* Rapidité du développement, en masquant les aspects fastidieux du développement web actuel
Mis côte à côte, le suivi de ces principes permet une bonne stabilité du projet à moyen et long terme.
@ -83,12 +83,28 @@ A ce moment-là, pour peu que votre mémoire ait déjà entraperçu le terme, il
=== Pour aller plus loin
Il existe énormément de ressources, autant spécifiques à Django que plus généralistes.
Il ne sera pas possible de toutes les détailler; faites un tour sur https://duckduckgo.com, https://stackoverflow.com, https://ycombinator.com, https://lobste.rs/, https://lecourrierduhacker.com/ ou https://www.djangoproject.com/.
Il ne sera pas possible de toutes les détailler; faites un tour sur
* https://duckduckgo.com,
* https://stackoverflow.com,
* https://ycombinator.com,
* https://lobste.rs/,
* https://lecourrierduhacker.com/
* ou https://www.djangoproject.com/.
Restez curieux, ne vous enclavez pas dans une technologie en particulier et gardez une bonne ouverture d'esprit.
=== Conventions
NOTE: Les notes indiquent des anecdotes.
TIP: Les conseils indiquent des éléments utiles, mais pas spécialement indispensables.
IMPORTANT: Les notes importantes indiquent des éléments à retenir.
CAUTION: Ces éléments indiquent des points d'attention. Les retenir vous fera gagner du temps en débuggage.
WARNING: Les avertissements indiquent un (potentiel) danger ou des éléments pouvant amener des conséquences pas spécialement sympathiques.
=== Let's keep in touch
@ -107,6 +123,7 @@ include::part-9-resources/_index.adoc[]
include::glossary.adoc[]
[index]
== Index

View File

@ -1,4 +1,4 @@
== Python
== Le langage Python
Le langage https://www.python.org/[Python] est un https://docs.python.org/3/faq/general.html#what-is-python[langage de programmation] interprété, interactif, amusant, orienté objet (souvent), fonctionnel (parfois), open source, multi-plateformes, flexible, facile à apprendre et difficile à maîtriser.

View File

@ -159,19 +159,6 @@ Nous allons détailler ci-dessous trois méthodes de déploiement:
* Dans des containers, avec Docker-Compose.
* Sur une *Plateforme en tant que Service* (ou plus simplement, *((PaaS))*), pour faire abstraction de toute la couche de configuration du serveur.
=== Sur une machine hôte
La première étape pour la configuration de notre hôte consiste à définir les utilisateurs et groupes de droits. Il est faut absolument éviter de faire tourner une application en tant qu'utilisateur *root*, car la moindre faille pourrait avoir des conséquences catastrophiques.
Une fois que ces utilisateurs seront configurés, nous pourrons passer à l'étape de configuration, qui consistera à:
1. Déployer les sources
2. Démarrer un serveur implémentant une interface WSGI (**Web Server Gateway Interface**), qui sera chargé de créer autant de [.line-through]#petits lutins# travailleurs que nous le désirerons.
3. Démarrer un superviseur, qui se chargera de veiller à la bonne santé de nos petits travailleurs, et en créer de nouveaux s'il le juge nécessaire
4. Configurer un proxy inverse, qui s'occupera d'envoyer les requêtes d'un utilisateur externe à la machine hôte vers notre serveur applicatif, qui la communiquera à l'un des travailleurs.
La machine hôte peut être louée chez Digital Ocean, Scaleway, OVH, Vultr, ... Il existe des dizaines d'hébergements typés VPS (**Virtual Private Server**). A vous de choisir celui qui vous convient footnote:[Personnellement, j'ai un petit faible pour Hetzner Cloud].
include::debian.adoc[]
include::heroku.adoc[]

View File

@ -1,4 +1,15 @@
=== Déploiement sur Debian
== Déploiement sur Debian
La première étape pour la configuration de notre hôte consiste à définir les utilisateurs et groupes de droits. Il est faut absolument éviter de faire tourner une application en tant qu'utilisateur *root*, car la moindre faille pourrait avoir des conséquences catastrophiques.
Une fois que ces utilisateurs seront configurés, nous pourrons passer à l'étape de configuration, qui consistera à:
1. Déployer les sources
2. Démarrer un serveur implémentant une interface WSGI (**Web Server Gateway Interface**), qui sera chargé de créer autant de [.line-through]#petits lutins# travailleurs que nous le désirerons.
3. Démarrer un superviseur, qui se chargera de veiller à la bonne santé de nos petits travailleurs, et en créer de nouveaux s'il le juge nécessaire
4. Configurer un proxy inverse, qui s'occupera d'envoyer les requêtes d'un utilisateur externe à la machine hôte vers notre serveur applicatif, qui la communiquera à l'un des travailleurs.
La machine hôte peut être louée chez Digital Ocean, Scaleway, OVH, Vultr, ... Il existe des dizaines d'hébergements typés VPS (**Virtual Private Server**). A vous de choisir celui qui vous convient footnote:[Personnellement, j'ai un petit faible pour Hetzner Cloud].
[source,bash]
----
@ -16,7 +27,7 @@ chown gwift:webapps /home/gwift <5>
<5> On donne les droits sur le répertoire /home/gwift
==== Installation des dépendances systèmes
=== 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 l'installer en parallèle de la version officiellement supportée par votre distribution.
@ -42,7 +53,7 @@ sudo make altinstall <1>
----
<1> *Attention !* Le paramètre `altinstall` est primordial. Sans lui, vous écraserez l'interpréteur initialement supporté par la distribution, et cela pourrait avoir des effets de bord non souhaités.
==== Installation de la base de données
=== Installation de la base de données
On l'a déjà vu, Django se base sur un pattern type https://www.martinfowler.com/eaaCatalog/activeRecord.html[ActiveRecords] pour la gestion de la persistance des données et supporte les principaux moteurs de bases de données connus:
@ -56,7 +67,7 @@ CAUTION: Chaque pilote doit être utilisé précautionneusement ! Chaque version
Ci-dessous, quelques procédures d'installation pour mettre un serveur à disposition. Les deux plus simples seront MariaDB et PostgreSQL, qu'on couvrira ci-dessous. Oracle et Microsoft SQLServer se trouveront en annexes.
===== PostgreSQL
==== PostgreSQL
On commence par installer PostgreSQL.
@ -94,20 +105,20 @@ $$$
NOTE: penser à inclure un bidule pour les backups.
===== MariaDB
==== MariaDB
Idem, installation, configuration, backup, tout ça.
A copier de grimboite, je suis sûr d'avoir des notes là-dessus.
===== Microsoft SQL Server
==== Microsoft SQL Server
===== Oracle
==== Oracle
==== Préparation de l'environnement utilisateur
=== Préparation de l'environnement utilisateur
[source,bash]
----
@ -140,7 +151,7 @@ cd webapps/gwift
gunicorn config.wsgi:application --bind localhost:3000 --settings=config.settings_production
----
==== Configuration de l'application
=== Configuration de l'application
[source,bash]
----
@ -152,14 +163,14 @@ 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
=== Création des répertoires de logs
[source,text]
----
mkdir -p /var/www/gwift/static
----
==== Création du répertoire pour le socket
=== Création du répertoire pour le socket
Dans le fichier `/etc/tmpfiles.d/gwift.conf`:
@ -175,7 +186,7 @@ Suivi de la création par systemd :
systemd-tmpfiles --create
----
==== Gunicorn
=== Gunicorn
[source,bash]
----
@ -207,7 +218,7 @@ exec gunicorn ${DJANGO_WSGI_MODULE}:application \
--log-file=-
----
==== Supervision, keep-alive et autoreload
=== Supervision, keep-alive et autoreload
Pour la supervision, on passe par Supervisor. Il existe d'autres superviseurs,
@ -278,7 +289,7 @@ gwift: started
----
==== Ouverture des ports
=== Configuration du firewall et ouverture des ports
et 443 (HTTPS).
@ -291,7 +302,7 @@ 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 d'Nginx
=== Installation d'Nginx
[source]
----
@ -343,7 +354,7 @@ server {
<1> Ce répertoire sera complété par la commande `collectstatic` que l'on verra plus tard. L'objectif est que les fichiers ne demandant aucune intelligence soit directement servis par Nginx. Cela évite d'avoir 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
==== Mise à jour
=== Mise à jour
Script de mise à jour.
@ -361,7 +372,7 @@ kill -HUP `ps -C gunicorn fch -o pid | head -n 1` <1>
----
<1> https://stackoverflow.com/questions/26902930/how-do-i-restart-gunicorn-hup-i-dont-know-masterpid-or-location-of-pid-file
==== Configuration des sauvegardes
=== Configuration des sauvegardes
Les sauvegardes ont été configurées avec borg: `yum install borgbackup`.
@ -381,7 +392,7 @@ Et dans le fichier crontab :
----
==== Rotation des jounaux
=== Rotation des jounaux
[source,bash]
----
@ -396,6 +407,6 @@ Et dans le fichier crontab :
Puis on démarre logrotate avec # logrotate -d /etc/logrotate.d/gwift pour vérifier que cela fonctionne correctement.
==== Ansible
=== Ansible
TODO

View File

@ -1,14 +1,18 @@
=== Heroku
== Déploiement sur Heroku
https://www.heroku.com[Heroku] est une _Plateform As A Service_ footnote:[Aussi abrégé "PaaS" pour les conaisseurs], où vous choisissez le _service_ dont vous avez besoin (une base de données, un service de cache, un service applicatif, ...), vous lui envoyer les paramètres nécessaires et le tout démarre gentiment sans que vous ne deviez superviser l'hôte.
https://www.heroku.com[Heroku] est une _Plateform As A Service_ (((paas))), où vous choisissez le _service_ dont vous avez besoin (une base de données, un service de cache, un service applicatif, ...), vous lui envoyer les paramètres nécessaires et le tout démarre gentiment sans que vous ne deviez superviser l'hôte.
Ce mode démarrage ressemble énormément aux 12 facteurs dont nous avons déjà parlé plus tôt - raison de plus pour que notre application soit directement prête à y être déployée, d'autant plus qu'il ne sera pas possible de modifier un fichier une fois qu'elle aura démarré: si vous souhaitez modifier un paramètre, cela reviendra à couper l'actuelle et envoyer de nouveaux paramètres et recommencer le déploiement depuis le début.
.Invest in apps, not ops. Heroku handles the hard stuff — patching and upgrading, 24/7 ops and security, build systems, failovers, and more — so your developers can stay focused on building great apps.
image::images/deployment/heroku.png[]
Pour un projet de type "hobby" et pour l'exemple de déploiement ci-dessous, il est tout à fait possible de s'en sortir sans dépenser un kopek, afin de tester nos quelques idées ou mettre rapidement un _Most Valuable Product_ en place. La seule contrainte consistera à pouvoir héberger des fichiers envoyés par vos utilisateurs - ceci pourra être fait en configurant un _bucket S3_ chez Amazon (beurk), Scaleway ou OVH footnote:[Entre autres.]
Pour un projet de type "hobby" et pour l'exemple de déploiement ci-dessous, il est tout à fait possible de s'en sortir sans dépenser un kopek, afin de tester nos quelques idées ou mettre rapidement un _Most Valuable Product_ en place.
La seule contrainte consistera à pouvoir héberger des fichiers envoyés par vos utilisateurs - ceci pourra être fait en configurant un _bucket compatible S3_, par exemple chez Amazon, Scaleway ou OVH.
Le fonctionnement est relativement simple: pour chaque application, Heroku crée un dépôt Git qui lui est associé. Au travers de la commande `heroku create`, vous associez en fait une nouvelle référence à votre code source:
Le fonctionnement est relativement simple: pour chaque application, Heroku crée un dépôt Git qui lui est associé.
Il suffit donc d'envoyer les sources de votre application pour qu'Heroku les interprête comme étant une nouvelle version, et déploie les nouvelles fonctionnalités, sous réserve que tous les tests passent correctement.
Au travers de la commande `heroku create`, vous associez en fait une nouvelle référence à votre code source:
[source,bash]
----
@ -31,9 +35,9 @@ $ cat .git/config
Pour envoyer une nouvelle version, il suffit dès lors (après l'avoir paramétrée), de pousser la référence grâce à la commande `git push heroku master`.
Prêt à vous lancer ? Commencez par créer un compte: https://signup.heroku.com/python.
Prêt à vous lancer ? Commencez par créer un compte: https://signup.heroku.com/python.
==== Configuration du compte Heroku
=== Configuration du compte Heroku
+ Récupération des valeurs d'environnement pour les réutiliser ci-dessous.

View File

@ -74,6 +74,16 @@
isbn = {978-1-449-37332-0},
release = {Fifteenth release - 2021-03-26}
}
@misc{
django,
title = {The web framework for perfectionists with deadlines},
url = {https://www.djangoproject.com/}
}
@misc{
django_design_philosophies,
title = {Design Philosophies},
url = {https://docs.djangoproject.com/en/dev/misc/design-philosophies/}
}
@misc{
consider_sqlite,
title = {Consider SQLite},