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

CI/CD v Github Actions za projekt na Flask+Angular
V tem članku bom delil svojo izkušnjo nastavitve CI/CD z uporabo nadzorne plošče Plesk in Github Actions. Danes se bomo naučili, kako postaviti preprost projekt z nepremišljenim imenom 'Helloworld'. Napisan je v Python okviru Flask, z delavci na Celery in frontendov z Angular 8.

Povezave do repozitorijev: backend, frontend.

V prvem delu članka bomo pregledali naš projekt in njegove dele. V drugem se bomo osredotočili na nastavitev Pleska ter namestitev potrebnih razširitev in komponent (Baza podatkov, RabbitMQ, Redis, Docker itd.).

V tretjem delu se bomo končno ukvarjali z nastavitvijo pipeline-a za postavitev našega projekta na strežnik v dev- in prod-okolje. Nato bomo zagnali spletno stran na strežniku.

In ja, pozabil sem se predstaviti. Ime mi je Oleg Borzov, sem fullstack razvijalec v ekipi CRM za upravljavce hipotekarnih posojil v Domklik.

Pregled projekta

Najprej si poglejmo dva repozitorija projekta — backend in frontend — in preletimo kodo.

Backend del: Flask+Celery

Za backend sem izbral precej priljubljeno kombinacijo med Python razvijalci: okvir Flask (za API) in Celery (za obdelavo nalog). Kot ORM se uporablja SQLAlchemy. Za migracije se uporablja Alembic. Za validacijo JSON v ročajih — Marshmallow.

V repozitoriji obstaja datoteka Readme.md s podrobnim opisom strukture in navodili za zagon projekta.

API spletnega dela je dovolj preprost, sestoji iz 6 ročajev:

  • /ping — za preverjanje dostopnosti;
  • ročaji za registracijo, avtentifikacijo, deavtentifikacijo in pridobitev avtentificiranega uporabnika;
  • ročaj za pošiljanje emailov, ki dodaja nalogo v čakalno vrsto Celery.

Del Celery je še bolj preprost, tam je le ena naloga send_mail_task.

V mapi /conf so dve podmapi:

  • docker s dvema Docker datotekama (base.dockerfile za gradnjo redko spreminjajoče se osnovne slike in Dockerfile za glavne gradnje);
  • .env_files — z datotekami z okolijskimi spremenljivkami za različna okolja.

V korenu projekta so štiri datoteke docker-compose:

  • docker-compose.local.db.yml za dvig lokalne baze podatkov za razvijanje;
  • docker-compose.local.workers.yml za lokalni dvig delavca, baze, Redis-a in RabbitMQ;
  • docker-compose.test.yml za izvajanje testov pri razporejanju;
  • docker-compose.yml za postavitev.

In zadnja zanimiva mapa je — .ci-cd. V njej so shell skripti za postavitev:

  • deploy.sh — zagon migracij in postavitve. Zažene se na strežniku po končanju gradnje in izvajanju testov v Github Actions;
  • rollback.sh — povratak kontejnerjev na prejšnjo različico gradnje;
  • curl_tg.sh — pošiljanje obvestil o postavitvi v Telegram.

Frontend na Angular

Repozitorij z frontom je precej lažji od backenda. Fronta sestavlja tri strani:

  • Glavna stran s obrazcem za pošiljanje e-pošte in gumbom za izhod.
  • Stran za prijavo.
  • Stran za registracijo.

Glavna stran izgleda skromno:

CI/CD v Github Actions za projekt na Flask+Angular
V korenu ležita dva datoteka Dockerfile in docker-compose.yml, prav tako pa znana mapa .ci-cd s nekoliko manj skripti kot v repozitoriju backend (odstranjeni so skripti za zagon testov).

Ustanovitev projekta v Plesk

Začnimo s konfiguracijo Pleska in ustvarjanjem naročnine za našo spletno stran.

Namestitev razširitev

V Plesku potrebujemo štiri razširitve:

  • Docker za upravljanje in vizualno prikazovanje stanja kontejnerjev v administraciji Plesk;
  • Git za nastavitev koraka prenosa na strežniku;
  • Let's Encrypt za generiranje (in samodejno podaljšanje) brezplačnih TLS-certifikatov;
  • Firewal za nastavitev filtriranja prihajajočega prometa.

Namestimo jih lahko preko administracije Plesk v razdelku Razširitve:

CI/CD v Github Actions za projekt na Flask+Angular
Podrobno nastavitev razširitev ne bomo obravnavali, za naše demo-namen bomo uporabili privzete nastavitve.

Ustvarjanje naročnine in strani

Nato moramo ustvariti naročnino za našo spletno stran helloworld.ru in dodati poddomeno dev.helloworld.ru.

  1. Ustvarimo naročnino za domeno helloworld.ru in navedemo uporabniško ime-geslo za sistemskega uporabnika:

    CI/CD v Github Actions za projekt na Flask+Angular
    Na dnu strani označite Secure the domain with Let’s Encrypt, če želimo nastaviti HTTPS za spletno stran:

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

  2. Nato v tej naročnini ustvarimo poddomeno dev.helloworld.ru (za katero je prav tako možno izdati brezplačen TLS-certifikat):

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

Namestitev strežniških komponent

Imamo strežnik z OS Debian Stretch 9.12 in nameščenim upravljanjem Plesk Obsidian 18.0.27.

Moramo namestiti in konfigurirati za naš projekt:

  • PostgreSQL (v našem primeru bo en strežnik z dvema DB za dev- in prod-okolje).
  • RabbitMQ (isto, en instanca z različnimi vhosts za okolja).
  • Dve instanci Redis (za dev- in prod-okolje).
  • Docker Registry (za lokalno shranjevanje zbranih Docker-slik).
  • Učinkovinski vmesnik za Docker registry.

PostgreSQL

V kompletu s Pleskom že pride SSQL PostgreSQL, vendar ne najnovejše različice (ob času pisanja članka Plesk Obsidian je podpiral Postgres različic 8.4–10.8). Mi pa želimo za svojo aplikacijo najnovejšo različico (12.3 ob času pisanja članka), zato jo bomo namestili ročno.

Podrobnih navodil za namestitev Postgresa na Debianu je na spletu ogromno (primer), zato jih ne bom podrobno opisoval, le navedel bom ukaze:

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

Обратите внимание, что в PostgreSQL настройки по умолчанию достаточно средние, поэтому необходимо отрегулировать конфигурацию. В этом нам поможет калькулятор: необходимо ввести параметры вашего сервера и заменить настройки в файле /etc/postgresql/12/main/postgresql.confна предложенные. Тут следует уточнить, что такие калькуляторы — не универсальное решение, и базу нужно настраивать более детально, исходя из вашего оборудования, приложений и сложности запросов. Но для начала этого вполне достаточно.

Кроме того, что предлагает калькулятор, также измените в postgresql.confпорт 5432, заданный по умолчанию, на другой (в нашем примере — 53983).

После изменения конфигурационного файла перезагрузите postgresql-server командой:

service postgresql restart

Мы установили и настроили PostgreSQL. Теперь создадим БД, пользователей для dev- и prod-сред, и предоставим им права на управление БД:

$ 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

Перейдем к установке RabbitMQ — брокера сообщений для Celery. Установка на Debian осуществляется довольно просто:

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

После установки нам нужно создать vhosts, пользователей и предоставить нужные права:

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

Теперь установим и настроим последний компонент для нашего приложения — Redis. Он будет использоваться в качестве бэкенда для хранения результатов задач Celery.

Мы поднимем два Docker-контейнера с Redis для dev- и prod-сред с помощью расширения Docker для Plesk.

  1. Vstopimo v Plesk, pojdimo na razdelek Razširitve, poiščimo razširitev Docker in jo namestimo (potrebna nam je brezplačna različica):

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

  2. Pojdimo na nameščeno razširitev, poiščimo sliko redis bitnami in namestimo najnovejšo različico:

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

  3. Vstopimo v preneseni posod in prilagodimo konfiguracijo: določimo vrata, največjo dodeljeno velikost RAM-a, geslo v spremenljivkah okolja in montiramo volumen:

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

  4. Izvedemo korake 2-3 za prod-posodo, v nastavitvah samo spremenimo parametre: vrata, geslo, velikost RAM-a in pot do mape volume na strežniku:

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

Docker Registry

Poleg osnovnih storitev bi bilo dobro namestiti na strežnik lastno skladišče Docker slik. Na srečo je prostor na strežnikih zdaj precej poceni (resnično ceneje kot naročnina na DockerHub), pa tudi postopek namestitve zasebnega skladišča je zelo enostaven.

Želimo, da imamo nameščeno:

Zato:

  1. Ustvarili bomo v Plesku dve poddomeni v naši naročnini: docker.helloworld.ru in docker-ui.helloworld.ru, in konfigurirali bomo certifikate Let’s Encrypt zanje.
  2. V mapo poddomene docker.helloworld.ru dodamo datoteko docker-compose.yml с таким содержимым:
    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. Preko SSH bomo ustvarili datoteko .htpasswd za osnovno avtentikacijo v Docker skladišču:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Sestavili bomo in zagnali posode:
    docker-compose up -d
  5. In treba je preusmeriti Nginx na naše posode. To lahko storimo preko Pleska.

Naslednje korake je treba izvesti za poddomene docker.helloworld.ru in docker-ui.helloworld.ru:

V razdelku Razvijalna orodja naše strani gremo v Docker Proxy Rules:

CI/CD v Github Actions za projekt na Flask+Angular
In dodamo pravilo za posredovanje vhodnega prometa v našo posodo:

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

  1. Preverimo, ali se lahko prijavimo v našo posodo z lokalnega računalnika:
    $ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password
    WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    Prijava uspešna
  2. Prav tako bomo preverili delovanje poddomene docker-ui.helloworld.ru:

    CI/CD v Github Actions za projekt na Flask+Angular
    Ko boste kliknili na Browse repositories, bo brskalnik odprl okno za prijavo, v katerega boste morali vnesti uporabniško ime in geslo za repozitorij. Nato vas bo preusmerilo na stran s seznamom repozitorijev (zaenkrat bo ta prazna):

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

Odprite porte v Plesk Firewall

Po namestitvi in nastavitvi komponent moramo odpreti porte, da bodo komponente dostopne iz Docker kontejnerjev in zunanje mreže.

Poglejmo, kako to storiti, na primeru razširitve Firewall za Plesk, ki smo jo namestili prej.

  1. Pojdite na Orodja in nastavitve > Nastavitve > Firewall:
    CI/CD v Github Actions za projekt na Flask+Angular
  2. Pojdite na Spremenite pravila požarnega zidu Plesk > Dodajte po meri pravilo in odprite naslednje TCP porte za podomrežje Docker (172.0.0.0/8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

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

  3. Prav tako dodajmo pravilo, ki bo odprlo porte PostgreSQL in upravljalske plošče RabbitMQ za zunanji svet:

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

  4. Pravila uporabimo s klikom na gumb Uporabi spremembe:

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

Nastavitev CI/CD v Github Actions

Začnimo s najbolj zanimivim delom — nastavitvijo pipeline za neprekinjeno integracijo in dostavo našega projekta na strežnik.

Ta pipeline bo sestavljen iz dveh delov:

  • zbiranje slike in izvajanje testov (za backend) — na strani Githuba;
  • zagon migracij (za backend) in deploy kontejnerjev — na strežniku.

Deploy v Plesk

Najprej se osredotočimo na drugi del (saj je od njega odvisen prvi).

Postopek deploya bomo nastavili z uporabo razširitve Git za Plesk.

Oglejmo si primer s produkcijskim okoljem za Backend repozitorij.

  1. Prijavite se v naročnino našega spletnega mesta Helloworld in pojdite v pododdelek Git:

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

  2. V polje 'Remote Git repository' prilepite povezavo na naš Github repozitorij in spremenite privzeto mapo httpdocs na drugo (na primer, /httpdocs/hw_back):

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

  3. Kopirajte javni ključ SSH z prejšnjega koraka in dodajamo ga prilepite v nastavitvah Githuba.
  4. Kliknite OK na zaslonu v točki 2, nato pa vas bo preusmerilo na stran repozitorija v Plesku. Zdaj moramo nastaviti posodabljanje repozitorija ob commitih v osnovno vejo. Zato pojdite na Nastavitve repozitorija in shranite vrednost Webhook URL (bomo ga potrebovali kasneje pri nastavitvi Github Actions):

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

  5. V polju Dejanja na zaslonu iz prejšnje točke vnesite skripto za zagon deploya:
    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} — pot do mape prod backend repozitorija na strežniku;
    {ENV} — okolje (dev/prod), v našem primeru prod;
    {DOCKER_REGISTRY_HOST} — gostitelj našega docker repozitorija
    {TG_BOT_TOKEN} — žeton Telegram bota;
    {TG_CHAT_ID} — ID klepeta/kanala za pošiljanje obvestil.

    Primer 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
  6. Dodajamo korisnika iz naše pretplate u Docker grupu (kako bi mogao upravljati kontejnerima):
    sudo usermod -aG docker helloworld_admin

Dev-okruženje za backend repozitorij i frontend se postavlja na sličan način.

Pipeline za deploy u Github Actions

Prelazimo na podešavanje prvog dela našeg CI/CD pipeline-a u Github Actions.

Backend

Pipeline se opisuje u datoteci deploy.yml.

Ali pre nego što ga analiziramo, popunićemo potrebne tajne varijable u Github-u. Za to prelazimo u Settings -> Secrets:

  • DOCKER_REGISTRY — host našeg Docker repozitorijuma (docker.helloworld.ru);
  • DOCKER_LOGIN — korisničko ime za Docker repozitorijum;
  • DOCKER_PASSWORD — lozinka za njega;
  • DEPLOY_HOST — host na kojem je dostupna admin Plesk (primer: helloworld.ru:8443 ili 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN — token za deploy u prod-repozitorijum na serveru (dobijen u Razvijanje u Plesk tačka 4);
  • DEPLOY_BACK_DEV_TOKEN — token za deploy u dev-repozitorijum na serveru.

Proces deploy-a je jednostavan i sastoji se od tri osnovna koraka:

  • izgradnja i objavljivanje slike u našem repozitorijumu;
  • pokretanje testova u kontejneru zasnovanom na sveže izgrađenoj slici;
  • deploy u odgovarajuće okruženje u zavisnosti od grane (dev/master).

Frontend

Datoteka deploy.yml za front-repozitorij malo se razlikuje od back repozitorija. Nedostaje korak sa pokretanjem testova i menjaju se imena tokena za deploy. Tajne za front-repozitorij, inače, treba popuniti odvojeno.

Podešavanje sajta

Proksiranje saobraćaja putem Nginx-a

Pa, došli smo do kraja. Ostalo je samo da postavimo proksiranje dolaznog i odlaznog saobraćaja u naš kontejner preko Nginx-a. Ovaj proces smo već razmotrili u tački 5 podešavanja Docker Registry. Isto to treba ponoviti za back i front deo u dev i prod okruženjima.

Prikazat ću snimke podešavanja.

Backend

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

Frontend

CI/CD v Github Actions za projekt na Flask+Angular
Važno pojašnjenje. U frontend kontejner će se proksirati svi URL-ovi, osim onih koji počinju sa /api/ — oni će se proksirati u back kontejner (zato u back kontejneru svi obrtnici moraju početi sa /api/).

Zaključki

Sada bi naš sajt trebao biti dostupan na adresama helloworld.ru i dev.helloworld.ru (prod i dev okruženje odgovarajuće).

Sve u svemu, saznali smo kako da pripremimo jednostavnu aplikaciju na Flask-u i Angular-u i kako da postavimo pipeline u Github Actions za njen isporuku na server pod upravom Plesk.

Ponovo ću podeliti linkove na repozitorijume sa kodom: backend, frontend.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster