From c32140eb3f9e052005e1230ceb65d5c14de62f66 Mon Sep 17 00:00:00 2001 From: Fred Pauchet Date: Sun, 13 Dec 2020 21:30:00 +0100 Subject: [PATCH] Review 12 factors -> #7 --- source/images/diagrams/12-factors-1 | 1 + source/images/diagrams/12-factors-1.png | Bin 0 -> 55482 bytes source/images/diagrams/12-factors-7 | 1 + source/images/diagrams/12-factors-7.png | Bin 0 -> 17355 bytes source/main.adoc | 2 +- source/part-1-workspace/00-main.adoc | 43 ---------- source/part-1-workspace/_main.adoc | 35 ++++++++ .../building-maintainable-applications.adoc | 8 ++ .../maintainable-applications/12-factors.adoc | 77 ++++++++++++------ 9 files changed, 97 insertions(+), 70 deletions(-) create mode 100644 source/images/diagrams/12-factors-1 create mode 100644 source/images/diagrams/12-factors-1.png create mode 100644 source/images/diagrams/12-factors-7 create mode 100644 source/images/diagrams/12-factors-7.png delete mode 100644 source/part-1-workspace/00-main.adoc create mode 100644 source/part-1-workspace/_main.adoc create mode 100644 source/part-1-workspace/building-maintainable-applications.adoc diff --git a/source/images/diagrams/12-factors-1 b/source/images/diagrams/12-factors-1 new file mode 100644 index 0000000..cf4952d --- /dev/null +++ b/source/images/diagrams/12-factors-1 @@ -0,0 +1 @@ +1VnJcqMwFPwajnZZyHg5xktmMuVUUuWpmmRuMryAEowYIbzk60eAMGB5y1aQi63Xkh6oux9ItoHHy80PTkLvljngG2bH2Rh4Yphmv9eRnwmwzQA8QBngcupkUAmY01dQoJrnxtSBqDJQMOYLGlZBmwUB2KKCEc7ZujrsifnVq4bEBQ2Y28TX0T/UEV6GDsx+gf8E6nr5lVFvmPUsST5YrSTyiMPWJQhPDTzmjImstdyMwU+4y3nJ5l0f6d3dGIdAXDJhejMbzALn19++/+zN/8V3w9vrlrrZSGzzBYMj169CxoXHXBYQf1qgowKdMRbKYUiCzyDEVslHYsEk5Imlr3phQ8WDbHdU+7HUnmzKQWKTXh7dA6dLEMDzEYHg24c8ZxKkidpWHha50mirougFhO2peXbMV+CoIFt+suajrCooYjG34QSVuTsJd0GcGGfttJc1A0yuj2/lPA4+EXRVvQ+i3OvuxhUCy4bS+A16I/wOwSuMcRYHThppzH7AGOgiY+BjxqhBRrNWGbvfWcbz9d15W33XID+uVX6rmfJ32gPLKlkAHbVAq9vG1vd3QbdWF/Sa6oLLPHD+KVBI/lhRvDH6o3rfAmr3tiJ+rC71GzbioCtmZCE35hW9iE/dQLZtSU9C/mgFXFC59b1SHUvqOKlpOET0lSzSfAnTIaOBSFdjjQxrsuM+SQCbyqLVvlxNLnbDZVVOuFunVqVvddoId80smTpbtFRBXMy+yn6fLKc0hD09RSA0eXY38QHFBg0t2Y9tv967L6+jYvu1VqxWsCMSQXI8hrRWkq89f8hjY5g07a1PpfIcS97WHhUwD0nKyFqeu6uqLjKPzBY7gNgvbuqcu1jINKDwKPMFsvatVLgMnSpuTaij5Wp2rUqpDtVjYF2cqfsK8krH6XzYpwthakLcc+bEtqAs0CQ4Q/fXMocHnQpzls4cMg9Q1/sq6rBG3ZVtQyhIYOvubRR1qHbuugde2JH+wm4Ua2a3btYsjbWJMcbG1XAFPgtDiLnsRc1isb9nvUHdJCL9kXeARbNZLKLhnhd7tdPY12gc38hM44nGXHWr9hYeP99/X2g/GRY/Ymcb5eKfADz9Dw== \ No newline at end of file diff --git a/source/images/diagrams/12-factors-1.png b/source/images/diagrams/12-factors-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e276e870a259adeca75778dbb21368cb0a7e74 GIT binary patch literal 55482 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≪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 z%0A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 XlL(c$!|ilx00000NkvXXu0mjf_jUBb literal 0 HcmV?d00001 diff --git a/source/images/diagrams/12-factors-7 b/source/images/diagrams/12-factors-7 new file mode 100644 index 0000000..e0cbaff --- /dev/null +++ b/source/images/diagrams/12-factors-7 @@ -0,0 +1 @@ +zVddb5swFP01PC7iK1+PTZptqlq1WjStfZocuAUvhsuMCaS/fjaY8JUsqdZWk/Lge7Av9jmHex3DWUbFF06S8A59YIZt+oXhXBu2bbm2baif6e8rZGZNKiDg1NeTGmBNX0CDpkYz6kPamSgQmaBJF/QwjsETHYxwjnl32jOy7lsTEsAAWHuEDdEf1BehPoU9bfCvQIOwfrM1mVdPIlJP1idJQ+Jj3oKcleEsOaKoRlGxBKbIq3mp1n0+8fSwMQ6xuGTB75d8vc1upg77Xny7v3taPt5sPlk6zY6wTJ/YsCdMJlxsuBwFavSRyBr4DjKuKRP7Woc8pALWCfFUnEuvybmhiJiMLDnkmMU++Do6UG2qYAvCC/UTfVrgAoqTPFoHdaStASMQfC+n6AXOdFwt0Y6ean3zxh62q7GwbY0aJNqSwSF1o5ocaOFeI+IRDXv0ySzyi4GKm0SBHsNMJl38P8Rac7NDrGUOmbXsI8zO3ovY2YDYqyRh1COCYjzguGY24ehBmp7ndkO8bVASfJ8JRmP4eM5dp2tmy7qQ88l7ce4MOHddx3CuZmZth7atfVmsdYhchBhgTNiqQRcNeouYaOJ+gRB73WtIJrArCxRUPCq+RzP5qVfxUxnX0XWh5SiDfSt4AE4lD8BrLJacPLaDViYVNqnKqM51TnR18L9LLnnCjHtwvm4IwgMQ5z6DoYU4MPkh7Lr7ePvidtwQH+KE0yo0uo7khaYr7Tlty6hvlLeUdX6hridKw8W66qUPSOUWmzLu9sp4v+9VB9Creu44bOMfDDM/3w4T9XLgq50kNz0mtk/SsKzAZs8RguMWlshQCRejqtmLZ8pYDRm24zqu6yoTkDSprqTPtFDJFoxsgD1gSsv+IXswxKUDFqqGy7bCbnsTNigERq0JV4wG6oFQDl4QHR3yYNVHlofLsNnq+FERqDv6aLfzRzlsfm7U7bhc1m04b9BWJj0L2NORPR40lvGRvuKMR+NXVxIZNvfoykfNvxFn9Qc= \ No newline at end of file diff --git a/source/images/diagrams/12-factors-7.png b/source/images/diagrams/12-factors-7.png new file mode 100644 index 0000000000000000000000000000000000000000..cecd3d43ecb47eabd890010b0a542493fb96826e GIT binary patch literal 17355 zcmY+s1yqz#6E{w?^wKFT-QCj55(`T=g0Qf3cO$WsbV`bZ3W$ON3eqK^(nv^yAP7=Q zBj2;{`+n#D{m=0%&pvx&?%cUEb7y{IilM$188H(v78Vv6TpMPLg@q#oJg0*QfX}=d z_Ean^{M|qe%RsMCXE#qLEN)5l|2}a`h`IU%1aeElxFsYsJe?c^{e8TFN8r7e56aEi z%?b72-z3B&#Dv8qgvBLICB(QT)g)wr4@r3ud1-0u|F%cEIC=kXAZZaXU;sW#adB=* zDDZ@E^9~9H{)WoQ*vUxo15awczMf7NP7bct$gXx0uM}~;F`2fwuB}IUVfmiCT{yttnBTYGAMiD7-IY|+5331?u|8FIl z;$kA=BGSM+6QncJ-|hdI4YNq6K%~om7pU)O8tCF-9VBgR<>GAS9-tL$D*NAs1v~i% zxB*=G50C!u+?dXRVZKiPeT#Amc5?&>k>Hlp0Cotbe29sZ zmYu$TNSLp?xt_&;NB2eoEBMdQh5!eJ0qQY>gqx#K4$=W3nucQHhU&6zy1;v=p{ccR zpr5CoxP`k(ptH4)W00Czuxmh&o;uP5SeLUq(n?OpEWi(CZQ%iYN4Pl2ss+otducm` zO2RD695gk>WK87Lq~)#P)&Sd~K9;VQ&>#s12QLW+q?@yhlbpY`mbJdF8_Y#q-^oY?gnA9o&lyB0cvU% z+CdsHl!mi7)XCM*$4uVASv}YYZV=+^uP5$hjxvOM>KKZ

&J@0(9IZeRLf?oiqXr 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 Dc0P0& literal 0 HcmV?d00001 diff --git a/source/main.adoc b/source/main.adoc index fd0df4b..4e656ca 100644 --- a/source/main.adoc +++ b/source/main.adoc @@ -40,7 +40,7 @@ Et tout ça à un seul et même endroit. Oui. :-) Bonne lecture. -include::part-1-workspace/00-main.adoc[] +include::part-1-workspace/_main.adoc[] include::part-2-deployment/00-main.adoc[] diff --git a/source/part-1-workspace/00-main.adoc b/source/part-1-workspace/00-main.adoc deleted file mode 100644 index 0a61ee9..0000000 --- a/source/part-1-workspace/00-main.adoc +++ /dev/null @@ -1,43 +0,0 @@ -= Environnement de travail - -Avant de démarrer le développement, il est nécessaire de passer un peu de temps sur la configuration de l'environnement. - -Les morceaux de code seront développés pour Python3.6+ et Django 3.0+. Ils nécessiteront peut-être quelques adaptations pour fonctionner sur une version antérieure. - -Django fonctionne sur un https://docs.djangoproject.com/en/dev/internals/release-process/[roulement de trois versions mineures pour une version majeure], clôturé par une version LTS (_Long Term Support_). - -image::images/django-support-lts.png[] - -Ce sera une bonne indication à prendre en considération pour nos dépendances, puisqu'en visant une version particulière, on ne devra pratiquement pas se soucier (bon, un peu quand même...) des dépendances à installer, pour peu qu'on reste sous un certain seuil. - -NOTE: en relisant, le passage ci-dessus n'est peut-être pas hyper clair... A refaire. - -Dans cette partie, on va parler de *méthode de travail*, avec comme objectif visé, d'éviter que l'application ne tourne que sur notre machine et que chaque déploiement ne soit une plaie à gérer. Chaque mise à jour doit se limiter à: - -. démarrer un script, -. prévoir un rollback si cela plante -. se préparer une tisane en regardant nos flux RSS (si cette technologie existe encore...). - -**Remarque** : les commandes qui seront exécutés dans ce livre le seront depuis un shell sous GNU/Linux. Certaines devront donc être adaptées si vous êtes dans un autre environnement. - -== Construire des applications maintenables - -include::maintainable-applications/12-factors.adoc[] - -include::maintainable-applications/maintainable-applications.adoc[] - -include::maintainable-applications/solid.adoc[] - -include::environment/index.adoc[] - -include::venvs.adoc[] - -include::django.adoc[] - -include::unit_tests.adoc[] - -include::tools.adoc[] - -include::external_tools.adoc[] - -include::summary.adoc[] diff --git a/source/part-1-workspace/_main.adoc b/source/part-1-workspace/_main.adoc new file mode 100644 index 0000000..b8ddec9 --- /dev/null +++ b/source/part-1-workspace/_main.adoc @@ -0,0 +1,35 @@ += Environnement de travail + +Avant de démarrer le développement, il est nécessaire de passer un peu de temps sur la configuration de l'environnement. + +Les morceaux de code que vous trouverez ci-dessous seront développés pour Python3.6+ et Django 3.0+. Ils nécessiteront peut-être quelques adaptations pour fonctionner sur une version antérieure. + +Django fonctionne sur un https://docs.djangoproject.com/en/dev/internals/release-process/[roulement de trois versions mineures pour une version majeure], clôturé par une version LTS (_Long Term Support_). + +image::images/django-support-lts.png[] + +La version utilisée sera une bonne indication à prendre en considération pour nos dépendances, puisqu'en visant une version particulière, nous ne devrons pratiquement pas nous soucier (bon, un peu quand même...) des dépendances à installer, pour peu que l'on reste sous un certain seuil. + +Dans cette partie, nous allons parler de *méthode de travail*, avec comme objectif d'éviter que l'application ne tourne que sur notre machine et que chaque déploiement ne soit une plaie à gérer. Chaque mise à jour doit être réalisable de la manière la plus simple possible: + +. démarrer un script, +. prévoir un rollback si cela plante +. se préparer une tisane en regardant nos flux RSS (si cette technologie existe encore...). + +NOTE: La plupart des commandes qui seront présentées dans ce livre le seront depuis un shell sous GNU/Linux. Certaines d'entre elles pourraient devoir être adaptées si vous utilisez un autre système d'exploitation (macOS) ou n'importe quelle autre grosse bouse commerciale (MS Windows). + +include::building-maintainable-applications.adoc[] + +include::environment/index.adoc[] + +include::venvs.adoc[] + +include::django.adoc[] + +include::unit_tests.adoc[] + +include::tools.adoc[] + +include::external_tools.adoc[] + +include::summary.adoc[] diff --git a/source/part-1-workspace/building-maintainable-applications.adoc b/source/part-1-workspace/building-maintainable-applications.adoc new file mode 100644 index 0000000..939f92e --- /dev/null +++ b/source/part-1-workspace/building-maintainable-applications.adoc @@ -0,0 +1,8 @@ +== Construire des applications maintenables + + +include::maintainable-applications/12-factors.adoc[] + +include::maintainable-applications/maintainable-applications.adoc[] + +include::maintainable-applications/solid.adoc[] diff --git a/source/part-1-workspace/maintainable-applications/12-factors.adoc b/source/part-1-workspace/maintainable-applications/12-factors.adoc index 744a096..ec8054e 100644 --- a/source/part-1-workspace/maintainable-applications/12-factors.adoc +++ b/source/part-1-workspace/maintainable-applications/12-factors.adoc @@ -1,45 +1,70 @@ === 12 facteurs -Pour la méthode de travail et de développement, on va se baser sur les https://12factor.net/fr/[The Twelve-factor App] - ou plus simplement les *12 facteurs*. +Pour la méthode de travail et de développement, nous allons nous baser sur les https://12factor.net/fr/[The Twelve-factor App] - ou plus simplement les *12 facteurs*. -L'idée derrière cette méthode, et indépendamment des langages de développement utilisés, consiste à suivre un ensemble de douze concepts , afin de: +L'idée derrière cette méthode, et indépendamment des langages de développement utilisés, consiste à suivre un ensemble de douze concepts, afin de: -. *Faciliter la mise en place de phases d'automatisation*; plus concrètement, de faciliter les mises à jour applicatives, simplifier la gestion de l'hôte, diminuer la divergence entre les différents environnements d'exécution et offrir la possibilité d'intégrer le projet dans un processus d'https://en.wikipedia.org/wiki/Continuous_integration[intégration continue]/link:https://en.wikipedia.org/wiki/Continuous_deployment[déploiement continu] -. *Faciliter la mise à pied de nouveaux développeurs ou de personnes souhaitant rejoindre le projet* -. *Minimiser les divergences entre les différents environnemens composant un projet* +. *Faciliter la mise en place de phases d'automatisation*; plus concrètement, de faciliter les mises à jour applicatives, simplifier la gestion de l'hôte, diminuer la divergence entre les différents environnements d'exécution et offrir la possibilité d'intégrer le projet dans un processus d'https://en.wikipedia.org/wiki/Continuous_integration[intégration continue] ou link:https://en.wikipedia.org/wiki/Continuous_deployment[déploiement continu] +. *Faciliter la mise à pied de nouveaux développeurs ou de personnes souhaitant rejoindre le projet*, dans la mesure où la mise à disposition d'un environnement sera grandement facilitée. +. *Minimiser les divergences entre les différents environnemens sur lesquels un projet pourrait être déployé* . *Augmenter l'agilité générale du projet*, en permettant une meilleure évolutivité architecturale et une meilleure mise à l'échelle - _Vous avez 5000 utilisateurs en plus? Ajoutez un serveur et on n'en parle plus ;-)_. -En pratique, les idées qui se trouvent derrière les points ci-dessus permettront de monter facilement un nouvel environnement - qu'il soit sur la machine du petit nouveau dans l'équipe, sur un serveur Azure/Heroku/Digital Ocean ou votre nouveau Raspberry Pi Zéro caché à la cave. +En pratique, les points ci-dessus permettront de monter facilement un nouvel environnement - qu'il soit sur la machine du petit nouveau dans l'équipe, sur un serveur Azure/Heroku/Digital Ocean ou votre nouveau Raspberry Pi Zéro caché à la cave - et vous feront gagner un temps précieux. -Pour reprendre de manière très brute les différentes idées derrière cette méthode, on a: +Pour reprendre de manière très brute les différentes idées derrière cette méthode, nous avons: -. *Une base de code unique, suivie par un système de contrôle de versions*. Chaque déploiement de l'application se basera sur cette source, afin de minimiser les différences que l'on pourrait trouver entre deux environnements d'un même projet. On utilisera un dépôt Git - Github, Gitlab, Gitea, ... Au choix. +*#1 - Une base de code unique, suivie par un système de contrôle de versions*. Chaque déploiement de l'application se basera sur cette source, afin de minimiser les différences que l'on pourrait trouver entre deux environnements d'un même projet. On utilisera un dépôt Git - Github, Gitlab, Gitea, ... Au choix. -. *Déclarez explicitement les dépendances nécessaires au projet, et les isoler du reste du système lors de leur installation*. L'idée est que chaque installation ou configuration se fasse toujours de la même manière, et puisse être répétée quel que soit l'environnement cible. Cela permet également d'éviter que l'application n'utilise une dépendance qui soit déjà installée sur un des sytèmes de développement, et qu'elle soit difficile à répercuter sur un autre environnement. -Dans notre cas, cela pourra être fait au travers de https://pypi.org/project/pip/[pip - Package Installer for Python]. -Dans tous les cas, chaque application doit disposer d'un environnement sain, qui lui est assigné, et vu le peu de ressources que cela coûte, il ne faut pas s'en priver. +image::images/diagrams/12-factors-1.png[align=center] -. *Sauver la configuration directement au niveau de l'environnement*. -On veut par exemple éviter d'avoir à recompiler/redéployer l'application parce que l'adresse du serveur de messagerie a été modifiée, ou parce qu'un protocole a changé en cours de route. -Concrètement, toute information susceptible de modifier le comportement intrinsèque de l'application doit se trouver dans un fichier ou dans une variable d'environnement. -En allant un pas plus loin, cela permettra de paramétrer facilement un container, simplement en modifiant une variable de configuration, qui spécifiera la base de données sur laquelle l'application devra se connecter. -Toute clé de configuration (nom du serveur de base de données, adresse d'un service Web externe, clé d'API pour l'interrogation d'une ressource, ...) sera définie directement au niveau de l'hôte - à aucun moment, on ne doit trouver un mot de passe en clair dans le dépôt source ou une valeur susceptible d'évoluer, écrite en dur dans le code. +*#2 - Déclarez explicitement les dépendances nécessaires au projet, et les isoler du reste du système lors de leur installation*. Chaque installation ou configuration doit toujours être faite de la même manière, et doit pouvoir être répétée quel que soit l'environnement cible. -. *Traiter les ressources externes comme des ressources attachées*. +Cela permet d'éviter que l'application n'utilise une dépendance qui soit déjà installée sur un des sytèmes de développement, et qu'elle soit difficile, voire impossible, à répercuter sur un autre environnement. +Dans notre cas, cela pourra être fait au travers de https://pypi.org/project/pip/[PIP - Package Installer for Python] ou https://python-poetry.org/[Poetry]. + +Mais dans tous les cas, chaque application doit disposer d'un environnement sain, qui lui est assigné, et vu le peu de ressources que cela coûte, il ne faut pas s'en priver. + +*#3 - Sauver la configuration directement au niveau de l'environnement*. +Nous voulons éviter d'avoir à recompiler/redéployer l'application parce que: + +. l'adresse du serveur de messagerie a été modifiée, +. un protocole a changé en cours de route +. la base de données a été déplacée +. ... + +En pratique, toute information susceptible de modifier un lien applicatif doit se trouver dans un fichier ou dans une variable d'environnement, et doit être facilement modifiable. +En allant un pas plus loin, cela permettra de paramétrer facilement un container, en modifiant une variable de configuration qui spécifierait la base de données sur laquelle l'application devra se connecter. + +Toute clé de configuration (nom du serveur de base de données, adresse d'un service Web externe, clé d'API pour l'interrogation d'une ressource, ...) sera définie directement au niveau de l'hôte - à aucun moment, nous ne devons trouver un mot de passe en clair dans le dépôt source ou une valeur susceptible d'évoluer, écrite en dur dans le code. + +*#4 - Traiter les ressources externes comme des ressources attachées*. On parle de bases de données, de services de mise en cache, d'API externes, ... -L'application doit également être capable d'effectuer des changements au niveau de ces ressources sans que le code intrinsèque ne soit modifié. On parle alors de *ressources attachées*, dont la présence est nécessaire au bon fonctionnement de l'application, mais pour lesquelles le *type* n'est pas obligatoirement défini. -On veut par exemple "une base de données" et "une mémoire cache", et pas "une base MariaDB et une instance Memcached". De cette manière, les ressources peuvent être attachées et détachées d'un déploiement à la volée. +L'application doit être capable d'effectuer des changements au niveau de ces ressources sans que son code ne soit modifié. On parle alors de *ressources attachées*, dont la présence est nécessaire au bon fonctionnement de l'application, mais pour lesquelles le *type* n'est pas obligatoirement défini. + +Nous voulons par exemple "une base de données" et "une mémoire cache", et pas "une base MariaDB et une instance Memcached". De cette manière, les ressources peuvent être attachées et détachées d'un déploiement à la volée. + Si une base de données ne fonctionne pas correctement (problème matériel?), l'administrateur pourrait simplement restaurer un nouveau serveur à partir d'une précédente sauvegarde, et l'attacher à l'application sans que le code source ne soit modifié. une solution consiste à passer toutes ces informations (nom du serveur et type de base de données, clé d'authentification, ...) directement via des variables d'environnement. -. *Séparer proprement les phases de construction, de mise à disposition et d'exécution*. -La *construction* (_build_) convertit un code source en un ensemble de fichiers exécutables, associé à une version et à une transaction dans le système de gestion de sources. -La *mise à disposition* (_release_) associe cet ensemble à une configuration prête à être exécutée, tandis que la phase d'*exécution* (_run_) démarre les processus nécessaires au bon fonctionnement de l'application. On doit pouvoir se baser sur les _releases_ de Gitea, sur un serveur d'artefacts ou sur https://fr.wikipedia.org/wiki/Capistrano_(logiciel)[Capistrano]. +*#5 - Séparer proprement les phases de construction, de mise à disposition et d'exécution*. -. *Les processus d'exécution ne doivent rien connaître ou conserver de l'état de l'application*. -On suppose donc que toute information stockée en mémoire ou sur disque n'altérera pas le comportement futur de l'application, par exemple après un redémarrage non souhaité. -Si une réinitialisation devait être nécessaire, l'application ne devra pas compter sur la présence d'une information au niveau du système. +. La *construction* (_build_) convertit un code source en un ensemble de fichiers exécutables, associé à une version et à une transaction dans le système de gestion de sources. +. La *mise à disposition* (_release_) associe cet ensemble à une configuration prête à être exécutée, +. tandis que la phase d'*exécution* (_run_) démarre les processus nécessaires au bon fonctionnement de l'application. -. *Autoriser la liaison d'un port de l'application à un port du système hôte*. Les applications 12-factors sont auto-contenues et peuvent fonctionner en autonomie totale. L'idée ici est qu'elles puissent être joignables grâce à un mécanisme de pont, où l'hôte effectue la redirection vers l'un des ports ouverts par l'application, typiquement, en HTTP ou via un autre protocole. +Parmi les solutions possibles, nous pourrions nous pourrions nous baser sur les _releases_ de Gitea, sur un serveur d'artefacts ou sur https://fr.wikipedia.org/wiki/Capistrano_(logiciel)[Capistrano]. + +*#6 - Les processus d'exécution ne doivent rien connaître ou conserver de l'état de l'application*. + +Toute information stockée en mémoire ou sur disque ne doit pas altérer le comportement futur de l'application, par exemple après un redémarrage non souhaité. + +Pratiquement, si l'application devait rencontrer un problème, nous pourrions la redémarrer sur un autre serveur. Toute information qui aurait été stockée durant l'exécution de l'application sur le premier hôte serait donc perdue. +Si une réinitialisation devait être nécessaire, l'application ne devra pas compter sur la présence d'une information au niveau du nouveau système. + +Il serait également difficile d'appliquer une mise à l'échelle de l'application si une donnée indispensable à son fonctionnement devait se trouver sur une seule machine où elle est exécutée. + +*#7 - Autoriser la liaison d'un port de l'application à un port du système hôte*. Les applications 12-factors sont auto-contenues et peuvent fonctionner en autonomie totale. L'idée est qu'elles puissent être joignables grâce à un mécanisme de ponts, où l'hôte effectue la redirection vers l'un des ports ouverts par l'application, typiquement, en HTTP ou via un autre protocole. + +image::images/diagrams/12-factors-7.png[align=center] . *Faites confiance aux processus systèmes pour l'exécution de l'application*. Comme décrit plus haut, l'application doit utiliser des processus _stateless_ (sans état). On peut donc facilement créer et utiliser des processus supplémentaires pour tenir plus facilement une lourde charge, ou dédier des processus particuliers pour certaines tâches: requêtes HTTP _via_ des processus Web; _long-running_ jobs pour des processys asynchrones, ...