
Dans cet article, je vais partager mon expérience de configuration CI/CD à l'aide du panneau de contrÎle Plesk et de Github Actions. Aujourd'hui, nous allons apprendre à déployer un projet simple intitulé « Helloworld ». Il est écrit sur le framework Python Flask, avec des workers sur Celery et un frontend sur Angular 8.
Liens vers les dépÎts : , .
Dans la premiÚre partie de l'article, nous examinerons notre projet et ses composants. Dans la seconde, nous verrons comment configurer Plesk et installer les extensions et composants nécessaires (BD, RabbitMQ, Redis, Docker, etc.).
Dans la troisiÚme partie, nous verrons enfin comment configurer le pipeline pour déployer notre projet sur le serveur dans les environnements dev et prod. Puis nous lancerons le site sur le serveur.
Ah oui, j'ai oubliĂ© de me prĂ©senter. Je m'appelle Oleg Borzov, je suis dĂ©veloppeur fullstack dans l'Ă©quipe CRM pour les gestionnaires de prĂȘts hypothĂ©caires chez Domclick.
Aperçu du projet
Pour commencer, examinons les deux dĂ©pĂŽts du projet â backend et frontend â et parcourons le code.
Partie backend : Flask+Celery
Pour la partie backend, j'ai choisi une combinaison assez populaire parmi les dĂ©veloppeurs Python : le framework Flask (pour l'API) et Celery (pour la file d'attente des tĂąches). SQLAlchemy est utilisĂ© comme ORM. Alembic est utilisĂ© pour les migrations. Pour la validation JSON dans les handlers â Marshmallow.
Dans il y a un fichier Readme.md avec une description détaillée de la structure et des instructions pour exécuter le projet.
assez simple, composée de 6 handlers :
/pingâ pour vĂ©rifier la disponibilitĂ© ;- handlers pour l'inscription, l'authentification, la dĂ©sauthentification et l'obtention de l'utilisateur authentifiĂ© ;
- handler pour l'envoi d'email, qui place une tĂąche dans la file d'attente Celery.
encore plus simple, il n'y a qu'une seule tĂąche send_mail_task.
Dans le dossier il y a deux sous-dossiers :
dockeravec deux fichiers Docker (base.dockerfilepour construire une image de base peu modifiĂ©e etDockerfilepour les constructions principales) ;.env_filesâ avec des fichiers de variables d'environnement pour diffĂ©rents environnements.
Ă la racine du projet, il y a quatre fichiers docker-compose :
docker-compose.local.db.ymlpour lever une BD locale pour le développement ;docker-compose.local.workers.ymlpour lever localement un worker, BD, Redis et RabbitMQ ;docker-compose.test.ymlpour exécuter des tests lors du déploiement ;docker-compose.ymlpour le déploiement.
Et le dernier dossier intĂ©ressant pour nous â . Il contient des scripts shell pour le dĂ©ploiement :
deploy.shâ lancement des migrations et du dĂ©ploiement. Il est exĂ©cutĂ© sur le serveur aprĂšs la construction et l'exĂ©cution des tests dans Github Actions ;rollback.shâ restauration des conteneurs Ă la version prĂ©cĂ©dente de la construction ;curl_tg.shâ envoi de notifications de dĂ©ploiement sur Telegram.
Frontend sur Angular
beaucoup plus simple que le backend. Le frontend se compose de trois pages :
- Page d'accueil avec un formulaire d'envoi d'email et un bouton de déconnexion.
- Page de connexion.
- Page d'inscription.
La page d'accueil a un design minimaliste :

à la racine se trouvent deux fichiers Dockerfile et docker-compose.yml, ainsi qu'un dossier familier .ci-cd avec un nombre de scripts légÚrement inférieur à celui du dépÎt backend (les scripts pour exécuter des tests ont été supprimés).
Créons un projet dans Plesk
Commençons par la configuration de Plesk et la création d'un abonnement pour notre site.
Installation des extensions
Dans Plesk, nous aurons besoin de quatre extensions :
Dockerpour gérer et afficher visuellement l'état des conteneurs dans l'interface d'administration de Plesk ;Gitpour configurer l'étape de déploiement sur le serveur ;Let's Encryptpour générer (et renouveler automatiquement) des certificats TLS gratuits ;Pare-feupour configurer le filtrage du trafic entrant.
Nous pouvons les installer via l'interface d'administration de Plesk dans la section Extensions :

Nous ne traiterons pas la configuration détaillée des extensions, les paramÚtres par défaut conviendront pour nos objectifs de démonstration.
Création d'un abonnement et d'un site
Ensuite, nous devons créer un abonnement pour notre site helloworld.ru et ajouter le sous-domaine dev.helloworld.ru.
- Créons un abonnement pour le domaine helloworld.ru et indiquons le nom d'utilisateur et le mot de passe pour l'utilisateur systÚme :

Au bas de la page, cocher la case Sécuriser le domaine avec Let's Encrypt, si nous voulons configurer HTTPS pour le site :
- Puis dans cet abonnement, crĂ©ons le sous-domaine dev.helloworld.ru (pour lequel un certificat TLS gratuit peut Ă©galement ĂȘtre Ă©mis) :

Installation des composants serveur
Nous avons à disposition un serveur avec OS Debian Stretch 9.12 et le panneau de contrÎle installé Plesk Obsidian 18.0.27.
Nous devons installer et configurer pour notre projet :
- PostgreSQL (dans notre cas, il y aura un serveur avec deux bases de données pour les environnements dev et prod).
- RabbitMQ (mĂȘme chose, une instance avec diffĂ©rents vhosts pour les environnements).
- Deux instances Redis (pour les environnements dev et prod).
- Docker Registry (pour le stockage local des images Docker générées).
- Interface utilisateur pour Docker registry.
PostgreSQL
Avec Plesk, il y a déjà une base de données PostgreSQL incluse, mais pas à jour (au moment de la rédaction de cet article, Plesk Obsidian les versions de Postgres 8.4 à 10.8). Nous souhaitons pour notre application la derniÚre version (12.3 au moment de la rédaction de cet article), donc nous allons l'installer manuellement.
Il existe de nombreuses instructions détaillées pour installer Postgres sur Debian en ligne (), c'est pourquoi je ne vais pas les décrire en détail, je vais simplement donner les commandes :
wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib
Ătant donnĂ© que PostgreSQL a des paramĂštres par dĂ©faut plutĂŽt mĂ©diocres, il est essentiel de corriger la configuration. Pour cela, nous allons utiliser : il faut entrer les paramĂštres de votre serveur et remplacer les configurations dans le fichier /etc/postgresql/12/main/postgresql.confpar celles proposĂ©es. Il convient de prĂ©ciser que ces calculateurs ne sont pas une solution miracle, et la base doit ĂȘtre ajustĂ©e de maniĂšre plus prĂ©cise en fonction de votre matĂ©riel, de vos applications et de la complexitĂ© des requĂȘtes. Mais pour commencer, cela suffit.
En plus des paramĂštres suggĂ©rĂ©s par le calculateur, nous changeons dans postgresql.confle port par dĂ©faut 5432 Ă un autre (dans notre exemple â 53983).
AprÚs avoir modifié le fichier de configuration, redémarrons le serveur postgresql avec la commande :
service postgresql restart
Nous avons installé et configuré PostgreSQL. Maintenant, créons une base de données, des utilisateurs pour les environnements dev et prod, et attribuons aux utilisateurs des droits de gestion de la base de données :
$ su - postgres
postgres:~$ create database hw_dev_db_name;
CREATE DATABASE
postgres:~$ create user hw_dev_db_user with password 'hw_dev_db_password';
CREATE ROLE
postgres:~$ grant ALL privileges ON database hw_dev_db_name to hw_dev_db_user;
GRANT
postgres:~$ create database hw_prod_db_name;
CREATE DATABASE
postgres:~$ create user hw_prod_db_user with password 'hw_prod_db_password';
CREATE ROLE
postgres:~$ grant ALL privileges ON database hw_prod_db_name to hw_prod_db_user;
GRANT
RabbitMQ
Passons Ă l'installation de RabbitMQ â le courtier de messages pour Celery. Il s'installe assez facilement sur Debian :
wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
sudo dpkg -i erlang-solutions_1.0_all.deb
sudo apt-get update
sudo apt-get install erlang erlang-nox
sudo add-apt-repository 'deb http://www.rabbitmq.com/debian/ testing main'
wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get install rabbitmq-server
AprÚs l'installation, nous devons créer vhosts, des utilisateurs et leur attribuer les droits nécessaires :
sudo rabbitmqctl add_user hw_dev_amqp_user hw_dev_amqp_password
sudo rabbitmqctl set_user_tags hw_dev_amqp_user administrator
sudo rabbitmqctl add_vhost hw_dev_vhost
sudo rabbitmqctl set_permissions -p hw_dev_vhost hw_dev_amqp_user ".*" ".*" ".*"
sudo rabbitmqctl add_user hw_prod_amqp_user hw_prod_amqp_password
sudo rabbitmqctl set_user_tags hw_prod_amqp_user administrator
sudo rabbitmqctl add_vhost hw_prod_vhost
sudo rabbitmqctl set_permissions -p hw_prod_vhost hw_prod_amqp_user ".*" ".*" ".*"
Redis
Nous allons maintenant installer et configurer le dernier composant pour notre application â Redis. Il sera utilisĂ© comme backend pour stocker les rĂ©sultats des tĂąches Celery.
Nous allons déployer deux conteneurs Docker avec Redis pour les environnements dev et prod à l'aide de l'extension Docker pour Plesk.
- Accédez à Plesk, allez dans la section Extensions, recherchez l'extension Docker et installez-la (nous avons besoin de la version gratuite) :

- Allez dans l'extension installée, recherchez l'image
redis bitnamiet installez la derniĂšre version :
- Accédez au conteneur téléchargé et modifiez la configuration : indiquez le port, la taille maximale de la RAM allouée, le mot de passe dans les variables d'environnement, et montez le volume :

- Répétez les étapes 2-3 pour le conteneur prod, en modifiant seulement les paramÚtres : port, mot de passe, taille de la RAM et chemin du dossier volume sur le serveur :

Docker Registry
En plus des services de base, il serait utile d'installer un dépÎt Docker privé sur le serveur. Heureusement, l'espace sur les serveurs est maintenant suffisamment bon marché (certainement moins cher qu'un abonnement à DockerHub), et le processus d'installation d'un dépÎt privé est trÚs simple.
Nous souhaitons avoir installé :
- un dépÎt Docker protégé par mot de passe, accessible via un sous-domaine ;
- une interface UI pour visualiser les images dans le dépÎt, accessible à l'adresse .
Pour cela :
- CrĂ©ons dans Plesk deux sous-domaines dans notre abonnement : docker.helloworld.ru et docker-ui.helloworld.ru, et configurons des certificats Letâs Encrypt pour eux.
- Dans le dossier du sous-domaine docker.helloworld.ru, ajoutons le fichier
docker-compose.ymlavec ce contenu :version: "3" services: docker-registry: image: "registry:2" restart: always ports: - "53985:5000" environment: REGISTRY_AUTH: htpasswd REGISTRY_AUTH_HTPASSWD_REALM: basic-realm REGISTRY_AUTH_HTPASSWD_PATH: \/auth\/.htpasswd REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: \/data volumes: - .\/docker-registry.htpasswd:\/auth\/.htpasswd - .\/data:\/data docker-registry-ui: image: konradkleine\/docker-registry-frontend:v2 restart: always ports: - "53986:80" environment: VIRTUAL_HOST: '*, https:\/\/*' ENV_DOCKER_REGISTRY_HOST: 'docker-registry' ENV_DOCKER_REGISTRY_PORT: 5000 links: - 'docker-registry' - Avec SSH, générez le fichier .htpasswd pour la Basic-authentification dans le dépÎt Docker :
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Construisons et lançons les conteneurs :
docker-compose up -d - Et il faut rediriger Nginx vers nos conteneurs. Cela peut se faire via Plesk.
Les actions suivantes doivent ĂȘtre effectuĂ©es pour les sous-domaines docker.helloworld.ru et docker-ui.helloworld.ru :
Dans la section Dev Tools de notre site, accédez à RÚgles Proxy Docker:

Et ajoutez une rĂšgle pour le proxy du trafic entrant vers notre conteneur :

- Vérifions que nous pouvons nous authentifier dans notre conteneur depuis la machine locale :
$ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password AVERTISSEMENT ! L'utilisation de --password via la CLI est peu sécurisée. Utilisez --password-stdin. Connexion réussie - Vérifions également le fonctionnement du sous-domaine docker-ui.helloworld.ru :

En cliquant sur Parcourir les dĂ©pĂŽts, le navigateur affichera une fenĂȘtre d'authentification oĂč vous devrez entrer votre nom d'utilisateur et votre mot de passe pour le dĂ©pĂŽt. Ensuite, nous serons redirigĂ©s vers une page contenant la liste des dĂ©pĂŽts (qui sera encore vide au dĂ©but) :
Ouvrir les ports dans le pare-feu Plesk
AprÚs l'installation et la configuration des composants, nous devons ouvrir des ports pour que les composants soient accessibles à partir des conteneurs Docker et du réseau externe.
Voyons comment procéder, en prenant en exemple l'extension Firewall que nous avons installée précédemment pour Plesk.
- Passons Ă Outils & ParamĂštres > ParamĂštres > Pare-feu:

- Passons à Modifier les rÚgles du pare-feu Plesk > Ajouter une rÚgle personnalisée et ouvrir les ports TCP suivants pour le sous-réseau Docker (172.0.0.0/8):
RabbitMQ : 1883, 4369, 5671-5672, 25672, 61613-61614
Redis : 32785, 32786
- Ajoutons également une rÚgle pour ouvrir au monde extérieur les ports de PostgreSQL et du panneau de gestion de RabbitMQ :

- Appliquez les rĂšgles Ă l'aide du bouton Appliquer les modifications :

Configuration CI/CD dans Github Actions
Passons Ă la partie la plus intĂ©ressante â la configuration du pipeline d'intĂ©gration et de dĂ©ploiement continus de notre projet sur le serveur.
Ce pipeline sera composé de deux parties :
- construction de l'image et exĂ©cution des tests (pour le backend) â du cĂŽtĂ© de Github ;
- exĂ©cution des migrations (pour le backend) et dĂ©ploiement des conteneurs â sur le serveur.
Déploiement dans Plesk
Commençons par le second point (car le premier dépend de lui).
Nous allons configurer le processus de déploiement à l'aide de l'extension Git pour Plesk.
Prenons un exemple avec l'environnement Prod pour le dépÎt Backend.
- Accédez à l'abonnement de notre site Helloworld et allez dans la section Git :

- Collez dans le champ « DépÎt Git distant » le lien vers notre dépÎt Github et changez le dossier par défaut
httpdocsen un autre (par exemple,/httpdocs/hw_back):
- Copiez la clé publique SSH de l'étape précédente et ajoutez-la dans les paramÚtres de Github.
- Cliquez sur OK à l'écran au point 2, puis vous serez redirigé vers la page du dépÎt dans Plesk. Maintenant, nous devons configurer la mise à jour du dépÎt lors des commits sur la branche master. Pour ce faire, allons dans ParamÚtres du dépÎt et sauvegardez la valeur
Webhook URL(cela nous sera utile plus tard lors de la configuration de Github Actions) :
- Dans le champ Actions à l'écran précédent, saisissez le script pour lancer le déploiement :
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}oĂč :
{REPOSITORY_ABSOLUTE_PATH}â chemin vers le dossier prod du dĂ©pĂŽt backend sur le serveur ;
{ENV}â environnement (dev/prod), dans notre casprod;
{DOCKER_REGISTRY_HOST}â hĂŽte de notre dĂ©pĂŽt docker
{TG_BOT_TOKEN}â token du bot Telegram ;
{TG_CHAT_ID}â ID du chat/canal pour l'envoi de notifications.Exemple de script :
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - Nous ajoutons un utilisateur de notre abonnement au groupe Docker (pour qu'il puisse gérer les conteneurs) :
sudo usermod -aG docker helloworld_admin
L'environnement de dĂ©veloppement pour le dĂ©pĂŽt backend et frontend s'configure de la mĂȘme maniĂšre.
Pipeline de déploiement dans Github Actions
Passons Ă la configuration de la premiĂšre partie de notre pipeline CI/CD dans Github Actions.
Backend
Le pipeline est décrit dans .
Mais avant de l'examiner, remplissons dans Github les variables secrÚtes nécessaires. Pour cela, nous allons dans ParamÚtres -> Secrets:
DOCKER_REGISTRYâ l'hĂŽte de notre dĂ©pĂŽt Docker (docker.helloworld.ru);DOCKER_LOGINâ identifiant pour le dĂ©pĂŽt Docker;DOCKER_PASSWORDâ mot de passe pour cela;DEPLOY_HOSTâ l'hĂŽte oĂč l'interface Plesk est accessible (exemple : :8443 ou :8443);DEPLOY_BACK_PROD_TOKENâ jeton pour dĂ©ployer dans le dĂ©pĂŽt de production sur le serveur (nous l'avons obtenu dans le dĂ©ploiement dans Plesk p. 4);DEPLOY_BACK_DEV_TOKENâ jeton pour dĂ©ployer dans le dĂ©pĂŽt de dĂ©veloppement sur le serveur.
Le processus de déploiement est simple et se compose de trois étapes principales :
- construction et publication de l'image dans notre dépÎt ;
- exécution des tests dans le conteneur à partir de l'image récemment construite ;
- déploiement dans l'environnement requis selon la branche (dev/master).
Frontend
diffĂšre peu de celui du backend. Il n'y a pas d'Ă©tape pour l'exĂ©cution des tests et les noms des jetons pour le dĂ©ploiement changent. Les secrets pour le dĂ©pĂŽt frontend, d'ailleurs, doivent ĂȘtre remplis sĂ©parĂ©ment.
Configuration du site
Proxy du trafic via Nginx
Eh bien, nous sommes arrivĂ©s Ă la fin. Il ne reste plus qu'Ă configurer le proxy du trafic entrant et sortant dans notre conteneur via Nginx. Ce processus a dĂ©jĂ Ă©tĂ© abordĂ© au point 5 de la configuration du Docker Registry. La mĂȘme chose doit ĂȘtre rĂ©pĂ©tĂ©e pour les parties backend et frontend dans les environnements dev et prod.
Je vais fournir des captures d'écran des paramÚtres.
Backend

Frontend

Important Ă prĂ©ciser. Dans le conteneur frontend, toutes les URL seront proxyĂ©es, sauf celles qui commencent par /api/ â elles seront proxyĂ©es dans le conteneur backend (donc dans le conteneur backend, tous les gestionnaires doivent commencer par /api/).
Résultats
Maintenant, notre site doit ĂȘtre accessible aux adresses helloworld.ru et dev.helloworld.ru (environnements prod et dev respectivement).
En résumé, nous avons appris comment préparer une simple application sur Flask et Angular et configurer un pipeline dans Github Actions pour son déploiement sur un serveur géré par Plesk.
Je vais redonner les liens vers les dépÎts avec le code : , .
Source : habr.com
















