
V tem članku bom delil svojo izkušnjo nastavitve CI/CD z uporabo nadzorne plošče Plesk in Github Actions. Danes se bomo naučili, kako postaviti preprost projekt z nepremišljenim imenom 'Helloworld'. Napisan je v Python okviru Flask, z delavci na Celery in frontendov z Angular 8.
Povezave do repozitorijev: , .
V prvem delu članka bomo pregledali naš projekt in njegove dele. V drugem se bomo osredotočili na nastavitev Pleska ter namestitev potrebnih razširitev in komponent (Baza podatkov, RabbitMQ, Redis, Docker itd.).
V tretjem delu se bomo končno ukvarjali z nastavitvijo pipeline-a za postavitev našega projekta na strežnik v dev- in prod-okolje. Nato bomo zagnali spletno stran na strežniku.
In ja, pozabil sem se predstaviti. Ime mi je Oleg Borzov, sem fullstack razvijalec v ekipi CRM za upravljavce hipotekarnih posojil v Domklik.
Pregled projekta
Najprej si poglejmo dva repozitorija projekta — backend in frontend — in preletimo kodo.
Backend del: Flask+Celery
Za backend sem izbral precej priljubljeno kombinacijo med Python razvijalci: okvir Flask (za API) in Celery (za obdelavo nalog). Kot ORM se uporablja SQLAlchemy. Za migracije se uporablja Alembic. Za validacijo JSON v ročajih — Marshmallow.
V obstaja datoteka Readme.md s podrobnim opisom strukture in navodili za zagon projekta.
je dovolj preprost, sestoji iz 6 ročajev:
/ping— za preverjanje dostopnosti;- ročaji za registracijo, avtentifikacijo, deavtentifikacijo in pridobitev avtentificiranega uporabnika;
- ročaj za pošiljanje emailov, ki dodaja nalogo v čakalno vrsto Celery.
je še bolj preprost, tam je le ena naloga send_mail_task.
V mapi so dve podmapi:
dockers dvema Docker datotekama (base.dockerfileza gradnjo redko spreminjajoče se osnovne slike inDockerfileza glavne gradnje);.env_files— z datotekami z okolijskimi spremenljivkami za različna okolja.
V korenu projekta so štiri datoteke docker-compose:
docker-compose.local.db.ymlza dvig lokalne baze podatkov za razvijanje;docker-compose.local.workers.ymlza lokalni dvig delavca, baze, Redis-a in RabbitMQ;docker-compose.test.ymlza izvajanje testov pri razporejanju;docker-compose.ymlza postavitev.
In zadnja zanimiva mapa je — . V njej so shell skripti za postavitev:
deploy.sh— zagon migracij in postavitve. Zažene se na strežniku po končanju gradnje in izvajanju testov v Github Actions;rollback.sh— povratak kontejnerjev na prejšnjo različico gradnje;curl_tg.sh— pošiljanje obvestil o postavitvi v Telegram.
Frontend na Angular
je precej lažji od backenda. Fronta sestavlja tri strani:
- Glavna stran s obrazcem za pošiljanje e-pošte in gumbom za izhod.
- Stran za prijavo.
- Stran za registracijo.
Glavna stran izgleda skromno:

V korenu ležita dva datoteka Dockerfile in docker-compose.yml, prav tako pa znana mapa .ci-cd s nekoliko manj skripti kot v repozitoriju backend (odstranjeni so skripti za zagon testov).
Ustanovitev projekta v Plesk
Začnimo s konfiguracijo Pleska in ustvarjanjem naročnine za našo spletno stran.
Namestitev razširitev
V Plesku potrebujemo štiri razširitve:
Dockerza upravljanje in vizualno prikazovanje stanja kontejnerjev v administraciji Plesk;Gitza nastavitev koraka prenosa na strežniku;Let's Encryptza generiranje (in samodejno podaljšanje) brezplačnih TLS-certifikatov;Firewalza nastavitev filtriranja prihajajočega prometa.
Namestimo jih lahko preko administracije Plesk v razdelku Razširitve:

Podrobno nastavitev razširitev ne bomo obravnavali, za naše demo-namen bomo uporabili privzete nastavitve.
Ustvarjanje naročnine in strani
Nato moramo ustvariti naročnino za našo spletno stran helloworld.ru in dodati poddomeno dev.helloworld.ru.
- Ustvarimo naročnino za domeno helloworld.ru in navedemo uporabniško ime-geslo za sistemskega uporabnika:

Na dnu strani označite Secure the domain with Let’s Encrypt, če želimo nastaviti HTTPS za spletno stran:
- Nato v tej naročnini ustvarimo poddomeno dev.helloworld.ru (za katero je prav tako možno izdati brezplačen TLS-certifikat):

Namestitev strežniških komponent
Imamo strežnik z OS Debian Stretch 9.12 in nameščenim upravljanjem Plesk Obsidian 18.0.27.
Moramo namestiti in konfigurirati za naš projekt:
- PostgreSQL (v našem primeru bo en strežnik z dvema DB za dev- in prod-okolje).
- RabbitMQ (isto, en instanca z različnimi vhosts za okolja).
- Dve instanci Redis (za dev- in prod-okolje).
- Docker Registry (za lokalno shranjevanje zbranih Docker-slik).
- Učinkovinski vmesnik za Docker registry.
PostgreSQL
V kompletu s Pleskom že pride SSQL PostgreSQL, vendar ne najnovejše različice (ob času pisanja članka Plesk Obsidian Postgres različic 8.4–10.8). Mi pa želimo za svojo aplikacijo najnovejšo različico (12.3 ob času pisanja članka), zato jo bomo namestili ročno.
Podrobnih navodil za namestitev Postgresa na Debianu je na spletu ogromno (), zato jih ne bom podrobno opisoval, le navedel bom ukaze:
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
Обратите внимание, что в PostgreSQL настройки по умолчанию достаточно средние, поэтому необходимо отрегулировать конфигурацию. В этом нам поможет : необходимо ввести параметры вашего сервера и заменить настройки в файле /etc/postgresql/12/main/postgresql.confна предложенные. Тут следует уточнить, что такие калькуляторы — не универсальное решение, и базу нужно настраивать более детально, исходя из вашего оборудования, приложений и сложности запросов. Но для начала этого вполне достаточно.
Кроме того, что предлагает калькулятор, также измените в postgresql.confпорт 5432, заданный по умолчанию, на другой (в нашем примере — 53983).
После изменения конфигурационного файла перезагрузите postgresql-server командой:
service postgresql restart
Мы установили и настроили PostgreSQL. Теперь создадим БД, пользователей для dev- и prod-сред, и предоставим им права на управление БД:
$ 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
После установки нам нужно создать vhosts, пользователей и предоставить нужные права:
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
Теперь установим и настроим последний компонент для нашего приложения — Redis. Он будет использоваться в качестве бэкенда для хранения результатов задач Celery.
Мы поднимем два Docker-контейнера с Redis для dev- и prod-сред с помощью расширения Docker для Plesk.
- Vstopimo v Plesk, pojdimo na razdelek Razširitve, poiščimo razširitev Docker in jo namestimo (potrebna nam je brezplačna različica):

- Pojdimo na nameščeno razširitev, poiščimo sliko
redis bitnamiin namestimo najnovejšo različico:
- Vstopimo v preneseni posod in prilagodimo konfiguracijo: določimo vrata, največjo dodeljeno velikost RAM-a, geslo v spremenljivkah okolja in montiramo volumen:

- Izvedemo korake 2-3 za prod-posodo, v nastavitvah samo spremenimo parametre: vrata, geslo, velikost RAM-a in pot do mape volume na strežniku:

Docker Registry
Poleg osnovnih storitev bi bilo dobro namestiti na strežnik lastno skladišče Docker slik. Na srečo je prostor na strežnikih zdaj precej poceni (resnično ceneje kot naročnina na DockerHub), pa tudi postopek namestitve zasebnega skladišča je zelo enostaven.
Želimo, da imamo nameščeno:
- z geslom zaščiteno Docker skladišče, dostopno preko poddomene ;
- UI vmesnik za ogled slik v skladišču, dostopen na naslovu .
Zato:
- Ustvarili bomo v Plesku dve poddomeni v naši naročnini: docker.helloworld.ru in docker-ui.helloworld.ru, in konfigurirali bomo certifikate Let’s Encrypt zanje.
- V mapo poddomene docker.helloworld.ru dodamo datoteko
docker-compose.ymlс таким содержимым: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' - Preko SSH bomo ustvarili datoteko .htpasswd za osnovno avtentikacijo v Docker skladišču:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Sestavili bomo in zagnali posode:
docker-compose up -d - In treba je preusmeriti Nginx na naše posode. To lahko storimo preko Pleska.
Naslednje korake je treba izvesti za poddomene docker.helloworld.ru in docker-ui.helloworld.ru:
V razdelku Razvijalna orodja naše strani gremo v Docker Proxy Rules:

In dodamo pravilo za posredovanje vhodnega prometa v našo posodo:

- Preverimo, ali se lahko prijavimo v našo posodo z lokalnega računalnika:
$ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password WARNING! Using --password via the CLI is insecure. Use --password-stdin. Prijava uspešna - Prav tako bomo preverili delovanje poddomene docker-ui.helloworld.ru:

Ko boste kliknili na Browse repositories, bo brskalnik odprl okno za prijavo, v katerega boste morali vnesti uporabniško ime in geslo za repozitorij. Nato vas bo preusmerilo na stran s seznamom repozitorijev (zaenkrat bo ta prazna):
Odprite porte v Plesk Firewall
Po namestitvi in nastavitvi komponent moramo odpreti porte, da bodo komponente dostopne iz Docker kontejnerjev in zunanje mreže.
Poglejmo, kako to storiti, na primeru razširitve Firewall za Plesk, ki smo jo namestili prej.
- Pojdite na Orodja in nastavitve > Nastavitve > Firewall:

- Pojdite na Spremenite pravila požarnega zidu Plesk > Dodajte po meri pravilo in odprite naslednje TCP porte za podomrežje Docker (172.0.0.0/8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- Prav tako dodajmo pravilo, ki bo odprlo porte PostgreSQL in upravljalske plošče RabbitMQ za zunanji svet:

- Pravila uporabimo s klikom na gumb Uporabi spremembe:

Nastavitev CI/CD v Github Actions
Začnimo s najbolj zanimivim delom — nastavitvijo pipeline za neprekinjeno integracijo in dostavo našega projekta na strežnik.
Ta pipeline bo sestavljen iz dveh delov:
- zbiranje slike in izvajanje testov (za backend) — na strani Githuba;
- zagon migracij (za backend) in deploy kontejnerjev — na strežniku.
Deploy v Plesk
Najprej se osredotočimo na drugi del (saj je od njega odvisen prvi).
Postopek deploya bomo nastavili z uporabo razširitve Git za Plesk.
Oglejmo si primer s produkcijskim okoljem za Backend repozitorij.
- Prijavite se v naročnino našega spletnega mesta Helloworld in pojdite v pododdelek Git:

- V polje 'Remote Git repository' prilepite povezavo na naš Github repozitorij in spremenite privzeto mapo
httpdocsna drugo (na primer,/httpdocs/hw_back):
- Kopirajte javni ključ SSH z prejšnjega koraka in ga prilepite v nastavitvah Githuba.
- Kliknite OK na zaslonu v točki 2, nato pa vas bo preusmerilo na stran repozitorija v Plesku. Zdaj moramo nastaviti posodabljanje repozitorija ob commitih v osnovno vejo. Zato pojdite na Nastavitve repozitorija in shranite vrednost
Webhook URL(bomo ga potrebovali kasneje pri nastavitvi Github Actions):
- V polju Dejanja na zaslonu iz prejšnje točke vnesite skripto za zagon deploya:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}kde:
{REPOSITORY_ABSOLUTE_PATH}— pot do mape prod backend repozitorija na strežniku;
{ENV}— okolje (dev/prod), v našem primeruprod;
{DOCKER_REGISTRY_HOST}— gostitelj našega docker repozitorija
{TG_BOT_TOKEN}— žeton Telegram bota;
{TG_CHAT_ID}— ID klepeta/kanala za pošiljanje obvestil.Primer skripte:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - Dodajamo korisnika iz naše pretplate u Docker grupu (kako bi mogao upravljati kontejnerima):
sudo usermod -aG docker helloworld_admin
Dev-okruženje za backend repozitorij i frontend se postavlja na sličan način.
Pipeline za deploy u Github Actions
Prelazimo na podešavanje prvog dela našeg CI/CD pipeline-a u Github Actions.
Backend
Pipeline se opisuje u .
Ali pre nego što ga analiziramo, popunićemo potrebne tajne varijable u Github-u. Za to prelazimo u Settings -> Secrets:
DOCKER_REGISTRY— host našeg Docker repozitorijuma (docker.helloworld.ru);DOCKER_LOGIN— korisničko ime za Docker repozitorijum;DOCKER_PASSWORD— lozinka za njega;DEPLOY_HOST— host na kojem je dostupna admin Plesk (primer: :8443 ili :8443);DEPLOY_BACK_PROD_TOKEN— token za deploy u prod-repozitorijum na serveru (dobijen u Razvijanje u Plesk tačka 4);DEPLOY_BACK_DEV_TOKEN— token za deploy u dev-repozitorijum na serveru.
Proces deploy-a je jednostavan i sastoji se od tri osnovna koraka:
- izgradnja i objavljivanje slike u našem repozitorijumu;
- pokretanje testova u kontejneru zasnovanom na sveže izgrađenoj slici;
- deploy u odgovarajuće okruženje u zavisnosti od grane (dev/master).
Frontend
malo se razlikuje od back repozitorija. Nedostaje korak sa pokretanjem testova i menjaju se imena tokena za deploy. Tajne za front-repozitorij, inače, treba popuniti odvojeno.
Podešavanje sajta
Proksiranje saobraćaja putem Nginx-a
Pa, došli smo do kraja. Ostalo je samo da postavimo proksiranje dolaznog i odlaznog saobraćaja u naš kontejner preko Nginx-a. Ovaj proces smo već razmotrili u tački 5 podešavanja Docker Registry. Isto to treba ponoviti za back i front deo u dev i prod okruženjima.
Prikazat ću snimke podešavanja.
Backend

Frontend

Važno pojašnjenje. U frontend kontejner će se proksirati svi URL-ovi, osim onih koji počinju sa /api/ — oni će se proksirati u back kontejner (zato u back kontejneru svi obrtnici moraju početi sa /api/).
Zaključki
Sada bi naš sajt trebao biti dostupan na adresama helloworld.ru i dev.helloworld.ru (prod i dev okruženje odgovarajuće).
Sve u svemu, saznali smo kako da pripremimo jednostavnu aplikaciju na Flask-u i Angular-u i kako da postavimo pipeline u Github Actions za njen isporuku na server pod upravom Plesk.
Ponovo ću podeliti linkove na repozitorijume sa kodom: , .
Izvor: habr.com
















