CI/CD a Github Actions-ben Flask+Angular projekt számára

CI/CD a Github Actions-ben Flask+Angular projekt számára
Ebben a cikkben megosztom tapasztalataimat a CI/CD beállításáról a Plesk vezérlőpult és a Github Actions segítségével. Ma egy egyszerű, "Helloworld" nevű projekt telepítését fogjuk megtanulni. Ez a Flask Python keretrendszerben készült, Celery munkásokkal és Angular 8 front-enddel.

A repository-k linkjei: háttér, frontend.

A cikk első részében megnézzük a projektünket és annak részeit. A második részben pedig azt tárgyaljuk, hogyan állítsuk be a Plesk-t és telepítsük a szükséges kiterjesztéseket és komponenseket (adatbázis, RabbitMQ, Redis, Docker stb.).

A harmadik részben végül arra is rátérünk, hogyan állítsuk be a pipeline-t a projektünk szerverre történő telepítéséhez dev- és prod-környezetbe. Aztán elindítjuk a weboldalt a szerveren.

És igen, elfelejtettem bemutatkozni. Oleg Borzov vagyok, fullstack fejlesztő a lakáshitel menedzserek CRM csapatában a Domkliknél.

A projekt áttekintése

Először nézzük meg a projekt két repository-ját — a háttér és a frontend — és fussunk át a kódon.

Háttér rész: Flask+Celery

A háttérhez egy a Python fejlesztők körében elég népszerű összeállítást választottam: a Flask keretrendszert (az API-hoz) és a Celery-t (a feladatok sorba állításához). Az ORM SQLAlchemy-t használ. Az adatbázis-migrációkhoz Alembic-et alkalmazunk. A JSON validálására a Marshmallow-t.

A tárhelyen van egy Readme.md fájl részletes leírással a struktúráról és a projekt indítási utasításairól.

API web rész kifejezetten egyszerű, 6 végpontból áll:

  • /ping — a rendelkezésre állás ellenőrzésére;
  • végpontok a regisztráláshoz, bejelentkezéshez, kijelentkezéshez és a bejelentkezett felhasználó lekéréséhez;
  • végpont, amely emailt küld, és a feladatot a Celery sorba helyezi.

Celery rész még egyszerűbb, itt mindössze egy feladat van send_mail_task.

A mappában /conf két alkönyvtár található:

  • docker két Docker fájllal (base.dockerfile ritkán változó alapképek összeállításához és Dockerfile a fő összeállításokhoz);
  • .env_files — környezeti változókkal ellátott fájlok a különböző környezetekhez.

A projekt gyökerében négy docker-compose fájl található:

  • docker-compose.local.db.yml a helyi adatbázis felemeléséhez fejlesztéshez;
  • docker-compose.local.workers.yml a helyi munkás, adatbázis, Redis és RabbitMQ felemeléséhez;
  • docker-compose.test.yml a tesztek futtatásához a telepítés során;
  • docker-compose.yml a telepítéshez.

És az utolsó érdekes mappa — .ci-cd. Ebben találhatók a telepítési shell-script-ek:

  • deploy.sh — migrációk és telepítések indítása. Ez a szerveren elindul a Github Actions-ban a tesztek futtatása után;
  • rollback.sh — a konténerek visszaállítása a korábbi verzióra;
  • curl_tg.sh — értesítések küldése a telepítésről a Telegramon.

Angular front-end

Repository with the front is significantly simpler than the back-end. The front consists of three pages:

  • Home page with a form to submit an email and a logout button.
  • Login page.
  • Registration page.

The home page looks minimalistic:

CI/CD a Github Actions-ben Flask+Angular projekt számára
There are two files in the root Dockerfile és docker-compose.yml, as well as a familiar folder .ci-cd with slightly fewer scripts than in the back-end repository (test launch scripts have been removed).

Starting a project in Plesk

Let’s start with configuring Plesk and creating a subscription for our site.

Installing extensions

In Plesk, we will need four extensions:

  • Docker for managing and visually displaying the status of containers in the Plesk admin panel;
  • Konténerizálás for setting the deployment step on the server;
  • Let's Encrypt for generating (and auto-renewing) free TLS certificates;
  • Firewall for filtering incoming traffic.

They can be installed via the Plesk admin panel in the Extensions section:

CI/CD a Github Actions-ben Flask+Angular projekt számára
We will not discuss detailed configuration of the extensions; the default settings will suffice for our demo purposes.

Creating a subscription and a website

Next, we need to create a subscription for our site helloworld.ru and add the subdomain dev.helloworld.ru.

  1. We create a subscription for the domain helloworld.ru and specify a username-password for the system user:

    CI/CD a Github Actions-ben Flask+Angular projekt számára
    At the bottom of the page, check the box Secure the domain with Let’s Encrypt, if we want to set up HTTPS for the site:

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  2. Next, in this subscription, we create the subdomain dev.helloworld.ru (for which a free TLS certificate can also be issued):

    CI/CD a Github Actions-ben Flask+Angular projekt számára

Installing server components

We have a server with OS Debian Stretch 9.12 and the control panel Plesk Obsidian 18.0.27.

We need to install and configure for our project:

  • PostgreSQL (in our case, there will be one server with two databases for dev- and prod-environments).
  • RabbitMQ (the same, one instance with different vhosts for environments).
  • Two instances of Redis (for dev- and prod-environments).
  • Docker Registry (for local storage of built Docker images).
  • UI interface for Docker registry.

PostgreSQL

The PostgreSQL DBMS is already included with Plesk, but not the latest version (at the time of writing this article, Plesk Obsidian supported Postgres versions 8.4–10.8). We want the latest version for our application (12.3 at the time of writing), so we will install it manually.

There are plenty of detailed instructions for installing Postgres on Debian available online (példám), so I won’t describe them in detail, just provide the commands:

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

Figyelembe véve, hogy a PostgreSQL alapértelmezett beállításai meglehetősen közepesek, mindenképpen ki kell igazítani a konfigurációt. Ebben segít nekünk , amely szemlélteti, mennyit takarít meg vagy veszít az ember, ha például Lausanne-ból Écublans-ba (előváros, ahol az EPFL található) költözik.: meg kell adni a saját szerverünk paramétereit és a beállításokat a /etc/postgresql/12/main/postgresql.confjavasoltakra kell cserélni. Érdemes megjegyezni, hogy az ilyen kalkulátorok nem csodafegyverek, és az adatbázist célzottabban kell optimalizálni, figyelembe véve a hardverünket, az alkalmazást és a lekérdezések összetettségét. De indulásnak ez elegendő.

Az ajánlott kalkulátor beállításain kívül a , hogy a tesztadatbázisunk ne akarjon csendesen biztosítékot létrehozni.alapértelmezett 5432-es portot is másikra kell cserélnünk (a mi példánkban — 53983).

A konfigurációs fájl módosítása után újra kell indítani a postgresql-szervert a következő parancs használatával:

service postgresql restart

Telepítettük és beállítottuk a PostgreSQL-t. Most létrehozunk adatbázisokat, felhasználókat a dev- és prod-környezethez, és jogokat adunk a felhasználóknak az adatbázis kezelésére:

$ 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

Térjünk át a RabbitMQ telepítésére — üzenetkezelő a Celery számára. Debianon viszonylag egyszerűen telepíthető:

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

A telepítés után létre kell hoznunk vhosts, felhasználókat, és meg kell adnunk a szükséges jogokat:

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

Most telepítjük és beállítjuk az utolsó komponenst az alkalmazásunk számára — Redis-t. Ez a Celery feladatainak eredményeinek tárolására szolgáló hátsó rendszerként fog működni.

Két Docker-konténert indítunk Redis-szal a dev- és prod-környezetekhez a következő kiterjesztés segítségével Docker a Plesk számára.

  1. Belépünk a Pleskbe, átmegyünk a Kiterjesztések részlegbe, keresünk egy Docker kiterjesztést, és telepítjük (szükségünk van a ingyenes verzióra):

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  2. Átmegyünk a telepített kiterjesztésre, és keresünk egy képet: redis bitnami és telepítjük a legfrissebb verziót:

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  3. Belépünk a letöltött konténerbe, és módosítjuk a konfigurációt: megadjuk a portot, a maximális RAM méretet, a jelszót a környezeti változókban, és hozzáadjuk a kötetet:

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  4. A 2-3. lépéseket végrehajtjuk a prod-konténerre, csak a paramétereket módosítjuk: port, jelszó, RAM méret és a mappa elérési útja a szerveren:

    CI/CD a Github Actions-ben Flask+Angular projekt számára

Docker Registry

A alap szolgáltatások mellett érdemes lenne saját Docker-image tárolót létesíteni a szerveren. Szerencsére a tárhely árak most elég olcsók (biztosan olcsóbb, mint a DockerHub előfizetés), és a privát tároló telepítése is nagyon egyszerű.

Azt szeretnénk, ha a következőket telepítenénk:

Ehhez:

  1. Hozzunk létre a Pleskben két aldomaint az előfizetésünk keretében: docker.helloworld.ru és docker-ui.helloworld.ru, és állítsuk be számukra a Let’s Encrypt tanúsítványokat.
  2. A docker.helloworld.ru aldomain mappájába hozzáadunk egy fájlt: docker-compose.yml a következő tartalommal:
    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. SSH-n keresztül generáljuk a .htpasswd fájlt a Docker-tároló alapú hitelesítéshez:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Összeszereljük és elindítjuk a konténereket:
    docker-compose up -d
  5. Ezen kívül irányítani kell az Nginx-et a konténereinkre. Ezt a Plesk-en keresztül végezhetjük el.

A következő lépéseket végre kell hajtani a docker.helloworld.ru és docker-ui.helloworld.ru aldomainek esetében:

A részben Dev Tools a weboldalunkon belépünk a Docker Proxy Rules:

CI/CD a Github Actions-ben Flask+Angular projekt számára
és hozzáadunk egy szabályt az érkező forgalom irányítására a konténerünk felé:

CI/CD a Github Actions-ben Flask+Angular projekt számára

  1. Ellenőrizzük, hogy be tudunk-e jelentkezni a konténerünkbe a helyi gépről:
    $ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password
    WARNING! A --password CLI használata nem biztonságos. Használja a --password-stdin-t.
    Jelentkezés sikerült
  2. Ellenőrizzük a docker-ui.helloworld.ru aldomain működését is:

    CI/CD a Github Actions-ben Flask+Angular projekt számára
    Ha rákattintunk a Browse repositories lehetőségre, a böngésző megjelenít egy bejelentkező ablakot, ahová be kell írni a repozitórium felhasználónevét és jelszavát. Ezt követően átkerülünk a repozitóriumok listáján található oldalra (ez egyelőre üres lesz):

    CI/CD a Github Actions-ben Flask+Angular projekt számára

Portok megnyitása a Plesk Tűzfalban

A komponensek telepítése és beállítása után nyitnunk kell portokat, hogy a komponensek elérhetők legyenek a Docker konténerekből és a külső hálózatból.

Nézzük meg, hogyan csináljuk ezt a korábban telepített Plesk Tűzfal bővítmény példáján.

  1. Lépjünk a következőre Eszközök & Beállítások > Beállítások > Tűzfal:
    CI/CD a Github Actions-ben Flask+Angular projekt számára
  2. Lépjünk a következőre Plesk Tűzfal Szabályok módosítása > Egyéni szabály hozzáadása és nyissuk meg az alábbi TCP portokat a Docker alhálózat számára (172.0.0.0/8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  3. Ezen kívül adjunk hozzá egy szabályt, amely megnyitja a PostgreSQL és a RabbitMQ kezelőfelület portjait a külső világ számára:

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  4. Alkalmazzuk a szabályokat az Apply Changes gomb segítségével:

    CI/CD a Github Actions-ben Flask+Angular projekt számára

CI/CD beállítása a Github Actions-ban

Vágjunk bele a legérdekesebb részbe — a folyamatos integrációs és szállítási folyamat beállításába a projektünkhöz.

Ez a folyamat két részre oszlik:

  • a kép létrehozása és a tesztek futtatása (a háttérben) — a Github oldalán;
  • a migrációk végrehajtása (a háttérben) és a konténerek telepítése — a szerveren.

Telepítés Plesk-ben

Először nézzük meg a második pontot (mivel az elsőtól függ).

A telepítési folyamatot a Git bővítmény segítségével fogjuk beállítani a Plesk-ben.

Vizsgáljuk meg a Backend repozitórium Prod környezetének példáját.

  1. Lépjünk be a Helloworld webhely előfizetésébe, és navigáljunk a Git szekcióba:

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  2. Az "Remote Git repository" mezőbe beillesztjük a GitHub repozitóriumunk linkjét, és megváltoztatjuk az alapértelmezett mappát httpdocs egy másikra (például, /httpdocs/hw_back):

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  3. Másoljuk át a SSH nyilvános kulcsot az előző lépésből, és hozzáadjuk azt a Github beállításainál.
  4. Nyomjuk meg az OK gombot a 2. pontnál, ezután egyből a Plesk repozitórium oldalára kerülünk. Most be kell állítanunk a repozitórium frissítését a master ágba történő elkötelezésekkor. Ehhez lépjünk a Repozitórium beállításai és mentsük el a következő értéket: Webhook URL (ez szükséges lesz később a Github Actions beállításakor):

    CI/CD a Github Actions-ben Flask+Angular projekt számára

  5. Az előző pont képernyőjén az Actions mezőbe beírjuk a telepítés indításához szükséges scriptet:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    ahol:

    {REPOSITORY_ABSOLUTE_PATH} — a prod backend repozitórium mappája a szerveren;
    {ENV} — környezet (dev/prod), esetünkben prod;
    {DOCKER_REGISTRY_HOST} — a docker repozitóriumunk hostja;
    {TG_BOT_TOKEN} — a Telegram bot tokenje;
    {TG_CHAT_ID} — a chat/csatorna ID a értesítések küldésére.

    Script példa:

    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. Felhasználó hozzáadása a Docker csoporthoz (hogy kezelni tudja a konténereket) a feliratkozásunk alapján:
    sudo usermod -aG docker helloworld_admin

A Dev-környezet a backend-repozitórium és a frontend esetében hasonlóan van beállítva.

Pipeline telepítése a Github Actions-ban

Térjünk át a CI/CD pipeline első részének beállítására a Github Actions-ban.

Backend

A pipeline leírása a deploy.yml fájlban található..

De a részletezés előtt töltsük ki a szükséges Secret változókat a Github-ban. Ehhez navigáljunk a Beállítások -> Titkok között.:

  • DOCKER_REGISTRY — a Docker-repozitóriumunk hosztja (docker.helloworld.ru);
  • DOCKER_LOGIN — a Docker-repozitórium hozzáférési neve;
  • DOCKER_PASSWORD — jelszava;
  • DEPLOY_HOST — a Plesk adminisztrációs felületének hosztja (példa: helloworld.ru:8443 vagy 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN — a prod-repozitóriumba való telepítéshez szükséges token (ezt a Plesk telepítési útmutató 4. pontjában kaptuk);
  • DEPLOY_BACK_DEV_TOKEN — a dev-repozitóriumba való telepítéshez szükséges token.

A telepítési folyamat egyszerű és három fő lépésből áll:

  • a képfájl összeszerelése és publikálása a repo-nkban;
  • tesztek futtatása a konténerben az újonnan összeszerelt képfájl alapján;
  • telepítés a szükséges környezetbe a választott ágtól függően (dev/master).

Frontend

A deploy.yml fájl a frontend repónál nem sokban különbözik a backend-től. Ebben hiányzik a tesztfutás lépés és megváltoznak a telepítési tokenek nevei. A frontend repó titkait külön kell kitölteni.

Webhely beállítása

A forgalom átirányítása az Nginx-en keresztül

Nos, most a végére értünk. Már csak az szükséges, hogy beállítsuk a bejövő és kimenő forgalom átirányítását a konténerünkbe Nginx-en keresztül. Ezt a folyamatot már megtanultuk a Docker Registry 5. pontjában. Ugyanezt meg kell ismételni a backend és frontend esetében a dev és prod környezetekben.

Megmutatom a beállítások képernyőképeit.

Backend

CI/CD a Github Actions-ben Flask+Angular projekt számára

Frontend

CI/CD a Github Actions-ben Flask+Angular projekt számára
Fontos pontosítás. A frontend konténerbe minden URL átirányításra kerül, kivéve azokat, amelyek a következővel kezdődnek: /api/ — ezek átirányításra kerülnek a backend konténerbe (ezért a backend konténerben minden handlernek a következővel kell kezdődnie: /api/).

Összegzés

Most a webhelyünknek elérhetővé kell válnia a helloworld.ru és dev.helloworld.ru címen (a prod és dev környezetek megfelelően).

Összességében megtanultuk, hogyan készíthetünk egy egyszerű alkalmazást Flask és Angular használatával, és hogyan állíthatunk be egy pipeline-t a Github Actions-ban a kiszolgálóra való feltelepítéshez Plesk irányítása alatt.

Megosztom a kód repóira mutató linkeket: háttér, frontend.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster