CI/CD në Github Actions për projektin në Flask+Angular

CI/CD në Github Actions për projektin në Flask+Angular
Në këtë artikull do të ndaj përvojën time në konfigurimin e CI/CD me përdorimin e panelit të kontrollit Plesk dhe Github Actions. Sot do të mësojmë si të deploy një projekt të thjeshtë me titullin "Helloworld". Ai është shkruar në framework-un Python Flask, me punëtorë në Celery dhe frontend në Angular 8.

Linket e depove: back-end, frontend.

Në pjesën e parë të artikullit do të hedhim një vështrim mbi projektin tonë dhe pjesët e tij. Në të dytën, do të kuptojmë si të konfiguroni Plesk dhe të instaloni zgjatjet dhe komponentët e nevojshëm (DB, RabbitMQ, Redis, Docker, etj.).

Në pjesën e tretë, përfundimisht do të kuptojmë si të configure pipeline për të deploy projektin tonë në server në mjediset dev dhe prod. Pas kësaj, do ta lancojmë sitin në server.

Dhe po, harrova të prezantohem. Emri im është Oleg Borzov, unë jam zhvillues fullstack në ekipin CRM për menaxherët e kredive hipoteke në Domklik.

Përmbledhja e projektit

Për fillim, do të shqyrtojmë dy repozita të projektit - backend dhe frontend - dhe do të kalojmë përmes kodit.

Pjesa backend: Flask+Celery

Për backend kam marrë një kombinim mjaft të njohur ndër zhvilluesit e Python: frameworkun Flask (për API) dhe Celery (për radhën e detyrave). Përdoret SQLAlchemy si ORM. Për migrimet aplikohet Alembic. Për vërtetimin e JSON në endpoint-e përdoret Marshmallow.

Në repozitorit ekziston një skedë Readme.md me një përshkrim të detajuar të strukturës dhe udhëzimeve për nisjen e projektit.

API e pjesës web është mjaft e thjeshtë, përbëhet nga 6 endpoint-e:

  • /ping — pĂ«r kontrollimin e disponueshmĂ«risĂ«;
  • endpoint-e pĂ«r regjistrim, autentifikim, çautentifikim dhe pĂ«r tĂ« marrĂ« pĂ«rdoruesin e identifikuar;
  • endpoint pĂ«r dĂ«rgimin e email-it, qĂ« vendos njĂ« detyrĂ« nĂ« radhĂ«n Celery.

Pjesa e Celery është edhe më e thjeshtë, aty ka vetëm një detyrë send_mail_task.

Në dosjen /conf janë dy nënfoldera:

  • docker me dy skeda Docker (base.dockerfile pĂ«r ndĂ«rtimin e imazhit tĂ« bazĂ«s qĂ« ndryshohet rrallĂ« dhe Dockerfile pĂ«r ndĂ«rtimet kryesore);
  • .env_files — me skedarĂ« pĂ«r variablat mjedisore pĂ«r ambiente tĂ« ndryshme.

Në rrënjë të projektit ndodhen katër skedarë docker-compose:

  • docker-compose.local.db.yml pĂ«r ngritjen e bazĂ«s sĂ« tĂ« dhĂ«nave lokale pĂ«r zhvillim;
  • docker-compose.local.workers.yml pĂ«r ngritjen lokale tĂ« punonjĂ«sve, bazĂ«s sĂ« tĂ« dhĂ«nave, Redis dhe RabbitMQ;
  • docker-compose.test.yml pĂ«r ekzekutimin e testeve gjatĂ« shpĂ«rndarjes;
  • docker-compose.yml pĂ«r deploy.

Dhe folderi i fundit interesant pĂ«r ne — .ci-cd. NĂ« tĂ« gjetur skriptet shell pĂ«r vendosjen:

  • deploy.sh — nisja e migrimit dhe vendosjes. Aktivizohet nĂ« server pas ndĂ«rtimit dhe pĂ«rmbushjes sĂ« testeve nĂ« Github Actions;
  • rollback.sh — rikthimi i kontejnerĂ«ve nĂ« versionin e mĂ«parshĂ«m tĂ« ndĂ«rtimit;
  • curl_tg.sh — dĂ«rgimi i njoftimeve pĂ«r vendosjen nĂ« Telegram.

Frontend në Angular

Repoja me frontend është shumë më e thjeshtë se ajo e backend-it. Fronti përbëhet nga tri faqe:

  • Faqja kryesore me njĂ« formĂ« pĂ«r dĂ«rgimin e email-it dhe njĂ« buton pĂ«r daljen.
  • Faqja e hyrjes.
  • Faqja e regjistrimit.

Faqja kryesore duket askeptike:

CI/CD në Github Actions për projektin në Flask+Angular
Në rrënjë ndodhen dy skedarë Dockerfile dhe docker-compose.yml, si dhe një dosje e njohur për ne .ci-cd me një numër pak më të vogël skriptesh se në repo-n e backend-it (skriptet për fillimin e testeve janë larguar).

Krijojmë projektin në Plesk

Le të fillojmë me konfigurimin e Plesk dhe krijimin e abonimit për sajtin tonë.

Instalimi i shtesave

Në Plesk do na nevojiten katër shtesa:

  • Docker pĂ«r menaxhimin dhe shfaqjen vizuale tĂ« gjendjes sĂ« kontejnerĂ«ve nĂ« adminin e Plesk;
  • Git pĂ«r konfigurimin e hapit tĂ« vendosjes nĂ« server;
  • Let's Encrypt pĂ«r gjenerimin (dhe rinovimin automatik) e certifikatave falas TLS;
  • Firewall pĂ«r konfigurimin e filtrimit tĂ« trafikut qĂ« hyn.

Mund t'i instalojmë ato përmes adminit të Plesk në seksionin Shtesat:

CI/CD në Github Actions për projektin në Flask+Angular
Ne do të merremi me konfigurimin e detajuar të shtesave, konfigurimet e paracaktuara do të mjaftojnë për qëllimet tona demo.

Krijimi i një abonimi dhe një faqjeje

Më pas na nevojitet të krijojmë një abonim për faqen tonë helloworld.ru dhe të shtojmë atje subdomain-in dev.helloworld.ru.

  1. Krijojmë një abonim për domenin helloworld.ru dhe specifikojmë emrin e përdoruesit dhe fjalëkalimin për përdoruesin sistemik:

    CI/CD në Github Actions për projektin në Flask+Angular
    PoshtĂ« faqes, vendosim shenjĂ«n e kontrollit Siguroni domenin me Let’s Encrypt, nĂ«se dĂ«shirojmĂ« tĂ« konfigurojmĂ« HTTPS pĂ«r faqen:

    CI/CD në Github Actions për projektin në Flask+Angular

  2. Më pas në këtë abonim krijojmë subdomain-in dev.helloworld.ru (për të cilin gjithashtu mund të lëshojmë një certifikatë falas TLS):

    CI/CD në Github Actions për projektin në Flask+Angular

Instalimi i komponentëve serverikë

Ne kemi në dispozicion një server me OS Debian Stretch 9.12 dhe me panelin e menaxhimit të instaluar Plesk Obsidian 18.0.27.

Na nevojitet të instalojmë dhe konfigurojmë për projektin tonë:

  • PostgreSQL (nĂ« rastin tonĂ« do tĂ« jetĂ« njĂ« server me dy DB pĂ«r ambientet dev dhe prod).
  • RabbitMQ (po ashtu, njĂ« instancĂ« me vhosts tĂ« ndryshĂ«m pĂ«r ambientet).
  • Dy instanca Redis (pĂ«r ambientet dev dhe prod).
  • Docker Registry (pĂ«r ruajtjen lokale tĂ« imazheve tĂ« pĂ«rmbledhura Docker).
  • UI-interfaca pĂ«r Docker registry.

PostgreSQL

Me Plesk vjen edhe një DBMS PostgreSQL, megjithatë jo në versionin më të ri (në momentin e shkrimit të artikullit Plesk Obsidian mbështeste Ne duam të vendosim versionin më të fundit të Postgres (12.3 në momentin e shkruajtjes së këtij artikulli) për aplikacionin tonë, prandaj do ta instalojmë manualisht.

Ka shumĂ« udhĂ«zime tĂ« detajuara pĂ«r instalimin e Postgres nĂ« Debian nĂ« internet (shembull), prandaj nuk do tĂ« pĂ«rshkruaj me detaje, vetĂ«m do t’i jap komandat:

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

Duke marrë parasysh që PostgreSQL ka konfigurime mjaft mesatare nga fabrika, është e nevojshme të rregullojmë konfigurimin. Këtë do ta ndihmojmë llogaritës: duhet të vendosni parametrat e serverit tuaj dhe të zëvendësoni konfigurimet në skedarin /etc/postgresql/12/main/postgresql.confme ato të sugjeruara. Duhet përmendur se kalkulatorët e tillë nuk janë zgjidhja magjike, dhe baza duhet të tuneohet më saktësisht, duke u bazuar në harduerin tuaj, aplikacionin dhe kompleksitetin e kërkesave. Por për fillimin, kjo është e mjaftueshme.

PĂ«rveç konfigurimeve tĂ« propozuara nga kalkulatori, gjithashtu ndryshojmĂ« nĂ« postgresql.confportin 5432 tĂ« vendosur nĂ« mĂ«nyrĂ« tĂ« paracaktuar me njĂ« tjetĂ«r (nĂ« shembullin tonĂ« — 53983).

Pas ndryshimit të skedarit të konfigurimit, rishtazgjedhim postgresql-server me komandën:

service postgresql restart

Ne kemi instaluar dhe konfiguruar PostgreSQL. Tani do të krijojmë BAZAT e të dhënave, përdoruesit për ambientet dev dhe prod, dhe do t'u japim përdoruesve të drejtat për të menaxhuar bazën e të dhënave:

$ 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Ă« kalojmĂ« te instalimi i RabbitMQ — brokeri i mesazheve pĂ«r Celery. Instalimi Ă«shtĂ« mjaft i thjeshtĂ« nĂ« 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

Pas instalimit, ne duhet të krijojmë vhosts, përdoruesit dhe t'u japim të drejtat e nevojshme:

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

Tani do tĂ« instalojmĂ« dhe konfigurojmĂ« komponentin e fundit pĂ«r aplikacionin tonĂ« — Redis. Ai do tĂ« pĂ«rdoret si backend pĂ«r ruajtjen e rezultateve tĂ« detyrave Celery.

Ne do të ngremë dy kontejnerë Docker me Redis për ambientet dev dhe prod me ndihmën e zgjatjes Docker për Plesk.

  1. Hymë në Plesk, kalojmë te seksioni Zgjerime, kërkojmë zgjerimin Docker dhe e instalojmë (na nevojitet versioni falas):

    CI/CD në Github Actions për projektin në Flask+Angular

  2. Kalo në zgjerimin e instaluar, kërko me kërkimin imazhin redis bitnami dhe vendos versionin më të fundit:

    CI/CD në Github Actions për projektin në Flask+Angular

  3. Hymë në kontejnerin e shkarkuar dhe korrigjojmë konfigurimin: përcaktojmë portin, madhësinë maksimale të RAM-it, fjalëkalimin në variablat e mjedisit, dhe montojmë vëllimin:

    CI/CD në Github Actions për projektin në Flask+Angular

  4. Kryejmë hapat 2-3 për kontejnerin prod, vetëm ndryshojmë parametrat: portin, fjalëkalimin, madhësinë e RAM-it dhe rrugën për dosjen e vëllimit në server:

    CI/CD në Github Actions për projektin në Flask+Angular

Docker Registry

Përveç shërbimeve bazike, do të ishte mirë të vendosnim në serverin tonë një repository të vetin të imazheve Docker. Fatmirësisht, vendi në servera tani është mjaft i lirë (me siguri më i lirë se abonimi në DockerHub), dhe procesi i instalimit të një repository privat është shumë i thjeshtë.

Ne duam që të kemi instaluar:

Për këtë:

  1. Do tĂ« krijojmĂ« nĂ« Plesk dy podomene nĂ« abonimin tonĂ«: docker.helloworld.ru dhe docker-ui.helloworld.ru, dhe do t'i konfiguroni pĂ«r ta pĂ«rdorur certifikatĂ«n Let’s Encrypt.
  2. Në dosjen e podomenit docker.helloworld.ru do të shtojmë skedarin docker-compose.yml me këtë përmbajtje:
    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. Përmes SSH do të gjenerojmë skedarin .htpasswd për autorizimin Basic në repositorin Docker:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Do të ndërtojmë dhe ngremë kontenierët:
    docker-compose up -d
  5. Dhe duhet të drejtojmë Nginx në kontenierët tanë. Kjo mund të bëhet përmes Plesk.

Veprimet e mëposhtme duhet të kryhen për podomene docker.helloworld.ru dhe docker-ui.helloworld.ru:

Në seksionin Dev Tools në faqen tonë shkojmë tek Docker Proxy Rules:

CI/CD në Github Actions për projektin në Flask+Angular
Dhe shtojmë një rregull për të prokuruar trafikun e hyrjes në kontenierin tonë:

CI/CD në Github Actions për projektin në Flask+Angular

  1. Po shikojmë nëse mund të autorizohemi në kontejnerin tonë nga makina lokale:
    $ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password
    KËRCËNIM! PĂ«rdorimi i --password pĂ«rmes CLI Ă«shtĂ« i pasigurt. PĂ«rdorni --password-stdin.
    Autorizimi u krye me sukses
  2. Gjithashtu do të kontrollojmë funksionimin e subdomain-it docker-ui.helloworld.ru:

    CI/CD në Github Actions për projektin në Flask+Angular
    Kur të klikoni në Browse repositories, shfletuesi do të hapë një dritare për autorizim, ku do t'ju duhet të jepni emrin e përdoruesit dhe fjalëkalimin për depozitën. Pas kësaj, do të na çojë në faqen me listën e depozitave (tani për ju ajo do të jetë bosh):

    CI/CD në Github Actions për projektin në Flask+Angular

Hapni portat në Plesk Firewall

Pas instalimit dhe konfigurimit të komponentëve, na nevojitet të hapim portat që komponentët të jenë të aksesueshëm nga kontejnerët Docker dhe rrjeti i jashtëm.

Le të shohim se si ta bëjmë këtë me shembullin e zgjerimit të Firewall për Plesk që kemi instaluar më parë.

  1. Kalojmë në Tools & Settings > Settings > Firewall:
    CI/CD në Github Actions për projektin në Flask+Angular
  2. Kalojmë në Modifikoni Rregullat e Plesk Firewall > Shto Rregull të Personalizuar dhe hapni portat TCP të mëposhtme për subnet-in Docker (172.0.0.0/8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD në Github Actions për projektin në Flask+Angular

  3. Gjithashtu do të shtojmë një rregull që do të hapë portet për PostgreSQL dhe panelin e menaxhimit të RabbitMQ për botën e jashtme:

    CI/CD në Github Actions për projektin në Flask+Angular

  4. Zbatoni rregullat me butonin Apply Changes:

    CI/CD në Github Actions për projektin në Flask+Angular

Konfigurimi i CI/CD në Github Actions

TĂ« kalojmĂ« nĂ« pjesĂ«n mĂ« tĂ« interesantĂ« — konfigurimin e pipeline-it pĂ«r integrimin dhe shpĂ«rndarjen e vazhdueshme tĂ« projektit tonĂ« nĂ« server.

Ky kyç do të përbëhet nga dy pjesë:

  • ndĂ«rtimi i imazhit dhe ekzekutimi i testeve (pĂ«r backend) — nĂ« anĂ«n e Github;
  • njĂ« hapĂ«sirĂ« (pĂ«r backend) dhe depozitimi i kontejnerĂ«ve — nĂ« server.

Depoja në Plesk

Të merremi fillimisht me pikën e dytë (sepse varet nga e para).

Procesi i depoy-it do të konfigurohet me ndihmën e shtesës Git për Plesk.

Të shqyrtojmë një shembull me ambientin Prod për depozitën e Backend.

  1. Hyrim në abonimin e faqes sonë Helloworld dhe kaloni në nënseksionin Git:

    CI/CD në Github Actions për projektin në Flask+Angular

  2. Ngjitim në fushën "Remote Git repository" lidhjen me depozitën tonë në Github dhe ndryshojmë dosjen e paracaktuar httpdocs në një tjetër (për shembull, /httpdocs/hw_back):

    CI/CD në Github Actions për projektin në Flask+Angular

  3. Kopjojmë çelësin publik SSH nga etapa e mëparshme dhe shtojmë e vendosim në konfigurimet e Github.
  4. Klikoni OK në ekranin në pikën 2, pas së cilës do të kalojmë në faqen e depozitës në Plesk. Tani na nevojitet të konfigurojmë azhurnimin e depozitës për ndodhitë në degën master. Për këtë kaloni në Cilësimet e Depozitës dhe ruani vlerën Webhook URL (do të na nevojitet më vonë gjatë konfigurimit të Github Actions):

    CI/CD në Github Actions për projektin në Flask+Angular

  5. Në fushën e veprimeve në ekranin nga pika e mëparshme shkruani skriptin për të nisur depoy-in:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    ku:

    {REPOSITORY_ABSOLUTE_PATH} — rruga e dosjes prod backend-repozitorit nĂ« server;
    {ENV} — mjedisi (dev/prod), nĂ« rastin tonĂ« prod;
    {DOCKER_REGISTRY_HOST} — hosti i repositorit tonĂ« docker
    {TG_BOT_TOKEN} — tokeni i bot-it te Telegram;
    {TG_CHAT_ID} — ID e bisedĂ«s/kanalit pĂ«r dĂ«rgimin e njoftimeve.

    Shembulli i skriptit:

    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. Shtojmë përdoruesin nga abonimi ynë në grupin Docker (që të mund të menaxhojë kontejnerët):
    sudo usermod -aG docker helloworld_admin

Mjedisi Dev për backend-repozitorin dhe frontend konfigurohen njësoj.

Pipeline i depërtimit në Github Actions

Kalojmë te konfigurimi i pjesës së parë të CI/CD pipeline tonë në Github Actions.

Backend

Pajisja përshkruhet në skedarin deploy.yml.

Por para se ta shqyrtojmë, plotësojmë në Github variablat e nevojshme Sekrete. Për këtë kalojmë në Settings -> Secrets:

  • DOCKER_REGISTRY — hosti i repositorit tonĂ« Docker (docker.helloworld.ru);
  • DOCKER_LOGIN — pĂ«rdoruesi pĂ«r repositorin Docker;
  • DOCKER_PASSWORD — password-i pĂ«r tĂ«;
  • DEPLOY_HOST — hosti, ku Ă«shtĂ« e aksesueshme administrata Plesk (shembull: helloworld.ru:8443 ose 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN — tokeni pĂ«r depĂ«rtimin nĂ« repositorin prod nĂ« server (e kemi marrĂ« nĂ« Shtrirjen nĂ« Plesk pika 4);
  • DEPLOY_BACK_DEV_TOKEN — tokeni pĂ«r depĂ«rtimin nĂ« repositorin dev nĂ« server.

Procesi i deployment-it është i thjeshtë dhe përbëhet nga tri hapa kryesorë:

  • ndĂ«rtimi dhe publikimi i imazhit nĂ« depozitĂ«n tonĂ«;
  • kryerja e testeve nĂ« kontejnerin bazuar nĂ« imazhin e sapo ndĂ«rtuar;
  • vendosja nĂ« mjedisin e duhur nĂ« varĂ«si tĂ« degĂ«s (dev/master).

Frontend

Skedari deploy.yml për depozitën frontale nuk ndryshon shumë nga ai i pasmë. Aty nuk ka hapin e kryerjes së testeve dhe emrat e tokeneve për deployment ndryshojnë. Sekretet për depozitën frontale, për fat të mirë, duhet të plotësohen veçmas.

Konfigurimi i faqes

Proksimi i trafikut përmes Nginx

Përfundimisht, kemi arritur në fund. Mbete vetëm të konfigurojmë proksimin e trafikut hyrës dhe dalës në kontejnerin tonë përmes Nginx. Ky proces e kemi trajtuar tashmë në pikën 5 të konfigurimit të Docker Registry. E njëjta gjë duhet përsëritur për pjesët frontale dhe të pasme në mjediset dev dhe prod.

Do të sjell disa shkrepje të konfigurimeve.

Backend

CI/CD në Github Actions për projektin në Flask+Angular

Frontend

CI/CD në Github Actions për projektin në Flask+Angular
ShĂ«nim i rĂ«ndĂ«sishĂ«m. NĂ« kontejnerin frontend do tĂ« proksohen tĂ« gjitha URL-tĂ« pĂ«rveç atyre qĂ« fillojnĂ« me /api/ — ato do tĂ« proksohen nĂ« kontejnerin backend (prandaj nĂ« kontejnerin backend tĂ« gjitha trajtuesit duhet tĂ« fillojnĂ« me /api/).

Përfundimet

Tani faqja jonë duhet të jetë e aksesueshme në adresat helloworld.ru dhe dev.helloworld.ru (mjedisi prod dhe dev përkatës).

Në përmbledhje, mësuam si të përgatisim një aplikacion të thjeshtë në Flask dhe Angular dhe si të konfiguroni një pipeline në Github Actions për ta deployuar në një server që përdor Plesk.

Do ta përsëris lidhjet për repozitorët me kodin: back-end, frontend.

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster