
V tomto článku se podělím o své zkušenosti s nastavením CI/CD pomocí ovládacího panelu Plesk a Github Actions. Dnes se naučíme nasadit jednoduchý projekt s názvem „Helloworld“. Je napsán na Python frameworku Flask, s workery na Celery a frontendem na Angular 8.
Odkazy na repozitáře: , .
V první části článku se podíváme na náš projekt a jeho části. Ve druhé části si ukážeme, jak nastavit Plesk a nainstalovat potřebná rozšíření a komponenty (DB, RabbitMQ, Redis, Docker atd.).
Ve třetí části konečně zjistíme, jak nastavit pipeline pro nasazení našeho projektu na server do dev- a prod- prostředí. A poté spustíme web na serveru.
A ano, zapomněl jsem se představit. Jmenuji se Oleg Borzov, jsem fullstack vývojář v týmu CRM pro manažery hypotečního úvěrování v Domklik.
Přehled projektu
Nejprve se podíváme na dvě repozitáře projektu — backend a frontend — a projdeme si kód.
Backend část: Flask+Celery
Pro backend jsem vzal dost populární kombinaci mezi Python vývojáři: framework Flask (pro API) a Celery (pro frontu úloh). Jako ORM je používáno SQLAlchemy. Pro migraci se používá Alembic. Pro validaci JSON v routech — Marshmallow.
V existuje soubor Readme.md s podrobným popisem struktury a instrukcemi pro spuštění projektu.
je poměrně jednoduché, skládá se ze 6 rout:
/ping— pro kontrolu dostupnosti;- routy pro registraci, autorizaci, deautorizaci a získání autorizovaného uživatele;
- routa pro odesílání emailu, která přidává úlohu do fronty Celery.
je ještě jednodušší, existuje tam pouze jedna úloha send_mail_task.
Ve složce jsou zde dvě podsložky:
dockers dvěma Docker soubory (base.dockerfilepro sestavení seldom měněného základního obrazu aDockerfilepro hlavní sestavy);.env_files— se soubory proměnných pro různé prostředí.
V kořeni projektu se nacházejí čtyři soubory docker-compose:
docker-compose.local.db.ymlpro spuštění lokální databáze pro vývoj;docker-compose.local.workers.ymlpro lokální spuštění workeru, databáze, Redis a RabbitMQ;docker-compose.test.ymlpro provádění testů při nasazení;docker-compose.ymlpro nasazení.
A poslední zajímavá složka pro nás — . Obsahuje shell skripty pro nasazení:
deploy.sh— spuštění migrace a nasazení. Spouští se na serveru po sestavení a provedení testů v Github Actions;rollback.sh— vrácení kontejnerů na předchozí verzi sestavení;curl_tg.sh— odesílání upozornění na nasazení do Telegramu.
Frontend na Angularu
je výrazně jednodušší než backendový. Frontend se skládá ze tří stránek:
- Hlavní stránka s formulářem pro odesílání emailu a tlačítkem pro odhlášení.
- Přihlašovací stránka.
- Registrační stránka.
Hlavní stránka vypadá skromně:

V kořenovém adresáři jsou dva soubory Dockerfile a docker-compose.yml, stejně jako známá složka .ci-cd s o něco menším počtem skriptů než v backendovém repozitáři (byly odstraněny skripty pro spuštění testů).
Založení projektu v Plesk
Začneme s nastavením Plesk a vytvořením předplatného pro naši stránku.
Instalace rozšíření
V Plesk budeme potřebovat čtyři rozšíření:
Dockerpro správu a vizuální zobrazení stavu kontejnerů v administraci Plesk;Gitpro nastavení kroku nasazení na serveru;Let's Encryptpro generování (a automatické obnovování) bezplatných TLS certifikátů;Firewallpro nastavení filtrování příchozího provozu.
Instalovat je lze přes administraci Plesk v sekci Rozšíření:

Podrobnou konfiguraci rozšíření nebudeme zkoumat, pro naše demo účely budou vyhovovat výchozí nastavení.
Vytvoření předplatného a webové stránky
Dále potřebujeme vytvořit předplatné pro naši stránku helloworld.ru a přidat tam subdoménu dev.helloworld.ru.
- Vytváříme předplatné pro doménu helloworld.ru a uvádíme uživatelské jméno a heslo pro systémového uživatele:

Dole na stránce zaškrtneme Secure the domain with Let’s Encrypt, pokud chceme nastavit HTTPS pro stránku:
- Dále v tomto předplatném vytváříme subdoménu dev.helloworld.ru (pro kterou lze rovněž vydat bezplatný TLS certifikát):

Instalace serverových komponentů
Máme k dispozici server s OS Debian Stretch 9.12 a nainstalovanou řídicí panely Plesk Obsidian 18.0.27.
Musíme nainstalovat a nastavit pro náš projekt:
- PostgreSQL (v našem případě bude jeden server se dvěma databázemi pro dev a prod prostředí).
- RabbitMQ (to samé, jeden instance s různými vhosts pro prostředí).
- Dva instance Redis (pro dev a prod prostředí).
- Docker Registry (pro místní ukládání sestavených Docker obrazů).
- UI rozhraní pro Docker registry.
PostgreSQL
S Plesk už je dodávaná databáze PostgreSQL, avšak ne v nejnovější verzi (k datu psaní tohoto článku Plesk Obsidian Postgres verzí 8.4–10.8). My však chceme pro naši aplikaci nejnovější verzi (12.3 k datu psaní tohoto článku), takže ji nainstalujeme ručně.
Na internetu je spousta podrobných návodů na instalaci Postgres na Debianu (), takže je nebudu podrobně popisovat, pouze uvedu příkazy:
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
Vzhledem k tomu, že PostgreSQL má průměrně nastavené výchozí hodnoty, je nezbytné upravit konfiguraci. S tím nám pomůže : je třeba zadat parametry svého serveru a nahradit nastavení v souboru /etc/postgresql/12/main/postgresql.confnávrhy. Je třeba poznamenat, že podobné kalkulačky nejsou stříbrnou kulkou a databázi je třeba jemněji ladit podle vašeho hardwaru, aplikace a složitosti dotazů. Ale pro začátek je to dostatečné.
Kromě nastavení navržených kalkulačkou měníme také v postgresql.confvýchozí port 5432 na jiný (v našem příkladu — 53983).
Po změně konfiguračního souboru restartujeme postgresql-server příkazem:
service postgresql restart
Nainstalovali jsme a nastavili PostgreSQL. Nyní vytvoříme databáze, uživatele pro dev- a prod- prostředí a udělíme uživatelům práva na správu databází:
$ 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
Přejdeme k instalaci RabbitMQ — zprostředkovatele zpráv pro Celery. Na Debianu se instaluje docela jednoduše:
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
Po instalaci musíme vytvořit vhosts, uživatele a udělit potřebná práva:
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
Nyní nainstalujeme a nastavíme poslední komponentu pro naši aplikaci — Redis. Bude použit jako backend pro ukládání výsledků úloh Celery.
Zvedneme dva Docker kontejnery s Redis pro dev- a prod- prostředí pomocí rozšíření Docker pro Plesk.
- Přejdeme do Plesku, otevřeme sekci Rozšíření, vyhledáme rozšíření Docker a nainstalujeme ho (potřebujeme bezplatnou verzi):

- Přejdeme do nainstalovaného rozšíření a najdeme přes vyhledávání obraz
redis bitnamia nainstalujeme poslední verzi:
- Přejdeme do staženého kontejneru a upravíme konfiguraci: nastavíme port, maximální přidělenou velikost RAM, heslo v proměnných prostředí a namontujeme svazek:

- Provádíme kroky 2-3 pro prod-kontejner, pouze měníme parametry: port, heslo, velikost RAM a cestu ke složce svazku na serveru:

Docker Registry
Kromě základních služeb by bylo dobré na server nainstalovat vlastní repozitář Docker obrazů. Naštěstí je místo na serverech dnes dost levné (určitě levnější než předplatné na DockerHub) a proces instalace soukromého repozitáře je velmi jednoduchý.
Chceme, aby byly nainstalovány:
- chráněný heslem Docker repozitář dostupný přes subdoménu ;
- UI rozhraní pro zobrazení obrazů v repozitáři dostupné na adrese .
K tomu:
- V Plesku vytvoříme dva subdomény v našem předplatném: docker.helloworld.ru a docker-ui.helloworld.ru, a nastavíme pro ně certifikáty Let’s Encrypt.
- Do složky subdomény docker.helloworld.ru přidáme soubor
docker-compose.ymls tímto obsahem: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řes SSH vygenerujeme soubor .htpasswd pro Basic autorizaci v Docker repozitáři:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Sestavíme a spustíme kontejnery:
docker-compose up -d - A je potřeba přesměrovat Nginx na naše kontejnery. To lze provést přes Plesk.
Následující akce je potřeba provést pro subdomény docker.helloworld.ru a docker-ui.helloworld.ru:
V sekci Dev Tools naší stránky se dostaneme do Docker Proxy Rules:

A přidáme pravidlo pro procházení příchozího provozu do našeho kontejneru:

- Zkontrolujeme, že se můžeme autorizovat v našem kontejneru z lokálního počítače:
$ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password UPOZORNĚNÍ! Použití --password přes CLI je nepraktické. Použijte --password-stdin. Úspěšné přihlášení - Také zkontrolujeme funkci subdomény docker-ui.helloworld.ru:

Když kliknete na procházet repozitáře, prohlížeč otevře okno pro přihlášení, kde budete muset zadat uživatelské jméno a heslo pro repozitář. Poté budete přesměrováni na stránku se seznamem repozitářů (prozatím bude prázdná):
Otevřete porty ve Firewallu Plesk
Po instalaci a nastavení komponent musíme otevřít porty, aby byly komponenty přístupné z Docker kontejnerů a z vnější sítě.
Podíváme se, jak to udělat, na příkladu rozšíření Firewall pro Plesk, které jsme nainstalovali dříve.
- Přejdeme do Nástroje & Nastavení > Nastavení > Firewall:

- Přejdeme do Upravit pravidla Firewall Plesk > Přidat vlastní pravidlo a otevření následujících TCP portů pro podsíť Docker (172.0.0.0/8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- Dále přidáme pravidlo, které otevře porty PostgreSQL a management panelu RabbitMQ pro vnější svět:

- Aplikujte pravidla pomocí tlačítka Aplikovat změny:

Nastavení CI/CD v Github Actions
Přistoupíme k nejzajímavější části — nastavení pipeline kontinuální integrace a dodání našeho projektu na server.
Tato pipeline se bude skládat ze dvou částí:
- sestavení obrazu a spuštění testů (pro backend) — na straně Github;
- spuštění migrací (pro backend) a nasazení kontejnerů — na serveru.
Nasazení v Plesk
Nejprve se podíváme na druhý bod (protože od něj závisí první).
Proces nasazení nastavíme pomocí rozšíření Git pro Plesk.
Uvažujme příklad s produkčním prostředím pro Backend repozitář.
- Přejdeme do odběru našeho webu Helloworld a přejdeme do podsekce Git:

- Vložíme do pole „Remote Git repository“ odkaz na náš Github repozitář a změníme výchozí složku
httpdocsna jinou (například,/httpdocs/hw_back):
- Zkopírujte SSH veřejný klíč z předchozího kroku a ho do nastavení Github.
- Stiskněte OK na obrazovce v bodě 2, poté budete přesměrováni na stránku repozitáře v Plesk. Nyní musíme nastavit aktualizaci repozitáře při commitech do větve master. K tomu přejdeme do Nastavení repozitáře a uložíme hodnotu
Webhook URL(bude potřeba později při nastavování Github Actions):
- Na obrazovce z předchozího bodu do pole Actions zadáme skript pro spuštění nasazení:
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}— cesta k adresáři produkčního backend repozitáře na serveru;
{ENV}— prostředí (dev/production), v našem případěprod;
{DOCKER_REGISTRY_HOST}— host našich docker repozitářů
{TG_BOT_TOKEN}— token Telegram bota;
{TG_CHAT_ID}— ID chatu/kanálu pro zasílání oznámení.Příklad skriptu:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - Přidáváme uživatele z našeho předplatného do skupiny Docker (aby mohl spravovat kontejnery):
sudo usermod -aG docker helloworld_admin
Vývojové prostředí pro backend-repozitář a frontend se nastavuje obdobně.
Pipeline nasazení v Github Actions
Přecházíme k nastavení první části našeho CI/CD pipeline v Github Actions.
Backend plánovali udělat na Linuxu. Backend interaguje s DB, načítá potřebný seznam privilegií a poté, v závislosti na tom, jaká privilegium má autorizovaný uživatel, poskytuje přístup k podepisování finančních dokumentů a jejich zasílání k realizaci, nebo generaci nějaké zprávy.
Pipeline je popsána v .
Než se na něj podíváme, vyplníme v Github potřebné tajné proměnné. K tomu přejdeme do Nastavení -> Tajné:
DOCKER_REGISTRY— host našich Docker-repozitářů (docker.helloworld.ru);DOCKER_LOGIN— přihlašovací jméno k Docker-repozitáři;DOCKER_PASSWORD— heslo k němu;DEPLOY_HOST— host, na kterém je dostupné administrativní rozhraní Plesk (např. :8443 nebo :8443);DEPLOY_BACK_PROD_TOKEN— token pro nasazení do prod-repozitáře na serveru (dostali jsme jej v Nasazení v Plesk bod 4);DEPLOY_BACK_DEV_TOKEN— token pro nasazení do dev-repozitáře na serveru.
Proces nasazení je jednoduchý a skládá se ze tří hlavních kroků:
- sestavení a publikace obrazu v našem repozitáři;
- spuštění testů v kontejneru na základě čerstvě sestaveného obrazu;
- nasazení do požadovaného prostředí v závislosti na větvi (dev/master).
Frontend
se příliš neliší od backendového. Chybí v něm krok se spuštěním testů a mění se názvy tokenů pro nasazení. Tajné proměnné pro front-repozitář je mimochodem třeba vyplnit zvlášť.
Nastavení webu
Proxy provozu přes Nginx
No, a jsme na konci. Zbývá pouze nastavit proxy příchozího a odchozího provozu do našeho kontejneru přes Nginx. Tento proces jsme již probrali v bodě 5 nastavení Docker Registry. Totéž je třeba zopakovat pro backend a frontend v dev a prod prostředích.
Připojím snímky nastavení.
Backend plánovali udělat na Linuxu. Backend interaguje s DB, načítá potřebný seznam privilegií a poté, v závislosti na tom, jaká privilegium má autorizovaný uživatel, poskytuje přístup k podepisování finančních dokumentů a jejich zasílání k realizaci, nebo generaci nějaké zprávy.

Frontend

Důležité upřesnění. Do frontendového kontejneru budou proxy všechny URL, kromě těch, které začínají na /api/ — ty budou proxy do backendového kontejneru (proto v backendovém kontejneru by měly všechny zpracovatele začínat na /api/).
Závěry
Nyní by měl být náš web dostupný na adresách helloworld.ru a dev.helloworld.ru (prod a dev prostředí odpovídající).
Celkově jsme se naučili, jak připravit jednoduchou aplikaci na Flask a Angular a nastavit v Github Actions pipeline pro její nasazení na serveru řízeném Pleskem.
Zopakuji odkazy na repozitáře s kódem: , .
Zdroj: habr.com
















