CI/CD v Github Actions pre projekt na Flask+Angular

CI/CD v Github Actions pre projekt na Flask+Angular
V tomto článku sa podelím o svoje skúsenosti s nastavením CI/CD pomocou ovládacieho panela Plesk a Github Actions. Dnes sa naučíme nasadiť jednoduchý projekt s nezložitým názvom „Helloworld“. Je napísaný na Python frameworku Flask, s pracovníkmi na Celery a frontend je na Angular 8.

Odkazy na repozitáre: backend, frontend.

V prvej časti článku sa pozrieme na náš projekt a jeho časti. V druhej časti sa dozvieme, ako nastaviť Plesk a nainštalovať potrebné rozšírenia a komponenty (DB, RabbitMQ, Redis, Docker atď.).

V tretej časti sa konečne dozvieme, ako nastaviť pipeline pre nasadenie nášho projektu na server do dev- a prod-prostredia. Potom spustíme webovú stránku na serveri.

A áno, zabudol som sa predstaviť. Volám sa Oleg Borzov, som fullstack vývojár v tíme CRM pre manažérov hypotekárnych úverov v Domklik.

Prehľad projektu

Najskôr sa pozrime na dva repozitáre projektu - backend a frontend - a prejdeme si kódom.

Backendová časť: Flask+Celery

Pre backend som si vybral dostatočne populárnu medzi Python vývojármi kombináciu: framework Flask (pre API) a Celery (pre frontu úloh). Ako ORM sa používa SQLAlchemy. Pre migrácie sa používa Alembic. Pre validáciu JSON v rampách - Marshmallow.

V repozitári je tu súbor Readme.md s podrobným popisom štruktúry a pokynmi na spustenie projektu.

API webovej časti je celkom jednoduché, pozostáva zo 6 ramp:

  • /ping - na kontrolu dostupnosti;
  • rampy na registráciu, autorizáciu, deautorizáciu a získavanie autorizovaného užívateľa;
  • rampa na odoslanie emailu, ktorá dáva úlohu do fronty Celery.

Celery časť je ešte jednoduchšia, tam je len jedna úloha send_mail_task.

V priečinku /conf sú tam dve podpriečinky:

  • docker s dvoma Docker súbormi (base.dockerfile na zostavenie málo sa meniacich základných obrazov a Dockerfile na hlavné zostavy);
  • .env_files - so súbormi s premennými prostredia pre rôzne prostredia.

V kore projektu sa nachádzajú štyri súbory docker-compose:

  • docker-compose.local.db.yml na vytvorenie lokálnej DB pre vývoj;
  • docker-compose.local.workers.yml na lokálne vytvorenie pracovníka, DB, Redis a RabbitMQ;
  • docker-compose.test.yml na spustenie testov počas nasadzovania;
  • docker-compose.yml na nasadenie.

A posledná zaujímavá zložka - .ci-cd. V nej sa nachádzajú shell skripty na nasadenie:

  • deploy.sh - spustenie migrácie a nasadenia. Spúšťa sa na serveri po zostavení a spustení testov v Github Actions;
  • rollback.sh - vrátenie kontajnerov na predchádzajúcu verziu zostavenia;
  • curl_tg.sh - posielanie oznámení o nasadení do Telegramu.

Frontend na Angular

Repozitár s frontom je oveľa jednoduchší ako back-end. Front pozostáva z troch stránok:

  • Hlavná stránka s formulárom na odoslanie emailu a tlačidlom pre odhlásenie.
  • Prihlasovacia stránka.
  • Registračná stránka.

Hlavná stránka vyzerá asketicky:

CI/CD v Github Actions pre projekt na Flask+Angular
V kore je uložené dva súbory Dockerfile a docker-compose.yml, ako aj známa nám zložka .ci-cd s o niečo menším množstvom skriptov ako v back-endovom repozitári (skripty na spustenie testov boli odstránené).

Zakladáme projekt v Plesk

Začneme nastavením Plesk a vytvorením predplatného pre našu stránku.

Inštalácia rozšírení

V Plesk budeme potrebovať štyri rozšírenia:

  • Docker na správu a vizuálne zobrazenie stavu kontajnerov v administrácii Plesk;
  • Git na nastavenie kroku nasadenia na serveri;
  • Let's Encrypt na generovanie (a automatické predlžovanie) bezplatných TLS certifikátov;
  • Firewall na nastavenie filtrovania prichádzajúceho trafficu.

Môžeme ich nainštalovať cez administráciu Plesk v sekcii Rozšírenia:

CI/CD v Github Actions pre projekt na Flask+Angular
Detailné nastavenie rozšírení nebudeme rozoberať, pre naše demo účely budú vyhovovať predvolené nastavenia.

Vytvorenie predplatného a stránky

Ďalej potrebujeme vytvoriť predplatné pre našu stránku helloworld.ru a pridať tam subdoménu dev.helloworld.ru.

  1. Vytvárame predplatné pre doménu helloworld.ru a uvádzame prihlasovacie údaje pre systémového používateľa:

    CI/CD v Github Actions pre projekt na Flask+Angular
    Dole na stránke zaškrtneme Secure the domain with Let’s Encrypt, ak chceme nastaviť HTTPS pre stránku:

    CI/CD v Github Actions pre projekt na Flask+Angular

  2. Potom v tejto predplatnej vytvoríme subdoménu dev.helloworld.ru (pre ktorú je tiež možné vydávať bezplatný TLS certifikát):

    CI/CD v Github Actions pre projekt na Flask+Angular

Inštalácia serverových komponentov

Máme server s OS Debian Stretch 9.12 a nainštalovanou riadiacou panelou Plesk Obsidian 18.0.27.

Musíme nainštalovať a nastaviť pre náš projekt:

  • PostgreSQL (v našom prípade bude jeden server s dvoma databázami pre dev- a prod-prostredie).
  • RabbitMQ (rovnaké, jeden instance s rôznymi vhosts pre prostredia).
  • Dve inštancie Redis (pre dev- a prod-prostredie).
  • Docker Registry (na lokálne uchovávanie zostavených Docker obrazov).
  • UI rozhranie pre Docker registry.

PostgreSQL

S Plesk sa už dodáva databáza PostgreSQL, ale nie najnovšej verzie (v čase písania článku Plesk Obsidian podporoval Postgres verzií 8.4–10.8). My však chceme pre svoju aplikáciu najnovšiu verziu (12.3 v čase písania článku), preto ju nainštalujeme ručne.

Podrobných návodov na inštaláciu Postgres na Debian je na internete množstvo (príklad), preto ich podrobne opisovať nebudem, len uvediem prí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

Keďže PostgreSQL má pomerne priemerné predvolené nastavenia, je nutné upraviť konfiguráciu. Pri tom nám pomôže , ktorá názorne ukazuje, koľko človek ušetrí alebo stratí presťahovaním z Lozan, povedzme, do Ekublanu (predmestie, kde sa nachádza EPFL).: je potrebné zadať parametre svojho servera a nahradiť nastavenia v súbore /etc/postgresql/12/main/postgresql.confnavrhnutými. Je potrebné poznamenať, že takéto kalkulačky nie sú zázračná guľka a treba vyladiť databázu presnejšie, v závislosti od vášho hardvéru, aplikácie a zložitosti dopytov. Avšak na začiatok je to dostatočné.

Okrem navrhnutých nastavení kalkulačkou zmeníme v postgresql.confpredvolený port 5432 na iný (v našom prípade — 53983).

Po zmene konfiguračného súboru reštartujeme postgresql-server príkazom:

service postgresql restart

Nainštalovali sme a nastavili PostgreSQL. Teraz vytvoríme databázu, používateľov pre dev- a prod-prostredia a pridelíme používateľom práva na správu databázy:

$ 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

Prejdeme k inštalácii RabbitMQ — sprostredkovateľa správ pre Celery. Inštalácia na Debiane je celkom jednoduchá:

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 inštalácii musíme vytvoriť vhosts, používateľov a pridelíme potrebné 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 ".*" ".*" ".*"

Kľuč-hodnota

Teraz nainštalujeme a nastavíme poslednú zložku pre našu aplikáciu — Redis. Bude sa používať ako backend na ukladanie výsledkov úloh Celery.

Spustíme dva Docker kontajnery s Redis pre dev- a prod-prostredia pomocou rozšírenia Docker pre Plesk.

  1. Prihlásime sa do Plesku, prejdeme na záložku Rozšírenia, vyhľadáme rozšírenie Docker a nainštalujeme ho (potrebujeme bezplatnú verziu):

    CI/CD v Github Actions pre projekt na Flask+Angular

  2. Prejdeme na nainštalované rozšírenie a vyhľadáme obraz redis bitnami a nainštalujeme poslednú verziu:

    CI/CD v Github Actions pre projekt na Flask+Angular

  3. Otvoríme stiahnutý kontajner a upravíme konfiguráciu: nastavíme port, maximálnu alokovanú veľkosť RAM, heslo v premenných prostredia a pripojíme zväzok:

    CI/CD v Github Actions pre projekt na Flask+Angular

  4. Splníme kroky 2-3 pre prod-kontajner, v nastaveniach iba zmeníme parametre: port, heslo, veľkosť RAM a cestu k priečinku zväzku na serveri:

    CI/CD v Github Actions pre projekt na Flask+Angular

Docker Registry

Okrem základných služieb by nebolo zlé mať na serveri vlastný repozitár Docker-obrazov. Našťastie je miesto na serveroch teraz dostatočne lacné (určite lacnejšie ako predplatné na DockerHub) a proces inštalácie súkromného repozitára je veľmi jednoduchý.

Chceme mať nainštalované:

Na to:

  1. V Plesku vytvoríme dve subdomény v našej predplatbe: docker.helloworld.sk a docker-ui.helloworld.sk a nastavíme pre ne certifikáty Let’s Encrypt.
  2. Do priečinka subdomény docker.helloworld.sk pridáme súbor docker-compose.yml s takým obsahom:
    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. Pod SSH vygenerujeme súbor .htpasswd pre základnú autorizáciu v Docker-repozitári:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Zostavíme a spustíme kontajnery:
    docker-compose up -d
  5. A potrebujeme presmerovať Nginx na naše kontajnery. To je možné urobiť cez Plesk.

Nasledujúce kroky by sa mali vykonať pre subdomény docker.helloworld.sk a docker-ui.helloworld.sk:

V sekcii Dev Tools našej stránky prejdeme do Docker Proxy Pravidlá:

CI/CD v Github Actions pre projekt na Flask+Angular
A pridáme pravidlo na proxyovanie prichádzajúcej dopravy do nášho kontajnera:

CI/CD v Github Actions pre projekt na Flask+Angular

  1. Skontrolujeme, či sa môžeme prihlásiť do nášho kontajnera z lokálneho zariadenia:
    $ docker login docker.helloworld.sk -u hw_docker_admin -p hw_docker_password
    WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    Login Succeeded
  2. Rovnako skontrolujeme funkciu subdomény docker-ui.helloworld.sk:

    CI/CD v Github Actions pre projekt na Flask+Angular
    Pri kliknutí na Browse repositories prehliadač otvorí okno na autentifikáciu, do ktorého bude potrebné zadať meno a heslo do repozitára. Potom nás presmeruje na stránku so zoznamom repozitárov (táto stránka bude zatiaľ prázdna):

    CI/CD v Github Actions pre projekt na Flask+Angular

Otvárame porty v Plesk Firewall

Po inštalácii a nastavení komponentov musíme otvoriť porty, aby boli komponenty dostupné z Docker kontajnerov a vonkajšej siete.

Pozrime sa, ako to urobiť na príklade rozšírenia Firewall, ktoré sme predtým nainštalovali pre Plesk.

  1. Prechádzame do Nástroje & Nastavenia > Nastavenia > Firewall:
    CI/CD v Github Actions pre projekt na Flask+Angular
  2. Prechádzame do Upraviť pravidlá Plesk Firewall > Pridať vlastné pravidlo a otvárame nasledujúce TCP porty pre podsúbor Docker (172.0.0.0/8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD v Github Actions pre projekt na Flask+Angular

  3. Takisto pridáme pravidlo, ktoré otvorí vonkajšiemu svetu porty PostgreSQL a správcovskej paneli RabbitMQ:

    CI/CD v Github Actions pre projekt na Flask+Angular

  4. Pripravíme pravidlá pomocou tlačidla Apply Changes:

    CI/CD v Github Actions pre projekt na Flask+Angular

Nastavenie CI/CD v Github Actions

Prejdime k tej najzaujímavejšej časti — nastaveniu pipeline kontinuálnej integrácie a dodávky nášho projektu na server.

Táto pipeline bude pozostávať z dvoch častí:

  • súdržba obrazu a spustenie testov (pre backend) — na strane Github;
  • spustenie migrácií (pre backend) a nasadenie kontajnerov — na serveri.

Nasadenie v Plesk

Najprv sa pozrieme na druhý bod (pretože ten závisí od prvého).

Proces nasadenia budeme nastavovať pomocou rozšírenia Git pre Plesk.

Pozrime sa na príklad s Prod prostredím pre Backend repozitár.

  1. Prejdeme do predplatného našich webových stránok Helloworld a prejdeme do pododdielu Git:

    CI/CD v Github Actions pre projekt na Flask+Angular

  2. Vložíme do poľa „Remote Git repository“ odkaz na náš Github repozitár a zmeníme predvolený priečinok httpdocs na iný (napríklad, /httpdocs/hw_back):

    CI/CD v Github Actions pre projekt na Flask+Angular

  3. Skopírujeme SSH Public key z predchádzajúceho kroku a pridáme ho v nastaveniach Github.
  4. Klikneme na OK na obrazovke v bode 2, po čom nás presmeruje na stránku repozitára v Plesk. Teraz musíme nastaviť aktualizáciu repozitára pri komitách do vetvy master. Na to prejdeme do Nastavenia repozitára a uložíme hodnotu Webhook URL (bude nám potrebná neskôr pri nastavovaní Github Actions):

    CI/CD v Github Actions pre projekt na Flask+Angular

  5. V poli Actions na obrazovke z predchádzajúceho bodu zadáme skript na spustenie nasadenia:
    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 priečinku prod backend repozitára na serveri;
    {ENV} — prostredie (dev/prod), v našom prípade produkcia;
    {DOCKER_REGISTRY_HOST} — hostiteľ nášho docker repozitára
    {TG_BOT_TOKEN} — token Telegram bota;
    {TG_CHAT_ID} — ID chatu/kanála na zasielanie upozornení.

    Prí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
  6. Pridáme používateľa z našej predplatenej služby do skupiny Docker (aby mohol spravovať kontajnery):
    sudo usermod -aG docker helloworld_admin

Dev prostredie pre backend repozitár a frontend sa nastavujú podobne.

Pipeline nasadenia v Github Actions

Prechádzame k nastaveniu prvej časti nášho CI/CD pipeline v Github Actions.

Backend plánovali na Linuxe. Backend interaguje s DB, načítava potrebný zoznam privilegií a potom, v závislosti od toho, aké privilegované má autorizovaný používateľ, poskytuje prístup na podpisovanie finančných dokumentov a ich odosielanie na vykonanie, alebo generovanie nejakého reportu.

Pipeline je opísaný v súbore deploy.yml.

Ale predtým, ako ho rozoberieme, vyplníme v Github potrebné Secret premenné. Na to prejdeme do Nastavenia -> Tajomstvá:

  • DOCKER_REGISTRY — hostiteľ nášho Docker repozitára (docker.helloworld.ru);
  • DOCKER_LOGIN — prihlásenie do Docker repozitára;
  • DOCKER_PASSWORD — heslo k nemu;
  • DEPLOY_HOST — host, na ktorom je dostupná administrácia Plesk (príklad: helloworld.ru:8443 alebo 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN — token pre nasadenie do prod repozitára na serveri (dostali sme ho v Rozvoji v Plesk p. 4);
  • DEPLOY_BACK_DEV_TOKEN — token pre nasadenie do dev repozitára na serveri.

Proces nasadenia je jednoduchý a pozostáva z troch hlavných krokov:

  • kompilácia a publikovanie obrazu v našom repozitári;
  • spustenie testov v kontajneri na základe čerstvo zostaveného obrazu;
  • nasadenie do požadovaného prostredia v závislosti od vetvy (dev/master).

Frontend

Súbor deploy.yml pre front-end repozitár sa málo odlišuje od back-endového. Chýba krok so spustením testov a menia sa názvy tokenov pre nasadenie. Tajomstvá pre front-end repozitár je, mimochodom, potrebné vyplniť osobitne.

Nastavenie webu

Proxyovanie prevádzky cez Nginx

Takže sme na konci. Zostáva len nastaviť proxyovanie prichádzajúcej a odchádzajúcej prevádzky v našom kontajneri cez Nginx. Tento proces sme už preskúmali v bode 5 nastavenia Docker Registry. To isté je potrebné zopakovať pre back-end a front-end časti v dev a prod prostrediach.

Predložím snímky nastavení.

Backend plánovali na Linuxe. Backend interaguje s DB, načítava potrebný zoznam privilegií a potom, v závislosti od toho, aké privilegované má autorizovaný používateľ, poskytuje prístup na podpisovanie finančných dokumentov a ich odosielanie na vykonanie, alebo generovanie nejakého reportu.

CI/CD v Github Actions pre projekt na Flask+Angular

Frontend

CI/CD v Github Actions pre projekt na Flask+Angular
Dôležité upresnenie. Do front-end kontajnera budú proxyované všetky URL, okrem tých, ktoré začínajú na /api/ — tie budú proxyované do back-end kontajnera (preto v back-end kontajneri musia všetky spracovateľské funkcie začínať s /api/).

Zhrnutie

Teraz by mal byť náš web prístupný na adresách helloworld.ru a dev.helloworld.ru (prod a dev prostredie, resp.).

Celkovo sme sa naučili, ako pripraviť jednoduchú aplikáciu na Flask a Angular a nastaviť pipeline v Github Actions pre jej nasadenie na serveri riadenom Pleskom.

Zopakuajem odkazy na repozitáre s kódom: backend, frontend.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster