U ovom članku ću podijeliti svoje iskustvo postavljanja CI/CD-a koristeći Plesk Control Panel i Github Actions. Danas ćemo naučiti kako implementirati jednostavan projekat s jednostavnim imenom "Helloworld". Napisan je u Flask Python okviru, sa Celery radnicima i Angular 8 frontendom.
U prvom dijelu članka osvrnut ćemo se na naš projekt i njegove dijelove. U drugom ćemo shvatiti kako postaviti Plesk i instalirati potrebna proširenja i komponente (DB, RabbitMQ, Redis, Docker, itd.).
U trećem dijelu ćemo konačno shvatiti kako postaviti cevovod za postavljanje našeg projekta na server u dev i prod okruženju. A onda ćemo pokrenuti stranicu na serveru.
I da, zaboravio sam da se predstavim. Moje ime je Oleg Borzov, ja sam fullstack programer u CRM timu za menadžere hipoteka u Domclicku.
Pregled projekta
Prvo, pogledajmo dva projektna spremišta - backend i front - i prođimo preko koda.
Pozadina: Flask+Celery
Za zadnji dio, uzeo sam gomilu koja je prilično popularna među Python programerima: Flask framework (za API) i Celery (za red zadataka). SQLAchemy se koristi kao ORM. Alembic se koristi za migracije. Za JSON validaciju u ručkama - Marshmallow.
В spremišta postoji Readme.md fajl sa detaljnim opisom strukture i uputstvima za pokretanje projekta.
API za web dio prilično nekompliciran, sastoji se od 6 olovaka:
/ping - provjeriti dostupnost;
ručke za registraciju, autorizaciju, deautorizaciju i dobivanje ovlaštenog korisnika;
ručka e-pošte koja stavlja zadatak u red čekanja Celery.
Dio celera još lakše, postoji samo jedan problem send_mail_task.
Glavna stranica sa formom za slanje e-pošte i dugmetom za izlaz.
Stranica za prijavu.
Stranica za registraciju.
Glavna stranica izgleda asketski:
Postoje dva fajla u korenu Dockerfile и docker-compose.yml, kao i poznati folder .ci-cd sa nešto manje skripti nego u stražnjem spremištu (uklonjene skripte za pokretanje testova).
Pokretanje projekta u Plesku
Počnimo postavljanjem Pleska i kreiranjem pretplate za našu web stranicu.
Instaliranje ekstenzija
U Plesku su nam potrebna četiri proširenja:
Docker za upravljanje i vizualni prikaz statusa kontejnera u Plesk admin panelu;
Git da konfigurišete korak implementacije na serveru;
Let's Encrypt za generiranje (i automatsko obnavljanje) besplatnih TLS certifikata;
Firewall da konfigurišete filtriranje dolaznog saobraćaja.
Možete ih instalirati preko Plesk admin panela u odjeljku Ekstenzije:
Nećemo uzeti u obzir detaljne postavke za ekstenzije, zadane postavke će poslužiti za naše demo svrhe.
Kreirajte pretplatu i web lokaciju
Zatim moramo kreirati pretplatu za našu web stranicu helloworld.ru i tamo dodati poddomen dev.helloworld.ru.
Kreirajte pretplatu za domen helloworld.ru i navedite lozinku za prijavu za korisnika sistema:
Označite kvadratić na dnu stranice Osigurajte domenu pomoću Let's Encryptako želimo da postavimo HTTPS za sajt:
Zatim, u ovoj pretplati, kreirajte poddomenu dev.helloworld.ru (za koju također možete izdati besplatni TLS certifikat):
Instaliranje serverskih komponenti
Imamo server sa OS Debian Stretch 9.12 i instaliran kontrolni panel Plesk Obsidian 18.0.27.
Moramo da instaliramo i konfigurišemo za naš projekat:
PostgreSQL (u našem slučaju, postojaće jedan server sa dve baze podataka za dev i prod okruženja).
RabbitMQ (ista, ista instanca sa različitim vhostovima za okruženja).
Dvije Redis instance (za dev i prod okruženja).
Docker Registry (za lokalno skladištenje izgrađenih Docker slika).
UI za Docker registar.
PostgreSQL
Plesk već dolazi sa PostgreSQL DBMS, ali ne i najnovijom verzijom (u vrijeme pisanja Plesk Obsidian podržano Postgres verzije 8.4–10.8). Želimo najnoviju verziju za našu aplikaciju (12.3 u vrijeme pisanja ovog teksta), pa ćemo je ručno instalirati.
Postoji mnogo detaljnih uputa za instalaciju Postgresa na Debian na mreži (primer), pa ih neću detaljno opisivati, samo ću dati naredbe:
S obzirom da PostgreSQL ima prilično osrednje podrazumevane postavke, potrebno je ispraviti konfiguraciju. Ovo će nam pomoći kalkulator: potrebno je da unesete parametre vašeg servera i zamijenite postavke u datoteci /etc/postgresql/12/main/postgresql.confonima koji su ponuđeni. Ovdje treba napomenuti da ovakvi kalkulatori nisu čarobni metak, te da bazu treba preciznije podesiti, na osnovu vašeg hardvera, aplikacije i složenosti upita. Ali ovo je dovoljno za početak.
Pored postavki koje je predložio kalkulator, mijenjamo se i u postgresql.confpodrazumevani port 5432 na drugi (u našem primeru - 53983).
Nakon promjene konfiguracijske datoteke, ponovo pokrenite postgresql-server naredbom:
service postgresql restart
Instalirali smo i konfigurisali PostgreSQL. Sada kreirajmo bazu podataka, korisnike za dev i prod okruženja i dajmo korisnicima prava za upravljanje bazom podataka:
$ 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
Rabbit MQ
Prijeđimo na instaliranje RabbitMQ-a, posrednika poruka za Celery. Instalacija na Debian je prilično jednostavna:
Sada instalirajmo i konfiguriramo posljednju komponentu za našu aplikaciju - Redis. Koristit će se kao backend za pohranjivanje rezultata Celery zadataka.
Podići ćemo dva Docker kontejnera sa Redis-om za dev i prod okruženja koristeći ekstenziju Docker za Plesk.
Idemo na Plesk, idemo na odjeljak Extensions, tražimo ekstenziju Docker i instaliramo je (treba nam besplatna verzija):
Idite na instaliranu ekstenziju, pronađite sliku kroz pretragu redis bitnami i instalirajte najnoviju verziju:
Ulazimo u preuzeti kontejner i prilagođavamo konfiguraciju: specificiramo port, maksimalnu dodijeljenu veličinu RAM-a, lozinku u varijablama okruženja i montiramo volumen:
Izvodimo korake 2-3 za prod kontejner, u postavkama mijenjamo samo parametre: port, lozinku, veličinu RAM-a i putanju do foldera volumena na serveru:
Docker Registry
Pored osnovnih usluga, bilo bi dobro da na server stavite i sopstveno Docker spremište slika. Srećom, prostor na serveru je sada prilično jeftin (sigurno jeftiniji od pretplate na DockerHub), a proces postavljanja privatnog spremišta je vrlo jednostavan.
Kreirajmo dvije poddomene u Plesku u našoj pretplati: docker.helloworld.ru i docker-ui.helloworld.ru, i konfigurirajmo Let's Encrypt certifikate za njih.
Dodajte datoteku u mapu poddomena docker.helloworld.ru docker-compose.yml sa ovakvim sadržajem:
I moramo preusmjeriti Nginx na naše kontejnere. Ovo se može uraditi preko Pleska.
Za poddomene docker.helloworld.ru i docker-ui.helloworld.ru potrebno je uraditi sljedeće korake:
odjeljak Dev Tools idite na našu stranicu Docker proxy pravila:
I dodajte pravilo za proxy dolazni promet u naš kontejner:
Provjeravamo da se možemo prijaviti u naš kontejner sa lokalne mašine:
$ 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
Provjerimo i rad poddomena docker-ui.helloworld.ru:
Kada kliknete na Pregledaj spremišta, pretraživač će prikazati prozor za autorizaciju u koji ćete morati da unesete korisničko ime i lozinku za spremište. Nakon toga ćemo biti prebačeni na stranicu sa listom spremišta (za sada će vam ona biti prazna):
Otvaranje portova u Plesk Firewall-u
Nakon instalacije i konfiguracije komponenti, moramo otvoriti portove kako bi komponente bile dostupne iz Docker kontejnera i vanjske mreže.
Pogledajmo kako to učiniti koristeći proširenje Firewall za Plesk koje smo ranije instalirali.
Idi Alati i postavke > Postavke > Zaštitni zid:
Idi Izmijenite pravila Plesk Firewall > Dodaj prilagođeno pravilo i otvorite sljedeće TCP portove za Docker podmrežu (172.0.0.0 / 8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
Također ćemo dodati pravilo koje će otvoriti PostgreSQL portove i RabbitMQ upravljačke ploče prema vanjskom svijetu:
Primijenite pravila pomoću dugmeta Primijeni promjene:
Postavljanje CI/CD-a u Github Actions
Prijeđimo na najzanimljiviji dio – postavljanje kontinuiranog integracionog cjevovoda i isporuku našeg projekta na server.
Ovaj cevovod će se sastojati od dva dela:
pravljenje slike i pokretanje testova (za pozadinu) - na Github strani;
pokretanje migracija (za pozadinu) i postavljanje kontejnera - na serveru.
Postavite u Plesk
Hajde da se prvo pozabavimo drugom tačkom (jer prva zavisi od toga).
Mi ćemo konfigurirati proces implementacije koristeći Git ekstenziju za Plesk.
Razmotrite primjer sa Prod okruženjem za Backend spremište.
Idemo na pretplatu naše Helloworld web stranice i idemo u pododjeljak Git:
Umetnite vezu do našeg Github spremišta u polje "Remote Git repository" i promijenite zadanu mapu httpdocs drugome (npr. /httpdocs/hw_back):
Kopirajte SSH javni ključ iz prethodnog koraka i dodati nalazi se u Github postavkama.
Kliknite OK na ekranu u koraku 2, nakon čega ćemo biti preusmjereni na stranicu spremišta u Plesku. Sada treba da konfigurišemo spremište da se ažurira prilikom urezivanja na glavnu granu. Da biste to učinili, idite na Postavke spremišta i sačuvajte vrijednost Webhook URL (trebat će nam kasnije prilikom postavljanja Github Actions):
U polje Akcije na ekranu iz prethodnog paragrafa unesite skriptu za pokretanje implementacije:
cd {REPOSITORY_ABSOLUTE_PATH}
.ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}
gde:
{REPOSITORY_ABSOLUTE_PATH} - put do prod foldera pozadinskog spremišta na serveru; {ENV} - okruženje (dev/prod), u našem slučaju prod; {DOCKER_REGISTRY_HOST} - domaćin našeg docker repozitorija {TG_BOT_TOKEN} — Telegram bot token; {TG_CHAT_ID} — ID ćaskanja/kanala za slanje obavještenja.
Primjer 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
Dodajte korisnika iz naše pretplate u Docker grupu (kako bi mogli upravljati kontejnerima):
sudo usermod -aG docker helloworld_admin
Razvojno okruženje za backend spremište i frontend su postavljeni na isti način.
Cjevovod za implementaciju u Github Actions
Pređimo na postavljanje prvog dijela našeg CI/CD cevovoda u Github Actions.
DEPLOY_HOST — host na kojem je dostupna Plesk admin panel (primjer: helloworld.com: 8443 ili 123.4.56.78:8443);
DEPLOY_BACK_PROD_TOKEN - token za implementaciju u prod-repozitorijum na serveru (dobili smo ga u Deployment in Plesk str. 4);
DEPLOY_BACK_DEV_TOKEN - token za postavljanje u dev spremište na serveru.
Proces postavljanja je jednostavan i sastoji se od tri glavna koraka:
izrada i objavljivanje slike u našem spremištu;
izvođenje testova u kontejneru na osnovu svježe napravljene slike;
implementacija u željeno okruženje ovisno o grani (dev/master).
frontend
Deploy.yml fajl za prednje spremište malo drugačiji od Beckovog. Nedostaje korak s pokretanjem testova i promjenama imena tokena za implementaciju. Tajne za prednji repozitorij, inače, treba popuniti zasebno.
Postavljanje stranice
Proxy promet putem Nginxa
Pa, došli smo do kraja. Ostaje samo konfigurirati proxying dolaznog i odlaznog prometa u naš kontejner preko Nginxa. Već smo pokrili ovaj proces u koraku 5 podešavanja Docker Registry-a. Isto bi trebalo ponoviti za stražnje i prednje dijelove u dev i prod okruženjima.
Dat ću snimke ekrana postavki.
backend
frontend
Važnoe utočnenie. Svi URL-ovi će biti poslani u frontend kontejner, osim onih koji počinju sa /api/ - oni će biti poslani u zadnji kontejner (tako u zadnjem kontejneru, svi rukovaoci moraju početi sa /api/).
Ishodi
Sada bi naša stranica trebala biti dostupna na helloworld.ru i dev.helloworld.ru (prod- i dev-environments, respektivno).
Ukupno smo naučili kako pripremiti jednostavnu aplikaciju u Flask-u i Angular-u i postaviti cjevovod u Github Actions-u da bismo je postavili na server koji pokreće Plesk.
Duplicirat ću veze do spremišta sa kodom: backend, frontend.