CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

CI/CD nan Github Aksyon pou yon pwojè flacon + angilè
Nan atik sa a, mwen pral pataje eksperyans mwen nan mete kanpe CI/CD lè l sèvi avèk Plesk Kontwòl Panel ak Github Actions. Jodi a nou pral aprann ki jan yo deplwaye yon pwojè senp ak non an "Helloworld" san konplike. Li ekri nan kad Flask Python, ak travayè seleri ak yon entèfas angilè 8.

Lyen ki mennen nan depo: backend, fasad.

Nan premye pati atik la, nou pral gade pwojè nou an ak pati li yo. Nan dezyèm lan, nou pral konnen ki jan yo mete Plesk ak enstale ekstansyon ki nesesè yo ak konpozan (DB, RabbitMQ, Redis, Docker, elatriye).

Nan twazyèm pati a, nou pral finalman konnen ki jan yo mete kanpe yon tiyo pou deplwaye pwojè nou an nan yon sèvè nan yon anviwònman dev ak prod. Lè sa a, nou pral lanse sit la sou sèvè a.

E wi, mwen bliye prezante tèt mwen. Non mwen se Oleg Borzov, mwen se yon devlopè fullstack nan ekip CRM pou manadjè ipotèk nan Domclick.

Apèsi sou lekòl la Pwojè

Premyèman, ann gade de depo pwojè - backend ak devan - epi ale sou kòd la.

Backend: Flacon + seleri

Pou pati dèyè a, mwen te pran yon pakèt ki byen popilè nan mitan devlopè Python: fondasyon an Flask (pou API a) ak seleri (pou keu travay la). SQLAchemy yo itilize kòm ORM. Alambik yo itilize pou migrasyon. Pou validation JSON nan manch - Marshmallow.

В depo gen yon dosye Readme.md ak yon deskripsyon detaye sou estrikti a ak enstriksyon pou kouri pwojè a.

Web Pati API byen senp, konsiste de 6 plim:

  • /ping - pou tcheke disponiblite;
  • manch pou anrejistreman, otorizasyon, de-otorizasyon ak jwenn yon itilizatè otorize;
  • yon manch imèl ki mete yon travay nan keu seleri a.

Pati seleri menm pi fasil, gen yon sèl pwoblèm send_mail_task.

Nan katab la /conf gen de sousdosye:

  • docker ak de Dockerfile (base.dockerfile pou konstwi yon imaj de baz raman chanje ak Dockerfile pou asanble prensipal);
  • .env_files - ak dosye ak varyab anviwònman pou diferan anviwònman.

Gen kat dosye docker-konpoze nan rasin pwojè a:

  • docker-compose.local.db.yml ogmante yon baz done lokal pou devlopman;
  • docker-compose.local.workers.yml pou ogmante lokal travayè a, baz done, Redis ak RabbitMQ;
  • docker-compose.test.yml fè tès pandan deplwaman;
  • docker-compose.yml pou deplwaman.

Ak dènye folder nou enterese nan - .ci-cd. Li gen scripts koki pou deplwaman:

  • deploy.sh — lansman migrasyon ak deplwaman. Kouri sou sèvè a apre bati ak kouri tès nan Github Actions;
  • rollback.sh - Rollback nan resipyan nan vèsyon anvan asanble a;
  • curl_tg.sh - voye notifikasyon deplwaman bay Telegram.

Frontend sou angilè

Repozitwa ak devan pi senp pase Beck la. Devan an konsiste de twa paj:

  • Paj prensipal ak yon fòm pou voye imèl ak yon bouton sòti.
  • Paj konekte.
  • Paj enskripsyon an.

Paj prensipal la sanble asèt:

CI/CD nan Github Aksyon pou yon pwojè flacon + angilè
Gen de dosye nan rasin lan Dockerfile и docker-compose.yml, osi byen ke katab la abitye .ci-cd ak yon ti kras mwens scripts pase nan repozitwa a tounen (retire scripts pou kouri tès yo).

Kòmanse yon pwojè nan Plesk

Ann kòmanse pa mete Plesk epi kreye yon abònman pou sit nou an.

Enstale ekstansyon

Nan Plesk, nou bezwen kat ekstansyon:

  • Docker jere ak vizyèlman montre estati resipyan yo nan panèl admin Plesk la;
  • Git konfigirasyon etap deplwaman sou sèvè a;
  • Let's Encrypt jenere (ak renouvle oto) sètifika TLS gratis;
  • Firewall konfigirasyon filtraj trafik k ap rantre.

Ou ka enstale yo atravè panèl admin Plesk nan seksyon ekstansyon yo:

CI/CD nan Github Aksyon pou yon pwojè flacon + angilè
Nou pa pral konsidere paramèt detaye pou ekstansyon yo, paramèt default yo ap fè pou rezon Demo nou an.

Kreye yon abònman ak sit

Apre sa, nou bezwen kreye yon abònman pou sit entènèt helloworld.ru nou an epi ajoute soudomain dev.helloworld.ru la.

  1. Kreye yon abònman pou domèn helloworld.ru epi presize modpas login pou itilizatè sistèm lan:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè
    Tcheke kare ki anba paj la Sekirize domèn nan ak ann ankriptesi nou vle mete HTTPS pou sit la:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  2. Apre sa, nan abònman sa a, kreye yon subdomain dev.helloworld.ru (pou ki ou kapab tou bay yon sètifika TLS gratis):

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

Enstale konpozan sèvè

Nou gen yon sèvè ak OS Debian Stretch 9.12 ak enstale panèl kontwòl Plesk Obsidian 18.0.27.

Nou bezwen enstale ak konfigirasyon pou pwojè nou an:

  • PostgreSQL (nan ka nou an, pral gen yon sèl sèvè ak de baz done pou anviwònman dev ak prod).
  • RabbitMQ (menm, menm egzanp ak vhosts diferan pou anviwònman).
  • De egzanp Redis (pou anviwònman dev ak prod).
  • Docker Rejis (pou depo lokal imaj Docker bati).
  • UI pou rejis Docker.

Postgrèskl

Plesk deja vini ak PostgreSQL DBMS, men se pa dènye vèsyon an (nan moman w ap ekri Plesk Obsidian sipòte Postgres vèsyon 8.4–10.8). Nou vle vèsyon an dènye pou aplikasyon nou an (12.3 nan moman sa a ekri), kidonk nou pral enstale li manyèlman.

Gen anpil enstriksyon detaye pou enstale Postgres sou Debian sou nèt la (egzanp), Se konsa, mwen pa pral dekri yo an detay, mwen pral jis bay kòmandman yo:

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

Lè ou konsidere ke PostgreSQL gen anviwònman default olye medyokri, li nesesè korije konfigirasyon an. Sa ap ede nou kalkilatris: ou bezwen kondwi nan paramèt yo nan sèvè ou a epi ranplase anviwònman yo nan dosye a /etc/postgresql/12/main/postgresql.confbay moun yo ofri yo. Li ta dwe remake isit la ke kalkilatris sa yo se pa yon bal majik, ak baz la ta dwe branche pi jisteman, ki baze sou pyès ki nan konpitè, aplikasyon, ak konpleksite rechèch ou an. Men, sa a se ase yo kòmanse.

Anplis de anviwònman yo pwopoze pa kalkilatris la, nou menm tou nou chanje nan postgresql.confpò a default 5432 nan yon lòt (nan egzanp nou an - 53983).

Apre chanje fichye konfigirasyon an, rekòmanse postgresql-server ak lòd la:

service postgresql restart

Nou te enstale ak konfigirasyon PostgreSQL. Koulye a, ann kreye yon baz done, itilizatè yo pou anviwònman dev ak prod, epi bay itilizatè yo dwa pou jere baz done a:

$ 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

Lapen MQ

Ann ale nan enstale RabbitMQ, yon koutye mesaj pou seleri. Enstale li sou Debian se byen senp:

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

Apre enstalasyon, nou bezwen kreye vhosts, itilizatè yo ak bay dwa ki nesesè yo:

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

Koulye a, ann enstale ak konfigirasyon dènye eleman pou aplikasyon nou an - Redis. Li pral itilize kòm yon backend pou estoke rezilta yo nan travay seleri.

Nou pral ogmante de resipyan Docker ak Redis pou anviwònman dev ak prod lè l sèvi avèk ekstansyon an Docker pou Plesk.

  1. Nou ale nan Plesk, ale nan seksyon ekstansyon, chèche ekstansyon Docker epi enstale li (nou bezwen yon vèsyon gratis):

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  2. Ale nan ekstansyon enstale a, jwenn imaj la atravè rechèch la redis bitnami epi enstale dènye vèsyon an:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  3. Nou antre nan veso telechaje a epi ajiste konfigirasyon an: presize pò a, gwosè maksimòm RAM atribye ba a, modpas la nan varyab anviwònman yo, epi monte volim la:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  4. Nou fè etap 2-3 pou veso prod la, nan anviwònman yo nou sèlman chanje paramèt yo: pò, modpas, gwosè RAM ak chemen nan katab volim sou sèvè a:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

Docker Rejis

Anplis de sèvis debaz yo, li ta bon pou mete pwòp repozitwa imaj Docker ou sou sèvè a. Erezman, espas sèvè kounye a byen bon mache (sètènman pi bon mache pase yon abònman DockerHub), ak pwosesis pou mete yon depo prive trè senp.

Nou vle genyen:

Pou fè sa:

  1. Ann kreye de subdomains nan Plesk nan abònman nou an: docker.helloworld.ru ak docker-ui.helloworld.ru, epi konfigirasyon ann ankripte sètifika pou yo.
  2. Ajoute fichye a nan katab subdomain docker.helloworld.ru docker-compose.yml ak kontni tankou sa a:
    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'
    

  3. Anba SSH, nou pral jenere fichye .htpasswd pou otorizasyon debaz nan repozitwa Docker la:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Kolekte epi leve veso yo:
    docker-compose up -d
  5. Epi nou bezwen redireksyon Nginx nan resipyan nou yo. Sa a ka fè atravè Plesk.

Etap sa yo dwe fè pou subdomains docker.helloworld.ru ak docker-ui.helloworld.ru:

Nan seksyon Dev Zouti sit nou an ale nan Règ Docker Proxy:

CI/CD nan Github Aksyon pou yon pwojè flacon + angilè
Epi ajoute yon règ nan proxy trafik k ap rantre nan veso nou an:

CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  1. Nou tcheke ke nou ka konekte nan veso nou an nan machin lokal la:
    $ 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
  2. Ann tcheke tou operasyon an nan docker-ui.helloworld.ru subdomain:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè
    Lè w klike sou Browse repositories, navigatè a pral montre yon fenèt otorizasyon kote w ap bezwen antre non itilizatè a ak modpas pou depo a. Apre sa, nou pral transfere nan yon paj ki gen yon lis depo (pou kounye a, li pral vid pou ou):

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

Louvri pò nan Plesk Firewall

Apre enstale ak konfigirasyon eleman yo, nou bezwen louvri pò pou konpozan yo aksesib nan resipyan Docker ak rezo ekstèn lan.

Ann wè ki jan fè sa lè l sèvi avèk ekstansyon Firewall pou Plesk ke nou enstale pi bonè.

  1. Ale nan Zouti & Anviwònman> Anviwònman> Firewall:
    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè
  2. Ale nan Modifye Règ Plesk Firewall > Ajoute Règ Custom epi louvri pò TCP sa yo pou sous-rezo Docker (172.0.0.0 / 8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  3. Nou pral ajoute tou yon règ ki pral louvri pò PostgreSQL ak panno jesyon RabbitMQ nan mond lan deyò:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  4. Aplike règ yo lè l sèvi avèk bouton Aplike Chanjman yo:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

Mete kanpe CI/CD nan Github Actions

Ann desann nan pati ki pi enteresan an - mete kanpe yon tiyo entegrasyon kontinyèl ak livrezon pwojè nou an sou sèvè a.

Tiyo sa a pral gen de pati:

  • bati yon imaj ak kouri tès (pou backend la) - sou bò Github;
  • kouri migrasyon (pou backend la) ak deplwaye resipyan - sou sèvè a.

Deplwaye nan Plesk

Ann fè fas ak dezyèm pwen an premye (paske premye a depann sou li).

Nou pral konfigirasyon pwosesis deplwaman an lè l sèvi avèk ekstansyon Git pou Plesk.

Konsidere yon egzanp ak yon anviwònman Prod pou yon depo Backend.

  1. Nou ale nan abònman sou sit entènèt Helloworld nou an epi ale nan seksyon Git la:

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  2. Mete yon lyen nan repozitwa Github nou an nan jaden "Remote Git repository" epi chanje katab la default. httpdocs nan yon lòt (egzanp. /httpdocs/hw_back):

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  3. Kopi kle piblik SSH ki soti nan etap anvan an epi ajoute li nan anviwònman Github.
  4. Klike OK sou ekran an nan etap 2, apre sa nou pral redireksyon sou paj depo a nan Plesk. Koulye a, nou bezwen konfigirasyon depo a yo dwe mete ajou sou komèt nan branch mèt la. Pou fè sa, ale nan Anviwònman depo epi sove valè a Webhook URL (nou pral bezwen li pita lè nou mete Aksyon Github):

    CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

  5. Nan jaden Aksyon ki sou ekran an nan paragraf anvan an, antre script la pou lanse deplwaman an:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    kote:

    {REPOSITORY_ABSOLUTE_PATH} - chemen nan folder nan prod nan repozitwa a backend sou sèvè a;
    {ENV} - anviwònman (dev / prod), nan ka nou an prod;
    {DOCKER_REGISTRY_HOST} - lame a nan depo docker nou an
    {TG_BOT_TOKEN} — Telegram bot jeton;
    {TG_CHAT_ID} — ID chat/chanèl pou voye notifikasyon yo.

    Egzanp 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
  6. Ajoute yon itilizatè ki soti nan abònman nou an nan gwoup la Docker (pou yo ka jere resipyan):
    sudo usermod -aG docker helloworld_admin

Anviwònman dev pou repozitwa backend la ak frontend yo mete kanpe nan menm fason an.

Tiyo deplwaman nan Github Actions

Ann kontinye nan mete kanpe premye pati nan tiyo CI/CD nou an nan Github Actions.

backend

Tiyo a dekri nan fichye deploy.yml.

Men, anvan analiz li, se pou nou ranpli varyab sekrè nou bezwen nan Github. Pou fè sa, ale nan Anviwònman -> Sekrè:

  • DOCKER_REGISTRY - lame a nan depo Docker nou an (docker.helloworld.ru);
  • DOCKER_LOGIN - konekte nan repozitwa Docker la;
  • DOCKER_PASSWORD - modpas pou li;
  • DEPLOY_HOST — lame kote panèl admin Plesk la disponib (egzanp: helloworld.com: 8443 oswa 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - yon siy pou deplwaman nan prod-repository sou sèvè a (nou te jwenn li nan Deplwaman nan Plesk p. 4);
  • DEPLOY_BACK_DEV_TOKEN - siy pou deplwaman nan depo dev sou sèvè a.

Pwosesis deplwaman an se senp epi li gen twa etap prensipal:

  • bati ak pibliye imaj la nan depo nou an;
  • fè tès nan yon veso ki baze sou yon imaj ki fèk bati;
  • deplwaman nan anviwònman an vle depann sou branch lan (dev / mèt).

Front end

Fichye deploy.yml pou depo devan an ti diferan de Beck la. Li manke yon etap ak tès kouri ak chanje non yo nan marqueur pou deplwaman. Sekrè pou depo devan an, nan chemen an, bezwen ranpli separeman.

Konfigirasyon sit la

Proxy trafik atravè Nginx

Oke, nou rive nan fen an. Li rete sèlman nan konfigirasyon proxy trafik fèk ap rantre ak sòtan nan veso nou an atravè Nginx. Nou te deja kouvri pwosesis sa a nan etap 5 nan konfigirasyon Docker Rejis la. Menm bagay la tou ta dwe repete pou pati dèyè yo ak devan nan anviwònman dev ak prod.

Mwen pral bay Ekran nan anviwònman yo.

backend

CI/CD nan Github Aksyon pou yon pwojè flacon + angilè

Front end

CI/CD nan Github Aksyon pou yon pwojè flacon + angilè
Klasifikasyon enpòtan. Tout URL yo pral proxy nan veso a entèfas, eksepte sa yo ki kòmanse ak /api/ - yo pral proxy nan veso dèyè a (konsa nan veso dèyè a, tout moun kap okipe yo dwe kòmanse avèk yo /api/).

Rezilta

Koulye a, sit nou an ta dwe disponib nan helloworld.ru ak dev.helloworld.ru (prod- ak dev-environments, respektivman).

An total, nou te aprann kijan pou prepare yon aplikasyon senp nan Flask ak angilè epi mete yon tiyo nan Github Actions pou woule li sou yon sèvè ki kouri Plesk.

Mwen pral kopi lyen ki mennen nan depo yo ak kòd la: backend, fasad.

Sous: www.habr.com

Add nouvo kòmantè