
In questu articulu, sparteraghju a mo sperienza di cunfigurà CI / CD cù u Plesk Control Panel è Github Actions. Oghje avemu da amparà cumu implementà un prughjettu simplice cù u nome "Helloworld". Hè scrittu in u framework Flask Python, cù i travagliadori Celery è un frontend Angular 8.
Ligami à i repositori: , .
In a prima parte di l'articulu, fighjemu u nostru prughjettu è e so parti. In u sicondu, avemu da capisce cumu si stallanu Plesk è installate l'estensioni è i cumpunenti necessarii (DB, RabbitMQ, Redis, Docker, etc.).
In a terza parte, scopreremu infine cumu stabilisce un pipeline per implementà u nostru prughjettu à un servitore in un ambiente di sviluppu è prod. E poi avemu da lancià u situ nant'à u servore.
È iè, mi sò scurdatu di presentà mi. Mi chjamu Oleg Borzov, sò un sviluppatore fullstack in a squadra CRM per i gestori di ipoteche in Domclick.
Panoramica di u prughjettu
Prima, fighjemu dui repositori di prughjettu - backend è front - è andemu nantu à u codice.
Backend : Flacon + Céleri
Per a parte posteriore, aghju pigliatu una mansa chì hè abbastanza populari trà i sviluppatori di Python: u framework Flask (per l'API) è Celery (per a fila di attività). SQLAchemy hè utilizatu cum'è ORM. L'alambic hè usatu per migrazioni. Per a validazione JSON in maniglie - Marshmallow.
В ci hè un schedariu Readme.md cù una descrizzione dettagliata di a struttura è struzzioni per eseguisce u prugettu.
abbastanza sèmplice, custituitu di 6 penne:
/ping- per verificà a dispunibilità;- gestisce per a registrazione, l'autorizazione, a disautorizazione è l'ottenimentu di un utilizatore autorizatu;
- un manicu di email chì mette un compitu in a fila d'Api.
ancu più faciule, ci hè solu un prublema send_mail_task.
In u cartulare ci sò dui sottucartuli:
dockercù dui Dockerfiles (base.dockerfileper custruisce una maghjina di basa raramente cambiante èDockerfileper l'assemblee principali);.env_files- cù schedari cù variabili di l'ambienti per diversi ambienti.
Ci sò quattru schedarii docker-compose à a radica di u prugettu:
docker-compose.local.db.ymlper crià una basa di dati lucale per u sviluppu;docker-compose.local.workers.ymlper l'elevazione lucale di u travagliu, basa di dati, Redis è RabbitMQ;docker-compose.test.ymlper eseguisce testi durante a implementazione;docker-compose.ymlper l'implementazione.
È l'ultimu cartulare chì ci interessa - . Contene script di shell per l'implementazione:
deploy.sh- lanciamentu di migrazione è implementazione. Funziona nantu à u servitore dopu à custruisce è eseguisce testi in Github Actions;rollback.sh- rollback di cuntenituri à a versione precedente di l'assemblea;curl_tg.sh- mandendu notifiche di implementazione à Telegram.
Frontend nantu à Angular
assai più simplice di Beck. U fronte hè custituitu di trè pagine:
- Pagina principale cù una forma per mandà email è un buttone di uscita.
- Pagina di login.
- Pagina di registrazione.
A pagina principale pare ascetica:

Ci sò dui schedari à a radica Dockerfile и docker-compose.yml, è ancu u cartulare familiar .ci-cd cù un pocu menu di script chì in u repository back (scripts sguassati per l'esecuzione di testi).
Cumincià un prughjettu in Plesk
Accuminciamu per cunfigurà Plesk è creendu un abbonamentu per u nostru situ.
Installazione di estensioni
In Plesk, avemu bisognu di quattru estensioni:
Dockerper gestisce è visualizà visualmente u statutu di cuntenituri in u pannellu di amministrazione di Plesk;Gitper cunfigurà u passu di implementazione in u servitore;Let's Encryptper generà (è rinnuvà automaticamente) certificati TLS gratuiti;Firewallper cunfigurà u filtru di u trafficu in entrata.
Pudete installà per mezu di u pannellu di amministrazione di Plesk in a sezione Estensioni:

Ùn cunsideremu micca i paràmetri detallati per l'estensioni, i paràmetri predeterminati facenu per i nostri scopi demo.
Crea un abbonamentu è u situ
Dopu, avemu bisognu di creà un abbunamentu per u nostru situ web helloworld.ru è aghjunghje u subdominiu dev.helloworld.ru.
- Crea un abbonamentu per u duminiu helloworld.ru è specificate u login-password per l'utilizatore di u sistema:

Verificate a casella in u fondu di a pagina Assicurà u duminiu cù Let's Encryptse vulemu stabilisce HTTPS per u situ:
- In seguitu, in questu abbonamentu, crea un sottodominiu dev.helloworld.ru (per quale pudete ancu emette un certificatu TLS gratuitu):

Installazione di cumpunenti di u Server
Avemu un servitore cun OS Debian Stretch 9.12 è pannellu di cuntrollu installatu Plesk Obsidian 18.0.27.
Avemu bisognu di stallà è cunfigurà per u nostru prughjettu:
- PostgreSQL (in u nostru casu, ci sarà un servitore cù duie basa di dati per ambienti dev è prod).
- RabbitMQ (stessa, stessa istanza cù diversi vhosts per ambienti).
- Dui istanze Redis (per ambienti dev è prod).
- Docker Registry (per u almacenamentu locale di l'imaghjini Docker custruitu).
- UI per u registru Docker.
PostgreSQL
Plesk vene digià cù PostgreSQL DBMS, ma micca l'ultima versione (à u mumentu di a scrittura Plesk Obsidian Versioni Postgres 8.4-10.8). Vulemu l'ultima versione per a nostra applicazione (12.3 à u mumentu di a scrittura), cusì l'installeremu manualmente.
Istruzzioni dettagliate per l'installazione di Postgres Debian Ci n'hè assai nant'à internet (), per quessa ùn li descriveraghju micca in dettagliu, daraghju solu i cumandamenti:
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
Cunsiderendu chì PostgreSQL hà paràmetri predeterminati piuttostu mediocre, hè necessariu di curregà a cunfigurazione. Questu ci aiuterà : avete bisognu di guidà in i paràmetri di u vostru servitore è rimpiazzà i paràmetri in u schedariu /etc/postgresql/12/main/postgresql.confà quelli offerti. Ci hè da nutà quì chì tali calculatrici ùn sò micca una bala magica, è a basa deve esse sintonizzata più precisamente, basatu annantu à u vostru hardware, l'applicazione è a cumplessità di a dumanda. Ma questu hè abbastanza per cumincià.
In più di i paràmetri pruposti da a calculatrice, cambiamu ancu postgresql.confu portu predeterminatu 5432 à un altru (in u nostru esempiu - 53983).
Dopu avè cambiatu u schedariu di cunfigurazione, riavvia u postgresql-server cù u cumandimu:
service postgresql restart
Avemu stallatu è cunfiguratu PostgreSQL. Avà creemu una basa di dati, utilizatori per ambienti di sviluppu è prod, è dete à l'utilizatori diritti per gestisce a basa di dati:
$ 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
Passemu à l'installazione di RabbitMQ, un broker di missaghji per Celery. Hè stallatu annantu à Debian Hè abbastanza simplice:
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
Dopu a stallazione, avemu bisognu di creà vhosts, utilizatori è cuncede i diritti necessarii:
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
Avà stallà è cunfigurà l'ultimu cumpunente per a nostra applicazione - Redis. Serà utilizatu cum'è backend per almacenà i risultati di i travaglii di Celery.
Aumenteremu dui cuntenituri Docker cù Redis per ambienti dev è prod utilizendu l'estensione Docker per Plesk.
- Andemu à Plesk, andemu à a sezione Estensioni, cercate l'estensione Docker è installate (avemu bisognu di una versione libera):

- Andate à l'estensione installata, truvate l'imaghjini attraversu a ricerca
redis bitnamiè stallà l'ultima versione:
- Andemu in u containeru telecaricatu è aghjustemu a cunfigurazione: specificate u portu, a dimensione massima di RAM assignata, a password in e variabili di l'ambiente, è muntate u voluminu:

- Facemu i passi 2-3 per u cuntainer prod, in i paràmetri solu cambiate i paràmetri: portu, password, dimensione RAM è percorsu à u cartulare di volumi in u servitore:

Docker Registry
In più di i servizii di basa, saria bellu di mette u vostru propiu repositoriu d'imaghjini Docker in u servitore. Fortunatamente, u spaziu di u servitore hè avà abbastanza prezzu (certamente più prezzu di un abbonamentu DockerHub), è u prucessu di stallà un repositoriu privatu hè assai simplice.
Vulemu avè:
- Repositoriu Docker protettu da password accessibile in un subdominiu ;
- UI per vede l'imaghjini in u repository, dispunibule à .
Per fà quessa:
- Creemu dui subdominii in Plesk in a nostra abbunamentu: docker.helloworld.ru è docker-ui.helloworld.ru, è cunfigurà i certificati Let's Encrypt per elli.
- Aghjunghjite u schedariu à u cartulare di subdominiu docker.helloworld.ru
docker-compose.ymlcun cuntenutu cum'è questu: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' - Sottu SSH, genereremu u schedariu .htpasswd per l'autorizazione Basic in u repository Docker:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Raccoglie e solleva i contenitori:
docker-compose up -d - È avemu bisognu di reindirizzà Nginx à i nostri cuntenituri. Questu pò esse fattu attraversu Plesk.
I seguenti passi devenu esse fattu per i subdominii docker.helloworld.ru è docker-ui.helloworld.ru:
rùbbrica Strumente Dev u nostru situ vai à Regoli di Docker Proxy:

È aghjunghje una regula per proxy u trafficu entrante à u nostru containeru:

- Avemu verificatu chì pudemu login in u nostru containeru da a macchina locale:
$ 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 - Fighjemu ancu u funziunamentu di u subdomain docker-ui.helloworld.ru:

Quandu clicate nantu à Sfoglia i repositori, u navigatore mostrarà una finestra d'autorizazione induve duverete inserisce u nome d'utilizatore è a password per u repository. Dopu quì, seremu trasferitu à una pagina cù una lista di repositori (per avà, serà viotu per voi):
Apertura di porti in Plesk Firewall
Dopu a stallazione è a cunfigurazione di i cumpunenti, avemu bisognu di apre i porti per chì i cumpunenti sò accessibili da i cuntenituri Docker è a reta esterna.
Videmu cumu fà questu utilizendu l'estensione Firewall per Plesk chì avemu installatu prima.
- Andà à Strumenti & Settings> Settings> Firewall:

- Andà à Mudificà e regule Plesk Firewall> Add Rule Custom è apre i seguenti porti TCP per a subnet Docker (172.0.0.0 / 8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- Avemu ancu aghjunghje una regula chì aprerà i porti PostgreSQL è i pannelli di gestione RabbitMQ à u mondu esternu:

- Applica e regule cù u buttone Apply Changes:

Configurazione di CI/CD in Github Actions
Andemu à a parte più interessante - stabilisce un pipeline di integrazione cuntinuu è furnisce u nostru prughjettu à u servitore.
Stu pipeline sarà custituitu di dui parti:
- custruì una maghjina è eseguisce e teste (per u backend) - in u latu di Github;
- esecuzione di migrazioni (per u backend) è implementazione di cuntenituri - nantu à u servitore.
Implementa à Plesk
Trattemu di u sicondu puntu prima (perchè u primu dipende da ellu).
Cunfiguremu u prucessu di implementazione utilizendu l'estensione Git per Plesk.
Cunsiderate un esempiu cù un ambiente Prod per un repository Backend.
- Andemu à l'abbunamentu di u nostru situ Helloworld è andemu à a sottosezzione Git:

- Inserite un ligame à u nostru repository Github in u campu "Repository Git Remote" è cambia u cartulare predeterminatu
httpdocsà un altru (es./httpdocs/hw_back):
- Copia a chjave publica SSH da u passu precedente è hè in i paràmetri di Github.
- Cliccate OK nant'à u screnu in u passu 2, dopu chì seremu ridiretti à a pagina di repository in Plesk. Avà avemu bisognu di cunfigurà u repository per esse aghjurnatu nantu à i cummissioni à u ramu maestru. Per fà questu, andate à Impostazioni di repository è salvà u valore
Webhook URL(avemu bisognu più tardi quandu cunfigurà Github Actions):
- In u campu Azioni nantu à u screnu da u paràgrafu precedente, entre in u script per lancià a implementazione:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}induve:
{REPOSITORY_ABSOLUTE_PATH}- percorsu à u cartulare prod di u repository backend in u servitore;
{ENV}- ambiente (dev / prod), in u nostru casuprod;
{DOCKER_REGISTRY_HOST}- l'ospite di u nostru repository docker
{TG_BOT_TOKEN}- Telegram bot token;
{TG_CHAT_ID}- ID di u chat / canale per mandà notificazioni.Esempiu di 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 - Aghjunghjite un utilizatore da u nostru abbonamentu à u gruppu Docker (per pudè gestisce i cuntenituri):
sudo usermod -aG docker helloworld_admin
L'ambiente di dev per u repository backend è u frontend sò stallati in u listessu modu.
Pipeline di implementazione in Github Actions
Passemu à stallà a prima parte di a nostra pipeline CI / CD in Github Actions.
Backend
U pipeline hè descrittu in .
Ma prima di analizà, compie e variabili Secret chì avemu bisognu in Github. Per fà questu, andate à Settings -> Secrets:
DOCKER_REGISTRY- l'ospite di u nostru repository Docker (docker.helloworld.ru);DOCKER_LOGIN- accede à u repositoriu Docker;DOCKER_PASSWORD- password per questu;DEPLOY_HOST- host induve u pannellu admin Plesk hè dispunibule (esempiu: : 8443 o : 8443);DEPLOY_BACK_PROD_TOKEN- un token per a implementazione à u prod-repository in u servitore (l'avemu in Deployment in Plesk p. 4);DEPLOY_BACK_DEV_TOKEN- token per implementazione à u repository dev in u servitore.
U prucessu di implementazione hè simplice è si compone di trè passi principali:
- custruisce è publicà l'imaghjini in u nostru repository;
- esecuzione di teste in un containeru basatu annantu à una maghjina appena custruita;
- implementazione à l'ambiente desideratu secondu u ramu (dev/master).
Front end
pocu sfarente da Beck. Manca un passu cù e teste in esecuzione è cambia i nomi di tokens per a implementazione. I secreti per u repositoriu di fronte, per via, deve esse cumpletu separatamente.
Configurazione di u situ
Proxy trafficu attraversu Nginx
Ebbè, avemu ghjuntu à a fine. Resta solu per cunfigurà u proxy di u trafficu entrante è uscente à u nostru containeru attraversu Nginx. Avemu digià cupertu stu prucessu in u puntu 5 di a cunfigurazione di u Docker Registry. U listessu deve esse ripetutu per a parte posteriore è frontale in ambienti dev è prod.
Puderaghju screenshots di i paràmetri.
Backend

Front end

Chjarificazione impurtante. Tutti l'URL seranu proxy à u cuntinuu di frontend, eccettu quelli chì cumincianu cù /api/ - seranu proxy à u cuntainer posteriore (so in u cuntinuu di daretu, tutti i manipulatori devenu principià cù /api/).
Risultati
Avà u nostru situ deve esse dispunibule in helloworld.ru è dev.helloworld.ru (prod- e dev-environments, rispettivamente).
In totale, avemu amparatu à preparà una applicazione simplice in Flask è Angular è stabilisce una pipeline in Github Actions per sparghje à un servitore chì esegue Plesk.
Dupliceraghju i ligami à i repositori cù u codice: , .
Source: www.habr.com
