
Në këtë artikull do të ndaj përvojën time në konfigurimin e CI/CD me përdorimin e panelit të kontrollit Plesk dhe Github Actions. Sot do të mësojmë si të deploy një projekt të thjeshtë me titullin "Helloworld". Ai është shkruar në framework-un Python Flask, me punëtorë në Celery dhe frontend në Angular 8.
Linket e depove: , .
Në pjesën e parë të artikullit do të hedhim një vështrim mbi projektin tonë dhe pjesët e tij. Në të dytën, do të kuptojmë si të konfiguroni Plesk dhe të instaloni zgjatjet dhe komponentët e nevojshëm (DB, RabbitMQ, Redis, Docker, etj.).
Në pjesën e tretë, përfundimisht do të kuptojmë si të configure pipeline për të deploy projektin tonë në server në mjediset dev dhe prod. Pas kësaj, do ta lancojmë sitin në server.
Dhe po, harrova të prezantohem. Emri im është Oleg Borzov, unë jam zhvillues fullstack në ekipin CRM për menaxherët e kredive hipoteke në Domklik.
Përmbledhja e projektit
Për fillim, do të shqyrtojmë dy repozita të projektit - backend dhe frontend - dhe do të kalojmë përmes kodit.
Pjesa backend: Flask+Celery
Për backend kam marrë një kombinim mjaft të njohur ndër zhvilluesit e Python: frameworkun Flask (për API) dhe Celery (për radhën e detyrave). Përdoret SQLAlchemy si ORM. Për migrimet aplikohet Alembic. Për vërtetimin e JSON në endpoint-e përdoret Marshmallow.
Në ekziston një skedë Readme.md me një përshkrim të detajuar të strukturës dhe udhëzimeve për nisjen e projektit.
është mjaft e thjeshtë, përbëhet nga 6 endpoint-e:
/pingâ pĂ«r kontrollimin e disponueshmĂ«risĂ«;- endpoint-e pĂ«r regjistrim, autentifikim, çautentifikim dhe pĂ«r tĂ« marrĂ« pĂ«rdoruesin e identifikuar;
- endpoint për dërgimin e email-it, që vendos një detyrë në radhën Celery.
është edhe më e thjeshtë, aty ka vetëm një detyrë send_mail_task.
Në dosjen janë dy nënfoldera:
dockerme dy skeda Docker (base.dockerfilepĂ«r ndĂ«rtimin e imazhit tĂ« bazĂ«s qĂ« ndryshohet rrallĂ« dheDockerfilepĂ«r ndĂ«rtimet kryesore);.env_filesâ me skedarĂ« pĂ«r variablat mjedisore pĂ«r ambiente tĂ« ndryshme.
Në rrënjë të projektit ndodhen katër skedarë docker-compose:
docker-compose.local.db.ymlpër ngritjen e bazës së të dhënave lokale për zhvillim;docker-compose.local.workers.ymlpër ngritjen lokale të punonjësve, bazës së të dhënave, Redis dhe RabbitMQ;docker-compose.test.ymlpër ekzekutimin e testeve gjatë shpërndarjes;docker-compose.ymlpër deploy.
Dhe folderi i fundit interesant pĂ«r ne â . NĂ« tĂ« gjetur skriptet shell pĂ«r vendosjen:
deploy.shâ nisja e migrimit dhe vendosjes. Aktivizohet nĂ« server pas ndĂ«rtimit dhe pĂ«rmbushjes sĂ« testeve nĂ« Github Actions;rollback.shâ rikthimi i kontejnerĂ«ve nĂ« versionin e mĂ«parshĂ«m tĂ« ndĂ«rtimit;curl_tg.shâ dĂ«rgimi i njoftimeve pĂ«r vendosjen nĂ« Telegram.
Frontend në Angular
është shumë më e thjeshtë se ajo e backend-it. Fronti përbëhet nga tri faqe:
- Faqja kryesore me një formë për dërgimin e email-it dhe një buton për daljen.
- Faqja e hyrjes.
- Faqja e regjistrimit.
Faqja kryesore duket askeptike:

Në rrënjë ndodhen dy skedarë Dockerfile dhe docker-compose.yml, si dhe një dosje e njohur për ne .ci-cd me një numër pak më të vogël skriptesh se në repo-n e backend-it (skriptet për fillimin e testeve janë larguar).
Krijojmë projektin në Plesk
Le të fillojmë me konfigurimin e Plesk dhe krijimin e abonimit për sajtin tonë.
Instalimi i shtesave
Në Plesk do na nevojiten katër shtesa:
Dockerpër menaxhimin dhe shfaqjen vizuale të gjendjes së kontejnerëve në adminin e Plesk;Gitpër konfigurimin e hapit të vendosjes në server;Let's Encryptpër gjenerimin (dhe rinovimin automatik) e certifikatave falas TLS;Firewallpër konfigurimin e filtrimit të trafikut që hyn.
Mund t'i instalojmë ato përmes adminit të Plesk në seksionin Shtesat:

Ne do të merremi me konfigurimin e detajuar të shtesave, konfigurimet e paracaktuara do të mjaftojnë për qëllimet tona demo.
Krijimi i një abonimi dhe një faqjeje
Më pas na nevojitet të krijojmë një abonim për faqen tonë helloworld.ru dhe të shtojmë atje subdomain-in dev.helloworld.ru.
- Krijojmë një abonim për domenin helloworld.ru dhe specifikojmë emrin e përdoruesit dhe fjalëkalimin për përdoruesin sistemik:

PoshtĂ« faqes, vendosim shenjĂ«n e kontrollit Siguroni domenin me Letâs Encrypt, nĂ«se dĂ«shirojmĂ« tĂ« konfigurojmĂ« HTTPS pĂ«r faqen:
- Më pas në këtë abonim krijojmë subdomain-in dev.helloworld.ru (për të cilin gjithashtu mund të lëshojmë një certifikatë falas TLS):

