
In dit artikel deel ik mijn ervaring met het instellen van CI/CD met behulp van het Plesk-configuratiescherm en Github Actions. Vandaag zullen we leren hoe we een eenvoudig project kunnen implementeren met de ongecompliceerde naam "Helloworld". Het is geschreven in het Flask Python-framework, met Celery-werkers en een Angular 8-frontend.
Links naar opslagplaatsen: , .
In het eerste deel van het artikel zullen we ons project en zijn onderdelen bekijken. In de tweede zullen we uitzoeken hoe Plesk moet worden ingesteld en de benodigde extensies en componenten moeten worden geïnstalleerd (DB, RabbitMQ, Redis, Docker, enz.).
In het derde deel zullen we eindelijk uitzoeken hoe we een pijplijn kunnen opzetten voor het implementeren van ons project op een server in een dev- en prod-omgeving. En dan lanceren we de site op de server.
En ja, ik vergat mezelf voor te stellen. Mijn naam is Oleg Borzov, ik ben een fullstack ontwikkelaar in het CRM-team voor hypotheekmanagers bij Domclick.
Projectoverzicht
Laten we eerst eens kijken naar twee projectrepository's - backend en front - en de code doornemen.
Backend: Flask+Selderij
Voor het achterste gedeelte heb ik een aantal genomen dat behoorlijk populair is onder Python-ontwikkelaars: het Flask-framework (voor de API) en Celery (voor de taakwachtrij). SQLAchemy wordt gebruikt als ORM. Alambic wordt gebruikt voor migraties. Voor JSON-validatie in handgrepen - Marshmallow.
В er is een Readme.md-bestand met een gedetailleerde beschrijving van de structuur en instructies voor het uitvoeren van het project.
vrij ongecompliceerd, bestaat uit 6 pennen:
/ping- beschikbaarheid controleren;- handvatten voor registratie, autorisatie, de-autorisatie en het verkrijgen van een geautoriseerde gebruiker;
- een e-mailhandle die een taak in de wachtrij van Celery plaatst.
nog eenvoudiger, er is maar één probleem send_mail_task.
In map er zijn twee submappen:
dockermet twee Dockerfiles (base.dockerfileom een zelden veranderend basisbeeld op te bouwen enDockerfilevoor hoofdsamenstellingen);.env_files- met bestanden met omgevingsvariabelen voor verschillende omgevingen.
Er zijn vier docker-compose-bestanden in de hoofdmap van het project:
docker-compose.local.db.ymleen lokale database opzetten voor ontwikkeling;docker-compose.local.workers.ymlvoor lokale opvoeding van de werknemer, database, Redis en RabbitMQ;docker-compose.test.ymlom tests uit te voeren tijdens de implementatie;docker-compose.ymlvoor inzet.
En de laatste map waarin we geïnteresseerd zijn - . Het bevat shell-scripts voor implementatie:
deploy.sh— lancering van migratie en implementatie. Draait op de server na het bouwen en uitvoeren van tests in Github Actions;rollback.sh- rollback van containers naar de vorige versie van de assembly;curl_tg.sh- het verzenden van implementatiemeldingen naar Telegram.
Frontend op Angular
veel eenvoudiger dan die van Beck. De voorkant bestaat uit drie pagina's:
- Hoofdpagina met een formulier voor het verzenden van e-mail en een exit-knop.
- Login pagina.
- Registratie pagina.
De hoofdpagina ziet er ascetisch uit:

Er zijn twee bestanden in de root Dockerfile и docker-compose.yml, evenals de vertrouwde map .ci-cd met iets minder scripts dan in de back-repository (verwijderde scripts voor het uitvoeren van tests).
Een project starten in Plesk
Laten we beginnen met het opzetten van Plesk en het aanmaken van een abonnement voor onze site.
Extensies installeren
In Plesk hebben we vier extensies nodig:
Dockerom de status van containers te beheren en visueel weer te geven in het Plesk-beheerderspaneel;Gitom de implementatiestap op de server te configureren;Let's Encryptom gratis TLS-certificaten te genereren (en automatisch te verlengen);Firewallom het filteren van inkomend verkeer te configureren.
U kunt ze installeren via het Plesk-beheerderspaneel in het gedeelte Extensies:

We houden geen rekening met de gedetailleerde instellingen voor extensies, de standaardinstellingen zijn voldoende voor onze demodoeleinden.
Maak een abonnement en site aan
Vervolgens moeten we een abonnement maken voor onze helloworld.ru-website en daar het dev.helloworld.ru-subdomein toevoegen.
- Maak een abonnement aan voor het domein helloworld.ru en specificeer het inlogwachtwoord voor de systeemgebruiker:

Vink het vakje onderaan de pagina aan Beveilig het domein met Let's Encryptals we HTTPS voor de site willen instellen:
- Maak vervolgens in dit abonnement een subdomein dev.helloworld.ru aan (waarvoor u ook een gratis TLS-certificaat kunt uitgeven):

Servercomponenten installeren
We hebben een server met OS Debian Uitrekken 9.12 en geïnstalleerd bedieningspaneel Plesk Obsidiaan 18.0.27.
We moeten installeren en configureren voor ons project:
- PostgreSQL (in ons geval is er één server met twee databases voor dev- en prod-omgevingen).
- RabbitMQ (dezelfde, dezelfde instantie met verschillende vhosts voor omgevingen).
- Twee Redis-instanties (voor dev- en prod-omgevingen).
- Docker Registry (voor lokale opslag van ingebouwde Docker-images).
- UI voor Docker-register.
PostgreSQL
Plesk wordt al geleverd met PostgreSQL DBMS, maar niet de nieuwste versie (op het moment van schrijven Plesk Obsidian Postgres-versies 8.4–10.8). We willen de nieuwste versie voor onze applicatie (12.3 op het moment van schrijven), dus we zullen deze handmatig installeren.
Подробных инструкций по установке Postgres на Debian в сети полно (), dus ik zal ze niet in detail beschrijven, ik zal alleen de commando's geven:
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 PostgreSQL nogal middelmatige standaardinstellingen heeft, is het noodzakelijk om de configuratie te corrigeren. Dit zal ons helpen : u moet de parameters van uw server invoeren en de instellingen in het bestand vervangen /etc/postgresql/12/main/postgresql.confaan die aangeboden. Hierbij moet worden opgemerkt dat dergelijke rekenmachines geen wondermiddel zijn en dat de basis nauwkeuriger moet worden afgestemd op basis van uw hardware, toepassing en complexiteit van de zoekopdracht. Maar dit is genoeg om te beginnen.
Naast de instellingen voorgesteld door de rekenmachine, veranderen we ook in postgresql.confde standaardpoort 5432 naar een andere (in ons voorbeeld - 53983).
Herstart postgresql-server na het wijzigen van het configuratiebestand met de opdracht:
service postgresql restart
We hebben PostgreSQL geïnstalleerd en geconfigureerd. Laten we nu een database maken, gebruikers voor dev- en prod-omgevingen, en gebruikers rechten geven 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
Перейдем к установке RabbitMQ — брокера сообщений для Celery. Ставится он на 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 creëren vhosts, gebruikers en verleen de nodige rechten:
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 het laatste onderdeel voor onze applicatie installeren en configureren - Redis. Het zal worden gebruikt als een backend voor het opslaan van de resultaten van Celery-taken.
We zullen twee Docker-containers verhogen met Redis voor dev- en prod-omgevingen met behulp van de extensie Docker voor Plesk.
- We gaan naar Plesk, gaan naar het gedeelte Extensies, zoeken naar de Docker-extensie en installeren deze (we hebben een gratis versie nodig):

- Ga naar de geïnstalleerde extensie, zoek de afbeelding via de zoekopdracht
redis bitnamien installeer de laatste versie:
- We gaan naar de gedownloade container en passen de configuratie aan: specificeer de poort, de maximale toegewezen RAM-grootte, het wachtwoord in de omgevingsvariabelen en koppel het volume:

- We voeren stappen 2-3 uit voor de prod-container, in de instellingen wijzigen we alleen de parameters: poort, wachtwoord, RAM-grootte en pad naar de volumemap op de server:

Docker-register
Naast de basisdiensten zou het fijn zijn om je eigen Docker image repository op de server te zetten. Gelukkig is serverruimte nu vrij goedkoop (zeker goedkoper dan een DockerHub-abonnement) en is het opzetten van een privérepository heel eenvoudig.
We willen hebben:
- met een wachtwoord beveiligde Docker-repository toegankelijk op een subdomein ;
- UI voor het bekijken van afbeeldingen in de repository, beschikbaar op .
Om dit te doen:
- Laten we twee subdomeinen maken in Plesk in ons abonnement: docker.helloworld.ru en docker-ui.helloworld.ru, en Let's Encrypt-certificaten voor hen configureren.
- Voeg het bestand toe aan de subdomeinmap docker.helloworld.ru
docker-compose.ymlmet inhoud als deze: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' - Onder SSH genereren we het .htpasswd-bestand voor basisautorisatie in de Docker-repository:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Containers verzamelen en optillen:
docker-compose up -d - En we moeten Nginx omleiden 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 paragraaf Dev Tools onze site ga naar Docker-proxyregels:

En voeg een regel toe om binnenkomend verkeer naar onze container te proxyen:

- We controleren 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 Bladeren door repository's klikt, geeft de browser een autorisatievenster weer waarin u de gebruikersnaam en het wachtwoord voor de repository moet invoeren. Daarna worden we overgebracht naar een pagina met een lijst met repositories (voorlopig is deze voor u leeg):
Poorten openen in Plesk Firewall
Na het installeren en configureren van de componenten moeten we poorten openen zodat de componenten toegankelijk zijn vanuit Docker-containers en het externe netwerk.
Laten we eens kijken hoe we dit kunnen doen met de Firewall-extensie voor Plesk die we eerder hebben geïnstalleerd.
- Ga naar Tools & instellingen > Instellingen > Firewall:

- Ga naar Pas Plesk Firewall-regels aan > Voeg aangepaste regel toe en open de volgende TCP-poorten voor het Docker-subnet (172.0.0.0 / 8):
KonijnMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- We zullen ook een regel toevoegen die PostgreSQL-poorten en RabbitMQ-beheerpanelen opent voor de buitenwereld:

- Pas de regels toe met de knop Wijzigingen toepassen:

CI/CD instellen in Github Actions
Laten we naar het meest interessante deel gaan: het opzetten van een continue integratiepijplijn en het leveren van ons project aan de server.
Deze pijplijn bestaat uit twee delen:
- een afbeelding bouwen en tests uitvoeren (voor de backend) - aan de kant van Github;
- migraties uitvoeren (voor de backend) en containers implementeren - op de server.
Implementeer naar Plesk
Laten we eerst het tweede punt behandelen (omdat het eerste ervan afhangt).
We zullen het implementatieproces configureren met behulp van de Git-extensie voor Plesk.
Overweeg een voorbeeld met een Prod-omgeving voor een Backend-repository.
- We gaan naar het abonnement van onze Helloworld-website en gaan naar de subsectie Git:

- Plaats een link naar onze Github-repository in het veld "Remote Git-repository" en wijzig de standaardmap
httpdocsnaar een ander (bijv./httpdocs/hw_back):
- Kopieer de openbare SSH-sleutel uit de vorige stap en het is in Github-instellingen.
- Klik op OK op het scherm in stap 2, waarna we worden doorgestuurd naar de repository-pagina in Plesk. Nu moeten we de repository configureren om te worden bijgewerkt bij commits naar de master branch. Ga hiervoor naar Opslagplaats instellingen en sla de waarde op
Webhook URL(we hebben het later nodig bij het instellen van Github Actions):
- Voer in het veld Acties op het scherm uit de vorige paragraaf het script in om de implementatie te starten:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}waar:
{REPOSITORY_ABSOLUTE_PATH}- pad naar de prod-map van de backend-repository op de server;
{ENV}- omgeving (dev / prod), in ons gevalprod;
{DOCKER_REGISTRY_HOST}- de host van onze docker-repository
{TG_BOT_TOKEN}— Telegram-bottoken;
{TG_CHAT_ID}— ID van de chat/het kanaal voor het verzenden van meldingen.Scriptvoorbeeld:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - Voeg een gebruiker uit ons abonnement toe aan de Docker-groep (zodat ze containers kunnen beheren):
sudo usermod -aG docker helloworld_admin
De ontwikkelomgeving voor de backend repository en de frontend zijn op dezelfde manier ingericht.
Implementatiepijplijn in Github Actions
Laten we verder gaan met het opzetten van het eerste deel van onze CI/CD-pijplijn in Github Actions.
backend
De pijpleiding wordt beschreven in .
Maar laten we, voordat we het gaan ontleden, de geheime variabelen invullen die we nodig hebben in Github. Ga hiervoor naar Instellingen -> Geheimen:
DOCKER_REGISTRY- de host van onze Docker-repository (docker.helloworld.ru);DOCKER_LOGIN- log in op de Docker-repository;DOCKER_PASSWORD- wachtwoord ervoor;DEPLOY_HOST— host waar het Plesk-beheerderspaneel beschikbaar is (voorbeeld: :8443 of :8443);DEPLOY_BACK_PROD_TOKEN- een token voor implementatie naar de prod-repository op de server (we hebben het in Implementatie in Plesk p. 4);DEPLOY_BACK_DEV_TOKEN- token voor implementatie naar de dev-repository op de server.
Het implementatieproces is eenvoudig en bestaat uit drie hoofdstappen:
- het bouwen en publiceren van de afbeelding in onze repository;
- tests uitvoeren in een container op basis van een vers gebouwde afbeelding;
- implementatie naar de gewenste omgeving, afhankelijk van de branch (dev/master).
Frontend
beetje anders dan die van Beck. Het mist een stap met het uitvoeren van tests en verandert de namen van tokens voor implementatie. Geheimen voor de frontrepository moeten trouwens apart worden ingevuld.
Site-opstelling
Proxy verkeer via Nginx
Nou, we zijn aan het einde gekomen. Het blijft alleen om de proxying van inkomend en uitgaand verkeer naar onze container via Nginx te configureren. We hebben dit proces al behandeld in stap 5 van de installatie van Docker Registry. Hetzelfde moet worden herhaald voor de voor- en achterkant in dev- en prod-omgevingen.
Ik zal screenshots van de instellingen verstrekken.
backend

Frontend

ажное очнение. Alle URL's worden via een proxy naar de frontend-container geleid, behalve de URL's die beginnen met /api/ - ze worden geproxyeerd naar de achterste container (dus in de achterste container moeten alle handlers beginnen met /api/).
Resultaten van
Nu zou onze site beschikbaar moeten zijn op helloworld.ru en dev.helloworld.ru (respectievelijk prod- en dev-omgevingen).
In totaal hebben we geleerd hoe we een eenvoudige applicatie in Flask en Angular kunnen voorbereiden en hoe we een pijplijn in Github Actions kunnen opzetten om deze uit te rollen naar een server waarop Plesk draait.
Ik zal de links naar de repositories dupliceren met de code: , .
Bron: www.habr.com
















