
În acest articol, voi împărtăși experiența mea de configurare CI/CD utilizând panoul de control Plesk și Github Actions. Astăzi vom învăța cum să implementăm un proiect simplu cu numele simplu „Helloworld”. Este scris în cadrul Flask Python, cu lucrători de țelină și un front-end Angular 8.
Link-uri către depozite: , .
În prima parte a articolului, vom analiza proiectul nostru și părțile sale. În al doilea, ne vom da seama cum să setăm Plesk și să instalăm extensiile și componentele necesare (DB, RabbitMQ, Redis, Docker etc.).
În cea de-a treia parte, vom descoperi în sfârșit cum să configuram o conductă pentru implementarea proiectului nostru pe un server într-un mediu de dezvoltare și producție. Și apoi vom lansa site-ul pe server.
Și da, am uitat să mă prezint. Numele meu este Oleg Borzov, sunt dezvoltator fullstack în echipa CRM pentru managerii de credite ipotecare de la Domclick.
Prezentare generală a proiectului
Mai întâi, să ne uităm la două depozite de proiecte - backend și front - și să trecem peste cod.
Backend: balon + țelină
Pentru partea din spate, am luat o grămadă care este destul de populară printre dezvoltatorii Python: framework-ul Flask (pentru API) și Celery (pentru coada de activități). SQLAchemy este folosit ca ORM. Alambicul este folosit pentru migrații. Pentru validarea JSON în mânere - Marshmallow.
В există un fișier Readme.md cu o descriere detaliată a structurii și instrucțiuni pentru rularea proiectului.
destul de simplu, constă din 6 stilouri:
/ping- pentru a verifica disponibilitatea;- manere pentru înregistrare, autorizare, dezautorizare și obținerea unui utilizator autorizat;
- un handle de e-mail care pune o sarcină în coada de țelină.
si mai usor, exista o singura problema send_mail_task.
În folder există două subdirectoare:
dockercu două Dockerfile (base.dockerfilepentru a construi o imagine de bază care se schimbă rar șiDockerfilepentru ansambluri principale);.env_files- cu fișiere cu variabile de mediu pentru diferite medii.
Există patru fișiere docker-compose la rădăcina proiectului:
docker-compose.local.db.ymlsă creeze o bază de date locală pentru dezvoltare;docker-compose.local.workers.ymlpentru ridicarea locală a lucrătorului, baza de date, Redis și RabbitMQ;docker-compose.test.ymlpentru a rula teste în timpul implementării;docker-compose.ymlpentru desfășurare.
Și ultimul folder care ne interesează - . Conține scripturi shell pentru implementare:
deploy.sh— lansarea migrației și implementării. Rulează pe server după construirea și rularea testelor în Github Actions;rollback.sh- derularea containerelor la versiunea anterioară a ansamblului;curl_tg.sh- trimiterea notificărilor de implementare către Telegram.
Frontend pe Angular
mult mai simplu decât al lui Beck. Fața este formată din trei pagini:
- Pagina principală cu un formular pentru trimiterea e-mailului și un buton de ieșire.
- Pagina de logare.
- Pagina de înregistrare.
Pagina principală pare ascetică:

Există două fișiere la rădăcină Dockerfile и docker-compose.yml, precum și folderul familiar .ci-cd cu puțin mai puține scripturi decât în depozitul din spate (scripturi eliminate pentru rularea testelor).
Pornirea unui proiect în Plesk
Să începem prin a configura Plesk și a crea un abonament pentru site-ul nostru.
Instalarea extensiilor
În Plesk, avem nevoie de patru extensii:
Dockerpentru a gestiona și afișa vizual starea containerelor în panoul de administrare Plesk;Gitpentru a configura pasul de implementare pe server;Let's Encryptpentru a genera (și reînnoi automat) certificate TLS gratuite;Firewallpentru a configura filtrarea traficului de intrare.
Le puteți instala prin panoul de administrare Plesk din secțiunea Extensii:

Nu vom lua în considerare setările detaliate pentru extensii, setările implicite vor fi potrivite pentru scopurile noastre demo.
Creați un abonament și un site
Apoi, trebuie să creăm un abonament pentru site-ul nostru helloworld.ru și să adăugăm acolo subdomeniul dev.helloworld.ru.
- Creați un abonament pentru domeniul helloworld.ru și specificați parola de conectare pentru utilizatorul sistemului:

Bifați caseta din partea de jos a paginii Securizează domeniul cu Let's Encryptdacă vrem să setăm HTTPS pentru site:
- Apoi, în acest abonament, creați un subdomeniu dev.helloworld.ru (pentru care puteți elibera și un certificat TLS gratuit):

Instalarea componentelor serverului
Avem un server cu OS Debian Întindere 9.12 și instalat panoul de control Plesk Obsidian 18.0.27.
Trebuie să instalăm și să configurăm pentru proiectul nostru:
- PostgreSQL (în cazul nostru, va exista un server cu două baze de date pentru mediile de dezvoltare și producție).
- RabbitMQ (aceeași, aceeași instanță cu vhost-uri diferite pentru medii).
- Două instanțe Redis (pentru medii de dezvoltare și producție).
- Docker Registry (pentru stocarea locală a imaginilor Docker construite).
- UI pentru registrul Docker.
PostgreSQL
Plesk vine deja cu PostgreSQL DBMS, dar nu cea mai recentă versiune (la momentul scrierii Plesk Obsidian Versiunile Postgres 8.4–10.8). Dorim cea mai recentă versiune pentru aplicația noastră (12.3 la momentul scrierii acestui articol), așa că o vom instala manual.
Подробных инструкций по установке Postgres на Debian в сети полно (), așa că nu le voi descrie în detaliu, voi da doar comenzile:
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
Având în vedere că PostgreSQL are setări implicite destul de mediocre, este necesară corectarea configurației. Acest lucru ne va ajuta : trebuie să introduceți parametrii serverului dvs. și să înlocuiți setările din fișier /etc/postgresql/12/main/postgresql.confcelor oferite. Trebuie remarcat aici că astfel de calculatoare nu sunt un glonț magic, iar baza ar trebui reglată mai precis, pe baza hardware-ului, aplicației și complexității interogărilor. Dar acest lucru este suficient pentru a începe.
Pe lângă setările propuse de calculator, mai schimbăm postgresql.confportul implicit 5432 la altul (în exemplul nostru - 53983).
După modificarea fișierului de configurare, reporniți postgresql-server cu comanda:
service postgresql restart
Am instalat și configurat PostgreSQL. Acum să creăm o bază de date, utilizatori pentru medii de dezvoltare și producție și să acordăm utilizatorilor drepturi de a gestiona baza de date:
$ 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
Iepure MQ
Перейдем к установке 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
După instalare, trebuie să creăm vhosts, utilizatorilor și acordați drepturile necesare:
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
Acum haideți să instalăm și să configurăm ultima componentă pentru aplicația noastră - Redis. Va fi folosit ca backend pentru stocarea rezultatelor sarcinilor de țelină.
Vom ridica două containere Docker cu Redis pentru medii de dezvoltare și producție folosind extensia Docker pentru Plesk.
- Mergem la Plesk, mergem la secțiunea Extensii, căutăm extensia Docker și o instalăm (avem nevoie de o versiune gratuită):

- Accesați extensia instalată, găsiți imaginea prin căutare
redis bitnamiși instalează cea mai recentă versiune:
- Intrăm în containerul descărcat și ajustăm configurația: specificăm portul, dimensiunea maximă a RAM alocată, parola în variabilele de mediu și montăm volumul:

- Efectuăm pașii 2-3 pentru containerul de produse, în setări modificăm doar parametrii: port, parolă, dimensiunea RAM și calea către folderul de volum de pe server:

Registrul Docker
Pe lângă serviciile de bază, ar fi bine să vă puneți propriul depozit de imagini Docker pe server. Din fericire, spațiul pe server este acum destul de ieftin (cu siguranță mai ieftin decât un abonament DockerHub), iar procesul de configurare a unui depozit privat este foarte simplu.
Vrem să avem:
- depozit Docker protejat prin parolă accesibil pe un subdomeniu ;
- UI pentru vizualizarea imaginilor în depozit, disponibil la .
Pentru a face acest lucru:
- Să creăm două subdomenii în Plesk în abonamentul nostru: docker.helloworld.ru și docker-ui.helloworld.ru și să configuram certificatele Let's Encrypt pentru ele.
- Adăugați fișierul în folderul subdomeniului docker.helloworld.ru
docker-compose.ymlcu conținut ca acesta: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' - Sub SSH, vom genera fișierul .htpasswd pentru autorizarea de bază în depozitul Docker:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Colectați și ridicați containerele:
docker-compose up -d - Și trebuie să redirecționăm Nginx către containerele noastre. Acest lucru se poate face prin Plesk.
Următorii pași trebuie efectuati pentru subdomeniile docker.helloworld.ru și docker-ui.helloworld.ru:
În secțiunea Instrumente Dev accesați site-ul nostru Reguli Docker Proxy:

Și adăugați o regulă pentru a proxy traficul de intrare în containerul nostru:

- Verificăm că ne putem conecta la containerul nostru de pe mașina locală:
$ 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 - Să verificăm și funcționarea subdomeniului docker-ui.helloworld.ru:

Când faceți clic pe Răsfoire depozite, browserul va afișa o fereastră de autorizare în care va trebui să introduceți numele de utilizator și parola pentru depozit. După aceea, vom fi transferați pe o pagină cu o listă de depozite (deocamdată, aceasta va fi goală pentru tine):
Deschiderea porturilor în Plesk Firewall
După instalarea și configurarea componentelor, trebuie să deschidem porturi astfel încât componentele să fie accesibile din containerele Docker și din rețeaua externă.
Să vedem cum să facem acest lucru folosind extensia Firewall pentru Plesk pe care am instalat-o mai devreme.
- Mergi la Instrumente și setări > Setări > Paravan de protecție:

- Mergi la Modificați regulile Plesk Firewall > Adăugați o regulă personalizată și deschideți următoarele porturi TCP pentru subrețeaua Docker (172.0.0.0 / 8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- Vom adăuga, de asemenea, o regulă care va deschide porturile PostgreSQL și panourile de gestionare RabbitMQ către lumea exterioară:

- Aplicați regulile folosind butonul Aplicați modificări:

Configurarea CI/CD în Github Actions
Să trecem la partea cea mai interesantă - crearea unei conducte de integrare continuă și livrarea proiectului nostru pe server.
Această conductă va consta din două părți:
- construirea unei imagini și rularea testelor (pentru backend) - pe partea Github;
- rularea migrațiilor (pentru backend) și implementarea containerelor - pe server.
Implementați pe Plesk
Să ne ocupăm mai întâi de al doilea punct (pentru că primul depinde de el).
Vom configura procesul de implementare folosind extensia Git pentru Plesk.
Luați în considerare un exemplu cu un mediu Prod pentru un depozit de backend.
- Mergem la abonamentul site-ului nostru Helloworld și mergem la subsecțiunea Git:

- Introduceți un link către depozitul nostru Github în câmpul „Depozitar Git la distanță” și schimbați folderul implicit
httpdocsla altul (ex./httpdocs/hw_back):
- Copiați cheia publică SSH de la pasul anterior și este în setările Github.
- Faceți clic pe OK pe ecran la pasul 2, după care vom fi redirecționați către pagina de depozit din Plesk. Acum trebuie să configuram depozitul pentru a fi actualizat la comiterea în ramura principală. Pentru a face acest lucru, accesați Setări pentru depozit și salvați valoarea
Webhook URL(vom avea nevoie de el mai târziu când configurați Github Actions):
- În câmpul Acțiuni de pe ecran din paragraful anterior, introduceți scriptul pentru a lansa implementarea:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}în cazul în care:
{REPOSITORY_ABSOLUTE_PATH}- calea către folderul prod al depozitului backend de pe server;
{ENV}- mediu (dev/prod), în cazul nostruprod;
{DOCKER_REGISTRY_HOST}- gazda depozitului nostru docker
{TG_BOT_TOKEN}— Jeton de bot Telegram;
{TG_CHAT_ID}— ID-ul chat-ului/canalului pentru trimiterea notificărilor.Exemplu 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 - Adăugați un utilizator din abonamentul nostru la grupul Docker (pentru a putea gestiona containerele):
sudo usermod -aG docker helloworld_admin
Mediul de dezvoltare pentru depozitul de backend și frontend-ul sunt configurate în același mod.
Conducta de implementare în Github Actions
Să trecem la configurarea primei părți a conductei noastre CI/CD în Github Actions.
Backend
Conducta este descrisă în .
Dar înainte de a-l analiza, să completăm variabilele Secret de care avem nevoie în Github. Pentru a face acest lucru, accesați Setări -> Secrete:
DOCKER_REGISTRY- gazda depozitului nostru Docker (docker.helloworld.ru);DOCKER_LOGIN- conectați-vă la depozitul Docker;DOCKER_PASSWORD- parola acestuia;DEPLOY_HOST— gazdă unde este disponibil panoul de administrare Plesk (exemplu: : 8443 sau :8443);DEPLOY_BACK_PROD_TOKEN- un token pentru implementare în prod-repository de pe server (l-am primit în Deployment in Plesk p. 4);DEPLOY_BACK_DEV_TOKEN- token pentru implementare în depozitul de dezvoltare de pe server.
Procesul de implementare este simplu și constă din trei pași principali:
- construirea și publicarea imaginii în depozitul nostru;
- rularea de teste într-un container pe baza unei imagini proaspăt construite;
- implementare în mediul dorit în funcție de ramură (dev/master).
Frontend
puțin diferit de cel al lui Beck. Îi lipsește un pas cu rularea testelor și schimbă numele token-urilor pentru implementare. Apropo, secretele pentru depozitul frontal trebuie completate separat.
Configurarea site-ului
Traficul proxy prin Nginx
Ei bine, am ajuns la final. Rămâne doar să configurați proxy traficul de intrare și de ieșire către containerul nostru prin Nginx. Am acoperit deja acest proces la pasul 5 din configurarea Docker Registry. Același lucru ar trebui repetat pentru părțile din spate și din față în mediile de dezvoltare și producție.
Voi oferi capturi de ecran ale setărilor.
Backend

Frontend

Lămurire importantă. Toate adresele URL vor fi trimise proxy către containerul de interfață, cu excepția celor care încep cu /api/ - vor fi proxy de containerul din spate (deci în containerul din spate, toți manipulatorii trebuie să înceapă cu /api/).
Rezultatele
Acum, site-ul nostru ar trebui să fie disponibil la helloworld.ru și dev.helloworld.ru (prod- și, respectiv, dev-medii).
În total, am învățat cum să pregătim o aplicație simplă în Flask și Angular și să configuram o conductă în Github Actions pentru a o implementa pe un server care rulează Plesk.
Voi duplica link-urile către depozite cu codul: , .
Sursa: www.habr.com
