Instalimi i komponentëve serverikë
Ne kemi në dispozicion një server me OS Debian Stretch 9.12 dhe me panelin e menaxhimit të instaluar Plesk Obsidian 18.0.27.
Na nevojitet të instalojmë dhe konfigurojmë për projektin tonë:
- PostgreSQL (në rastin tonë do të jetë një server me dy DB për ambientet dev dhe prod).
- RabbitMQ (po ashtu, një instancë me vhosts të ndryshëm për ambientet).
- Dy instanca Redis (për ambientet dev dhe prod).
- Docker Registry (për ruajtjen lokale të imazheve të përmbledhura Docker).
- UI-interfaca për Docker registry.
PostgreSQL
Me Plesk vjen edhe një DBMS PostgreSQL, megjithatë jo në versionin më të ri (në momentin e shkrimit të artikullit Plesk Obsidian Ne duam të vendosim versionin më të fundit të Postgres (12.3 në momentin e shkruajtjes së këtij artikulli) për aplikacionin tonë, prandaj do ta instalojmë manualisht.
Ka shumĂ« udhĂ«zime tĂ« detajuara pĂ«r instalimin e Postgres nĂ« Debian nĂ« internet (), prandaj nuk do tĂ« pĂ«rshkruaj me detaje, vetĂ«m do tâi jap komandat:
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
Duke marrë parasysh që PostgreSQL ka konfigurime mjaft mesatare nga fabrika, është e nevojshme të rregullojmë konfigurimin. Këtë do ta ndihmojmë : duhet të vendosni parametrat e serverit tuaj dhe të zëvendësoni konfigurimet në skedarin /etc/postgresql/12/main/postgresql.confme ato të sugjeruara. Duhet përmendur se kalkulatorët e tillë nuk janë zgjidhja magjike, dhe baza duhet të tuneohet më saktësisht, duke u bazuar në harduerin tuaj, aplikacionin dhe kompleksitetin e kërkesave. Por për fillimin, kjo është e mjaftueshme.
PĂ«rveç konfigurimeve tĂ« propozuara nga kalkulatori, gjithashtu ndryshojmĂ« nĂ« postgresql.confportin 5432 tĂ« vendosur nĂ« mĂ«nyrĂ« tĂ« paracaktuar me njĂ« tjetĂ«r (nĂ« shembullin tonĂ« â 53983).
Pas ndryshimit të skedarit të konfigurimit, rishtazgjedhim postgresql-server me komandën:
service postgresql restart
Ne kemi instaluar dhe konfiguruar PostgreSQL. Tani do të krijojmë BAZAT e të dhënave, përdoruesit për ambientet dev dhe prod, dhe do t'u japim përdoruesve të drejtat për të menaxhuar bazën e të dhënave:
$ 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
TĂ« kalojmĂ« te instalimi i RabbitMQ â brokeri i mesazheve pĂ«r Celery. Instalimi Ă«shtĂ« mjaft i thjeshtĂ« nĂ« 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
Pas instalimit, ne duhet të krijojmë vhosts, përdoruesit dhe t'u japim të drejtat e nevojshme:
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
Tani do tĂ« instalojmĂ« dhe konfigurojmĂ« komponentin e fundit pĂ«r aplikacionin tonĂ« â Redis. Ai do tĂ« pĂ«rdoret si backend pĂ«r ruajtjen e rezultateve tĂ« detyrave Celery.
Ne do të ngremë dy kontejnerë Docker me Redis për ambientet dev dhe prod me ndihmën e zgjatjes Docker për Plesk.
- Hymë në Plesk, kalojmë te seksioni Zgjerime, kërkojmë zgjerimin Docker dhe e instalojmë (na nevojitet versioni falas):

- Kalo në zgjerimin e instaluar, kërko me kërkimin imazhin
redis bitnamidhe vendos versionin më të fundit:
- Hymë në kontejnerin e shkarkuar dhe korrigjojmë konfigurimin: përcaktojmë portin, madhësinë maksimale të RAM-it, fjalëkalimin në variablat e mjedisit, dhe montojmë vëllimin:

- Kryejmë hapat 2-3 për kontejnerin prod, vetëm ndryshojmë parametrat: portin, fjalëkalimin, madhësinë e RAM-it dhe rrugën për dosjen e vëllimit në server:

Docker Registry
Përveç shërbimeve bazike, do të ishte mirë të vendosnim në serverin tonë një repository të vetin të imazheve Docker. Fatmirësisht, vendi në servera tani është mjaft i lirë (me siguri më i lirë se abonimi në DockerHub), dhe procesi i instalimit të një repository privat është shumë i thjeshtë.
Ne duam që të kemi instaluar:
- një repository Docker me fjalëkalim, të aksesueshëm përmes një subdomeni ;
- UI-i ndërfaqes për shikimin e imazheve në repositorin, e aksesueshme nga .
Për këtë:
- Do tĂ« krijojmĂ« nĂ« Plesk dy podomene nĂ« abonimin tonĂ«: docker.helloworld.ru dhe docker-ui.helloworld.ru, dhe do t'i konfiguroni pĂ«r ta pĂ«rdorur certifikatĂ«n Letâs Encrypt.
- Në dosjen e podomenit docker.helloworld.ru do të shtojmë skedarin
docker-compose.ymlme këtë përmbajtje: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' - Përmes SSH do të gjenerojmë skedarin .htpasswd për autorizimin Basic në repositorin Docker:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Do të ndërtojmë dhe ngremë kontenierët:
docker-compose up -d - Dhe duhet të drejtojmë Nginx në kontenierët tanë. Kjo mund të bëhet përmes Plesk.
Veprimet e mëposhtme duhet të kryhen për podomene docker.helloworld.ru dhe docker-ui.helloworld.ru:
Në seksionin Dev Tools në faqen tonë shkojmë tek Docker Proxy Rules:

Dhe shtojmë një rregull për të prokuruar trafikun e hyrjes në kontenierin tonë:

- Po shikojmë nëse mund të autorizohemi në kontejnerin tonë nga makina lokale:
$ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password KĂRCĂNIM! PĂ«rdorimi i --password pĂ«rmes CLI Ă«shtĂ« i pasigurt. PĂ«rdorni --password-stdin. Autorizimi u krye me sukses - Gjithashtu do tĂ« kontrollojmĂ« funksionimin e subdomain-it docker-ui.helloworld.ru:

Kur të klikoni në Browse repositories, shfletuesi do të hapë një dritare për autorizim, ku do t'ju duhet të jepni emrin e përdoruesit dhe fjalëkalimin për depozitën. Pas kësaj, do të na çojë në faqen me listën e depozitave (tani për ju ajo do të jetë bosh):
Hapni portat në Plesk Firewall
Pas instalimit dhe konfigurimit të komponentëve, na nevojitet të hapim portat që komponentët të jenë të aksesueshëm nga kontejnerët Docker dhe rrjeti i jashtëm.
Le të shohim se si ta bëjmë këtë me shembullin e zgjerimit të Firewall për Plesk që kemi instaluar më parë.
- Kalojmë në Tools & Settings > Settings > Firewall:

- Kalojmë në Modifikoni Rregullat e Plesk Firewall > Shto Rregull të Personalizuar dhe hapni portat TCP të mëposhtme për subnet-in Docker (172.0.0.0/8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- Gjithashtu do të shtojmë një rregull që do të hapë portet për PostgreSQL dhe panelin e menaxhimit të RabbitMQ për botën e jashtme:

- Zbatoni rregullat me butonin Apply Changes:

Konfigurimi i CI/CD në Github Actions
TĂ« kalojmĂ« nĂ« pjesĂ«n mĂ« tĂ« interesantĂ« â konfigurimin e pipeline-it pĂ«r integrimin dhe shpĂ«rndarjen e vazhdueshme tĂ« projektit tonĂ« nĂ« server.
Ky kyç do të përbëhet nga dy pjesë:
- ndĂ«rtimi i imazhit dhe ekzekutimi i testeve (pĂ«r backend) â nĂ« anĂ«n e Github;
- njĂ« hapĂ«sirĂ« (pĂ«r backend) dhe depozitimi i kontejnerĂ«ve â nĂ« server.
Depoja në Plesk
Të merremi fillimisht me pikën e dytë (sepse varet nga e para).
Procesi i depoy-it do të konfigurohet me ndihmën e shtesës Git për Plesk.
Të shqyrtojmë një shembull me ambientin Prod për depozitën e Backend.
- Hyrim në abonimin e faqes sonë Helloworld dhe kaloni në nënseksionin Git:

- Ngjitim në fushën "Remote Git repository" lidhjen me depozitën tonë në Github dhe ndryshojmë dosjen e paracaktuar
httpdocsnë një tjetër (për shembull,/httpdocs/hw_back):
- Kopjojmë çelësin publik SSH nga etapa e mëparshme dhe e vendosim në konfigurimet e Github.
- Klikoni OK në ekranin në pikën 2, pas së cilës do të kalojmë në faqen e depozitës në Plesk. Tani na nevojitet të konfigurojmë azhurnimin e depozitës për ndodhitë në degën master. Për këtë kaloni në Cilësimet e Depozitës dhe ruani vlerën
Webhook URL(do të na nevojitet më vonë gjatë konfigurimit të Github Actions):
- Në fushën e veprimeve në ekranin nga pika e mëparshme shkruani skriptin për të nisur depoy-in:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}ku:
{REPOSITORY_ABSOLUTE_PATH}â rruga e dosjes prod backend-repozitorit nĂ« server;
{ENV}â mjedisi (dev/prod), nĂ« rastin tonĂ«prod;
{DOCKER_REGISTRY_HOST}â hosti i repositorit tonĂ« docker
{TG_BOT_TOKEN}â tokeni i bot-it te Telegram;
{TG_CHAT_ID}â ID e bisedĂ«s/kanalit pĂ«r dĂ«rgimin e njoftimeve.Shembulli i skriptit:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - Shtojmë përdoruesin nga abonimi ynë në grupin Docker (që të mund të menaxhojë kontejnerët):
sudo usermod -aG docker helloworld_admin
Mjedisi Dev për backend-repozitorin dhe frontend konfigurohen njësoj.
Pipeline i depërtimit në Github Actions
Kalojmë te konfigurimi i pjesës së parë të CI/CD pipeline tonë në Github Actions.
Backend
Pajisja përshkruhet në .
Por para se ta shqyrtojmë, plotësojmë në Github variablat e nevojshme Sekrete. Për këtë kalojmë në Settings -> Secrets:
DOCKER_REGISTRYâ hosti i repositorit tonĂ« Docker (docker.helloworld.ru);DOCKER_LOGINâ pĂ«rdoruesi pĂ«r repositorin Docker;DOCKER_PASSWORDâ password-i pĂ«r tĂ«;DEPLOY_HOSTâ hosti, ku Ă«shtĂ« e aksesueshme administrata Plesk (shembull: :8443 ose :8443);DEPLOY_BACK_PROD_TOKENâ tokeni pĂ«r depĂ«rtimin nĂ« repositorin prod nĂ« server (e kemi marrĂ« nĂ« Shtrirjen nĂ« Plesk pika 4);DEPLOY_BACK_DEV_TOKENâ tokeni pĂ«r depĂ«rtimin nĂ« repositorin dev nĂ« server.
Procesi i deployment-it është i thjeshtë dhe përbëhet nga tri hapa kryesorë:
- ndërtimi dhe publikimi i imazhit në depozitën tonë;
- kryerja e testeve në kontejnerin bazuar në imazhin e sapo ndërtuar;
- vendosja në mjedisin e duhur në varësi të degës (dev/master).
Frontend
nuk ndryshon shumë nga ai i pasmë. Aty nuk ka hapin e kryerjes së testeve dhe emrat e tokeneve për deployment ndryshojnë. Sekretet për depozitën frontale, për fat të mirë, duhet të plotësohen veçmas.
Konfigurimi i faqes
Proksimi i trafikut përmes Nginx
Përfundimisht, kemi arritur në fund. Mbete vetëm të konfigurojmë proksimin e trafikut hyrës dhe dalës në kontejnerin tonë përmes Nginx. Ky proces e kemi trajtuar tashmë në pikën 5 të konfigurimit të Docker Registry. E njëjta gjë duhet përsëritur për pjesët frontale dhe të pasme në mjediset dev dhe prod.
Do të sjell disa shkrepje të konfigurimeve.
Backend

Frontend

ShĂ«nim i rĂ«ndĂ«sishĂ«m. NĂ« kontejnerin frontend do tĂ« proksohen tĂ« gjitha URL-tĂ« pĂ«rveç atyre qĂ« fillojnĂ« me /api/ â ato do tĂ« proksohen nĂ« kontejnerin backend (prandaj nĂ« kontejnerin backend tĂ« gjitha trajtuesit duhet tĂ« fillojnĂ« me /api/).
Përfundimet
Tani faqja jonë duhet të jetë e aksesueshme në adresat helloworld.ru dhe dev.helloworld.ru (mjedisi prod dhe dev përkatës).
Në përmbledhje, mësuam si të përgatisim një aplikacion të thjeshtë në Flask dhe Angular dhe si të konfiguroni një pipeline në Github Actions për ta deployuar në një server që përdor Plesk.
Do ta përsëris lidhjet për repozitorët me kodin: , .
Burimi: habr.com
















