
In dit artikel deel ik mijn ervaring met het instellen van CI/CD met behulp van het Plesk-bedieningspaneel en GitHub Actions. Vandaag gaan we leren hoe we een eenvoudig project met de onopvallende naam «Helloworld» kunnen implementeren. Het is geschreven in het Python-framework Flask, met workers op Celery en een frontend op Angular 8.
Links naar de repositories: , .
In het eerste deel van het artikel bekijken we ons project en de onderdelen ervan. In het tweede deel zullen we onderzoeken hoe we Plesk kunnen instellen en de noodzakelijke uitbreidingen en componenten (DB, RabbitMQ, Redis, Docker, etc.) kunnen installeren.
In het derde deel zullen we eindelijk onderzoeken hoe we een pipeline kunnen instellen voor het implementeren van ons project op de server in dev- en prod-omgevingen. En daarna starten we de site op de server.
En ja, ik ben vergeten me voor te stellen. Ik heet Oleg Borzov, ik ben fullstack-ontwikkelaar in het CRM-team voor hypotheekbeheerder in Domklik.
Projectoverzicht
Laten we beginnen met de twee repositories van het project - de backend en de frontend - en de code doornemen.
Backend-gedeelte: Flask+Celery
Voor het backend-gedeelte heb ik een vrij populaire stack gekozen onder Python-ontwikkelaars: het Flask-framework (voor API) en Celery (voor de taakqueue). SQLAlchemy wordt gebruikt als ORM. Alembic wordt toegepast voor migraties. Voor JSON-validatie in de endpoints wordt Marshmallow gebruikt.
In Er is een bestand Readme.md met een gedetailleerde beschrijving van de structuur en instructies voor het starten van het project.
is vrij eenvoudig, bestaat uit 6 endpoints:
/ping— voor de beschikbaarheidscontrole;- endpoints voor registratie, autorisatie, de-autorisatie en het verkrijgen van de geautoriseerde gebruiker;
- een endpoint voor het versturen van e-mail dat een taak in de Celery-queue plaatst.
is nog eenvoudiger, er is slechts één taak send_mail_task.
In de map bevat twee submappen:
dockermet twee Docker-bestanden (base.dockerfilevoor het bouwen van een zelden veranderend basisimage enDockerfilevoor de hoofdconstructies);.env_files— met bestanden voor omgevingsvariabelen voor verschillende omgevingen.
In de hoofdmap van het project bevinden zich vier docker-compose-bestanden:
docker-compose.local.db.ymlvoor het opzetten van een lokale DB voor ontwikkeling;docker-compose.local.workers.ymlvoor het lokaal opzetten van een worker, DB, Redis en RabbitMQ;docker-compose.test.ymlvoor het uitvoeren van tests tijdens de implementatie;docker-compose.ymlvoor de implementatie.
En de laatste interessante map voor ons — . Hierin bevinden zich shell-scripts voor implementatie:
deploy.sh— het starten van migraties en implementatie. Wordt uitgevoerd op de server na de bouw en het uitvoeren van tests in GitHub Actions;rollback.sh— het terugdraaien van containers naar de vorige versie van de build;curl_tg.sh— het versturen van meldingen over de implementatie naar Telegram.
Frontend op Angular
is veel eenvoudiger dan de backend. De frontend bestaat uit drie pagina's:
- De homepage met een formulier voor het verzenden van e-mail en een uitlogknop.
- Inlogpagina.
- Registratiepagina.
De homepage ziet er eenvoudig uit:

In de root liggen twee bestanden Dockerfile en docker-compose.yml, evenals de bekende map .ci-cd met iets minder scripts dan in het backend-repository (de scripts voor het uitvoeren van tests zijn verwijderd).
We starten het project in Plesk
Laten we beginnen met het instellen van Plesk en het creëren van een abonnement voor onze site.
Installeren van extensies
In Plesk hebben we vier extensies nodig:
Dockervoor het beheren en visueel weergeven van de status van containers in de Plesk-admin;Gitvoor het instellen van de deploy-stap op de server;Let's Encryptvoor het genereren (en automatisch verlengen) van gratis TLS-certificaten;Firewallvoor het instellen van filtering van binnenkomend verkeer.
Ze kunnen worden geïnstalleerd via de Plesk-admin in de sectie Extensies:

We zullen de gedetailleerde instellingen van de extensies niet bespreken; voor onze demo-doeleinden zijn de standaardinstellingen voldoende.
Aanmaken van een abonnement en site
Vervolgens moeten we een abonnement maken voor onze site helloworld.nl en daar het subdomein dev.helloworld.nl aan toevoegen.
- We creëren een abonnement voor het domein helloworld.nl en geven de login-wachtwoord op voor de systeemgebruiker:

Onder aan de pagina vink je het vakje aan Beveilig het domein met Let’s Encrypt, als we HTTPS voor de site willen instellen:
- Vervolgens maken we in dit abonnement het subdomein dev.helloworld.nl aan (waarvoor ook een gratis TLS-certificaat kan worden uitgegeven):

Installeren van servercomponenten
We hebben een server met OS Debian Stretch 9.12 en een geïnstalleerde beheerpanelen Plesk Obsidian 18.0.27.
We moeten voor ons project installeren en instellen:
- PostgreSQL (in ons geval zal er één server zijn met twee DB's voor dev- en prod-omgevingen).
- RabbitMQ (hetzelfde, één instantie met verschillende vhosts voor omgevingen).
- Twee instanties van Redis (voor dev- en prod-omgevingen).
- Docker Registry (voor lokale opslag van samengestelde Docker-images).
- UI-interface voor Docker registry.
PostgreSQL
Bij Plesk wordt al een PostgreSQL-database meegeleverd, maar niet de nieuwste versie (op het moment van schrijven ondersteunde Plesk Obsidian Er zijn tal van gedetailleerde instructies voor het installeren van Postgres op Debian online (
), dus ik zal ze niet uitgebreid beschrijven, maar gewoon de commando's geven:), daarom zal ik ze niet in detail beschrijven, ik geef gewoon de opdrachten:
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
Aangezien de standaardinstellingen in PostgreSQL nogal gemiddeld zijn, is het noodzakelijk om de configuratie aan te passen. Dit kan ons helpen : je moet de parameters van je server invoeren en de instellingen in het bestand /etc/postgresql/12/main/postgresql.confvervangen door de voorgestelde. Het is belangrijk op te merken dat dergelijke calculators geen wondermiddel zijn, en de database verder geoptimaliseerd moet worden op basis van jouw hardware, applicaties en de complexiteit van de queries. Maar voor een start is dit voldoende.
Naast de door de calculator voorgestelde instellingen, veranderen we in postgresql.confde standaardpoort 5432 naar een andere (in ons voorbeeld — 53983).
Na het wijzigen van het configuratiebestand herstarten we postgresql-server met de volgende opdracht:
service postgresql restart
We hebben PostgreSQL geïnstalleerd en geconfigureerd. Nu maken we een database, gebruikers voor dev- en prod-omgevingen, en geven we de gebruikers de rechten om de database te beheren:
$ 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
Laten we verder gaan met de installatie van RabbitMQ — de berichtenbroker voor Celery. Het wordt behoorlijk eenvoudig geïnstalleerd op 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
Na de installatie moeten we vhosts, gebruikers aanmaken en de benodigde rechten toekennen:
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
Laten we nu de laatste component voor onze applicatie installeren en configureren — Redis. Dit zal als backend dienen voor het opslaan van de resultaten van Celery-taken.
We zullen twee Docker-containers met Redis opzetten voor de dev- en prod-omgevingen met behulp van de extensie Docker voor Plesk.
- Ga naar Plesk, navigeer naar het gedeelte Extensies, zoek de Docker-extensie en installeer deze (we hebben de gratis versie nodig):

- Ga naar de geïnstalleerde extensie, vind via de zoekfunctie de afbeelding
redis bitnamien installeer de laatste versie:
- Ga naar de gedownloade container en pas de configuratie aan: geef de poort op, de maximale toegewezen hoeveelheid RAM, het wachtwoord in de omgevingsvariabelen en mount de volume:

- Voer stappen 2-3 uit voor de prod-container, wijzig alleen de parameters in de instellingen: poort, wachtwoord, RAM-grootte en het pad naar de map volume op de server:

Docker Registry
Naast de basisservices zou het goed zijn om een eigen Docker-image repository op de server te plaatsen. Gelukkig is de opslagruimte op servers nu redelijk goedkoop (zeker goedkoper dan een abonnement op DockerHub), en het proces van het installeren van een privé-repository is heel eenvoudig.
We willen dat we hebben geïnstalleerd:
- een met wachtwoord beveiligde Docker-repository, toegankelijk via een subdomein ;
- Een UI-interface om de afbeeldingen in de repository te bekijken, toegankelijk via het adres .
Daarvoor:
- Laten we in Plesk twee subdomeinen aanmaken in ons abonnement: docker.helloworld.ru en docker-ui.helloworld.ru, en laten we certificaten van Let's Encrypt voor hen instellen.
- In de map van het subdomein docker.helloworld.ru voegen we het bestand toe
docker-compose.ymlmet de volgende inhoud: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' - Genereer met SSH het bestand .htpasswd voor Basic-authenticatie in de Docker-repository:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Laten we de containers bouwen en opstarten:
docker-compose up -d - En we moeten Nginx doorsturen naar onze containers. Dit kan via Plesk.
De volgende stappen moeten worden uitgevoerd voor de subdomeinen docker.helloworld.ru en docker-ui.helloworld.ru:
In de sectie Dev Tools van onze website gaan we naar Docker Proxy Rules:

En we voegen een regel toe voor het proxen van het binnenkomende verkeer naar onze container:

- Controleer of we kunnen inloggen op onze container vanaf de lokale machine:
$ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password WARNING! Using --password via the CLI is insecure. Use --password-stdin. Login Succeeded - Laten we ook de werking van het subdomein docker-ui.helloworld.ru controleren:

Wanneer u op Browse repositories klikt, toont de browser een venster voor authenticatie waarin u de gebruikersnaam en het wachtwoord voor de repository moet invoeren. Daarna worden we doorgestuurd naar de pagina met de lijst van repositories (deze zal voorlopig leeg zijn):
Poorten openen in Plesk Firewall
Na het installeren en configureren van de componenten moeten we de poorten openen, zodat de componenten toegankelijk zijn vanuit Docker-containers en het externe netwerk.
Laten we bekijken hoe dit moet, aan de hand van de eerder geïnstalleerde Firewall-extensie voor Plesk.
- We gaan naar Tools & Settings > Instellingen > Firewall:

- We gaan naar Pas Plesk Firewall-regels aan > Voeg aangepaste regel toe en open de volgende TCP-poorten voor de Docker-subnet (172.0.0.0/8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- Laten we ook een regel toevoegen die de buitenwereld toegang geeft tot de PostgreSQL-poorten en de managementpanelen van RabbitMQ:

- Pas de regels toe met de knop Wijzigingen toepassen:

CI/CD-configuratie in Github Actions
Laten we beginnen met het spannendste gedeelte — het configureren van de continue integratie- en leveringspipeline voor ons project op de server.
Deze pipeline zal uit twee delen bestaan:
- het bouwen van een image en het uitvoeren van tests (voor de backend) — aan de Github-kant;
- migraties uitvoeren (voor de backend) en containers implementeren — op de server.
Implementatie in Plesk
Laten we eerst de tweede punt behandelen (aangezien de eerste daarvan afhankelijk is).
We zullen het implementatieproces configureren met behulp van de Git-extensie voor Plesk.
Laten we een voorbeeld bekijken met de Prod-omgeving voor de Backend-repository.
- We gaan naar het abonnement van onze Helloworld-website en navigeren naar het Git-subgedeelte:

- Plak de link naar onze Github-repository in het veld 'Remote Git repository' en wijzig de standaardmap
httpdocsin een andere (bijvoorbeeld,/httpdocs/hw_back):
- Kopieer de SSH Public key van de vorige stap en voeg deze toe in de instellingen van Github.
- Klik op OK op het scherm in punt 2, waarna we worden doorgestuurd naar de repositorypagina in Plesk. Nu moeten we de repository instellen zodat deze wordt bijgewerkt bij commits naar de master branch. Ga hiervoor naar Repository-instellingen en sla de waarde op
Webhook URL(deze hebben we later nodig bij de configuratie van Github Actions):
- Voer in het veld Acties op het scherm van de vorige stap het script in voor het starten van de implementatie:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}waarbij:
{REPOSITORY_ABSOLUTE_PATH}— het pad naar de map van de prod backend-repository op de server;
{ENV}— omgeving (dev/prod), in ons gevalprod;
{DOCKER_REGISTRY_HOST}— de host van onze docker repository
{TG_BOT_TOKEN}— de token van de Telegram-bot;
{TG_CHAT_ID}— de ID van de chat/kanaal voor het verzenden van meldingen.Voorbeeld van het 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 - Laten we de gebruiker uit ons abonnement aan de Docker-groep toevoegen (zodat hij de containers kan beheren):
sudo usermod -aG docker helloworld_admin
De ontwikkelomgeving voor de backend-repository en frontend wordt op dezelfde manier ingesteld.
Pipeline voor deployment in Github Actions
Laten we beginnen met het instellen van het eerste deel van onze CI/CD-pipeline in Github Actions.
Backend
De pipeline wordt beschreven in .
Maar voordat we dat bekijken, vullen we de benodigde geheimen in Github in. Ga hiervoor naar Instellingen -> Geheimen:
DOCKER_REGISTRY— het hostadres van onze Docker-repository (docker.helloworld.ru);DOCKER_LOGIN— login voor de Docker-repository;DOCKER_PASSWORD— wachtwoord hiervoor;DEPLOY_HOST— het hostadres waar het Plesk-dashboard beschikbaar is (bijvoorbeeld: :8443 of :8443);DEPLOY_BACK_PROD_TOKEN— token voor deployment naar de prod-repository op de server (we hebben dit gekregen in Deploy in Plesk punt 4);DEPLOY_BACK_DEV_TOKEN— token voor deployment naar de dev-repository op de server.
Het deploymentproces is eenvoudig en bestaat uit drie hoofd stappen:
- het bouwen en publiceren van de afbeelding in onze repository;
- het uitvoeren van tests in een container op basis van de vers gebouwde afbeelding;
- de deployment naar de juiste omgeving afhankelijk van de tak (dev/master).
Frontend
verschilt nauwelijks van de back-end. Het bevat geen stap voor het uitvoeren van tests en de namen van de tokens voor deployment zijn anders. Geheimen voor de front-end repository moeten trouwens apart worden ingevuld.
Website-instellingen
Traffic proxydelen via Nginx
Nou, we zijn aan het einde gekomen. We moeten alleen nog het inkomende en uitgaande verkeer naar onze container via Nginx instellen. Dit proces hebben we al besproken in punt 5 van de Docker Registry-instellingen. Dit moet voor de back-end en front-end in de dev- en prod-omgevingen worden herhaald.
Ik geef enkele screenshots van de instellingen.
Backend

Frontend

Belangrijke opmerking. In de frontend-container worden alle URL's geproxyd naar de backend-container, behalve die beginnen met /api/ — deze worden naar de backend-container geproxyd (daarom moeten alle handlers in de backend-container beginnen met /api/).
Conclusies
Nu moet onze site bereikbaar zijn via de adressen helloworld.ru en dev.helloworld.ru (respectievelijk prod- en dev-omgeving).
Samenvattend hebben we geleerd hoe we een eenvoudige applicatie op Flask en Angular kunnen voorbereiden en een pipeline in Github Actions kunnen instellen voor de deployment op een server die wordt beheerd door Plesk.
Hier zijn de links naar de repositories met de code: , .
Bron: habr.com
















