CI/CD i Github Actions för ett projekt pÄ Flask+Angular

CI/CD i Github Actions för ett projekt pÄ Flask+Angular
I den hÀr artikeln kommer jag att dela med mig av min erfarenhet av att konfigurera CI/CD med hjÀlp av kontrollpanelen Plesk och Github Actions. Idag ska vi lÀra oss att distribuera ett enkelt projekt med den okomplicerade titeln "Helloworld". Det Àr skrivet i Python-ramverket Flask, med arbetare pÄ Celery och frontend pÄ Angular 8.

LĂ€nkar till repositoryn: backend, frontend.

I den första delen av artikeln kommer vi att titta pÄ vÄrt projekt och dess delar. I den andra kommer vi att gÄ igenom hur man konfigurerar Plesk och installerar nödvÀndiga tillÀgg och komponenter (DB, RabbitMQ, Redis, Docker, etc.).

I den tredje delen kommer vi Àntligen att ta reda pÄ hur man stÀller in en pipeline för att distribuera vÄrt projekt pÄ servern i dev- och prod-miljö. Och sedan kommer vi att starta webbplatsen pÄ servern.

Och ja, jag glömde att presentera mig. Jag heter Oleg Borzov, jag Àr fullstack-utvecklare i CRM-teamet för hypotekslÄneledare pÄ Domklik.

Projektöversikt

Först ska vi titta pĂ„ tvĂ„ repositoryn för projektet — backend och frontend — och gĂ„ igenom koden.

Backend-del: Flask+Celery

För backend-delen har jag valt en ganska populĂ€r kombination bland Python-utvecklare: ramverket Flask (för API) och Celery (för uppgiftskö). SQLAlchemy anvĂ€nds som ORM. Alembic anvĂ€nds för migreringar. För validering av JSON i endpoints — Marshmallow.

I förrÄdet det finns en fil Readme.md med en detaljerad beskrivning av strukturen och instruktioner för att köra projektet.

API-webbdel ganska okomplicerat, bestÄr av 6 endpoints:

  • /ping — för att kontrollera tillgĂ€nglighet;
  • endpoints för registrering, autentisering, avregistrering och att hĂ€mta den autentiserade anvĂ€ndaren;
  • endpoint för att skicka e-post, som lĂ€gger en uppgift i Celery-kön.

Celery-del Ànnu enklare, det finns bara en uppgift send_mail_task.

I mappen /conf det finns tvÄ undermappar:

  • docker med tvĂ„ Docker-filer (base.dockerfile för att skapa en sĂ€llan Ă€ndrad basbild och Dockerfile för huvudbyggnationerna);
  • .env_files — med filer för miljövariabler för olika miljöer.

I roten av projektet finns fyra docker-compose-filer:

  • docker-compose.local.db.yml för att starta en lokal databas för utveckling;
  • docker-compose.local.workers.yml för lokal uppstart av arbetare, databas, Redis och RabbitMQ;
  • docker-compose.test.yml för att köra tester vid distribution;
  • docker-compose.yml för distribution.

Och den sista intressanta mappen för oss — .ci-cd. Den innehĂ„ller shell-skript för distribution:

  • deploy.sh — körning av migreringar och distribution. Startas pĂ„ servern efter byggnation och körning av tester i Github Actions;
  • rollback.sh — Ă„terstĂ€llning av containrar till föregĂ„ende version av bygget;
  • curl_tg.sh — skickar meddelanden om distribution till Telegram.

Frontend pÄ Angular

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

  • The main page with a form to send an email and a logout button.
  • Login page.
  • Registration page.

The main page looks minimalistic:

CI/CD i Github Actions för ett projekt pÄ Flask+Angular
At the root, there are two files Dockerfile och docker-compose.yml, as well as the familiar folder .ci-cd with slightly fewer scripts than in the back-end repository (scripts for running tests have been removed).

Setting up the 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;
  • Git for setting the deployment step on the server;
  • Let's Encrypt for generating (and auto-renewing) free TLS certificates;
  • Firewall for configuring incoming traffic filtering.

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

CI/CD i Github Actions för ett projekt pÄ Flask+Angular
We won't discuss the detailed configuration of the extensions, the default settings will suffice for our demo purposes.

Creating a subscription and a site

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

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

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular
    At the bottom of the page, we check the box Secure the domain with Let’s Encrypt, if we want to set up HTTPS for the website:

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

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

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

Installing server components

We have a server with OS Debian Stretch 9.12 and the control panel installed 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 package already includes a PostgreSQL DBMS in Plesk, but it's not the latest version (at the time of writing, 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 online (exempel), 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

Eftersom PostgreSQL har ganska medelmÄttiga standardinstÀllningar Àr det viktigt att justera konfigurationen. Det kan vi fÄ hjÀlp med av kalkylator: vi behöver ange parametrarna för vÄr server och ersÀtta instÀllningarna i filen /etc/postgresql/12/main/postgresql.confmed de föreslagna. HÀr ska det tillÀggas att sÄdana kalkylatorer inte Àr en universallösning, och databasen bör justeras mer exakt baserat pÄ din hÄrdvara, applikationen och komplexiteten i frÄgorna. Men för att börja Àr detta tillrÀckligt.

Förutom de av kalkylatorn föreslagna instÀllningarna Àndrar vi Àven postgresql.confden standardport som Àr angiven 5432 till en annan (i vÄrt exempel - 53983).

Efter att vi har Àndrat konfigurationsfilen, startar vi om postgresql-servern med kommandot:

service postgresql restart

Vi har installerat och konfigurerat PostgreSQL. Nu ska vi skapa databaser, anvÀndare för dev- och prod-miljöer, och ge anvÀndarna rÀttigheter att hantera databasen:

$ 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

LĂ„t oss gĂ„ vidare till installationen av RabbitMQ — meddelandebrokern för Celery. Det installeras ganska enkelt pĂ„ 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

Efter installationen behöver vi skapa vhosts, anvÀndare och ge dem nödvÀndiga rÀttigheter:

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

Nu ska vi installera och konfigurera den sista komponenten för vĂ„r applikation — Redis. Den kommer att anvĂ€ndas som backend för att lagra resultaten av uppgifter i Celery.

Vi kommer att starta tvÄ Docker-containrar med Redis för dev- och prod-miljöer med hjÀlp av tillÀgget Docker för Plesk.

  1. Logga in pÄ Plesk, gÄ till avsnittet TillÀgg, sök efter tillÀgget Docker och installera det (vi behöver gratisversionen):

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  2. GÄ till det installerade tillÀgget, sök efter bilden redis bitnami och installera den senaste versionen:

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  3. GÄ in i den nedladdade containern och justera konfigurationen: ange port, maximalt tilldelat RAM-minne, lösenord i miljövariabler och montera volymen:

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  4. Utför steg 2-3 för prod-containern, Àndra bara instÀllningarna: port, lösenord, RAM-storlek och sökvÀg till volymmappen pÄ servern:

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

Docker Registry

Förutom grundlÀggande tjÀnster skulle det vara bra att installera ett eget Docker-bildarkiv pÄ servern. Tack vare att utrymme pÄ servrar nu Àr ganska billigt (definitivt billigare Àn en prenumeration pÄ DockerHub), och installationen av ett privat arkiv Àr mycket enkel.

Vi vill att följande ska vara installerade:

För detta:

  1. Vi skapar tvÄ subdomÀner i Plesk i vÄr prenumeration: docker.helloworld.ru och docker-ui.helloworld.ru, och konfigurerar Let's Encrypt-certifikat för dem.
  2. I mappen för subdomÀnen docker.helloworld.ru lÀgger vi till filen docker-compose.yml med följande innehÄll:
    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. Genom SSH ska vi generera filen .htpasswd för grundlÀggande autentisering i Docker-arkivet:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Bygg och starta containrarna:
    docker-compose up -d
  5. Och vi behöver dirigera Nginx till vÄra containrar. Det kan göras via Plesk.

Följande ÄtgÀrder mÄste vidtas för subdomÀnerna docker.helloworld.ru och docker-ui.helloworld.ru:

I avsnittet Dev Tools pÄ vÄr webbplats gÄr vi till Docker Proxy Rules:

CI/CD i Github Actions för ett projekt pÄ Flask+Angular
Och lÀgg till en regel för att proxy-trafiken till vÄr container:

CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  1. Kontrollera att vi kan logga in pÄ vÄr container frÄn den lokala maskinen:
    $ 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. Vi kontrollerar ocksÄ att subdomÀnen docker-ui.helloworld.ru fungerar:

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular
    NÀr du trycker pÄ Browse repositories kommer webblÀsaren att visa en inloggningsruta dÀr du behöver ange anvÀndarnamn och lösenord för lagret. Efter det tas du till en sida med en lista över lagren (den kommer vara tom för dig just nu):

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

Öppna portar i Plesk Firewall

Efter installation och konfiguration av komponenterna behöver vi öppna portar sÄ att komponenterna blir tillgÀngliga frÄn Docker-containrar och frÄn det externa nÀtverket.

LÄt oss se hur detta görs med hjÀlp av det tidigare installerade Firewall-tillÀgget för Plesk.

  1. Vi gÄr till Verktyg & InstÀllningar > InstÀllningar > BrandvÀgg:
    CI/CD i Github Actions för ett projekt pÄ Flask+Angular
  2. Vi gĂ„r till Ändra Plesk Firewall-regler > LĂ€gg till anpassad regel och öppna följande TCP-portar för Docker-undernĂ€tet (172.0.0.0/8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  3. LÄt oss ocksÄ lÀgga till en regel som öppnar portar för PostgreSQL och RabbitMQ:s administrationspanel för omvÀrlden:

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  4. TillÀmpa reglerna med hjÀlp av knappen TillÀmpa Àndringar:

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

Konfiguration av CI/CD i Github Actions

LĂ„t oss gĂ„ till den mest intressanta delen — konfigurationen av pipeline för kontinuerlig integration och leverans av vĂ„rt projekt till servern.

Denna pipeline kommer att bestÄ av tvÄ delar:

  • bygga bilden och köra tester (för backend) — pĂ„ Github-sidan;
  • köra migrationer (för backend) och distribuera containrar — pĂ„ servern.

Distribution i Plesk

Vi börjar med det andra punkten (eftersom det pÄverkar det första).

Vi kommer att konfigurera distributionsprocessen med hjÀlp av Git-tillÀgget för Plesk.

Vi tar ett exempel med produktionsmiljön för Backend-lagret.

  1. GÄ till prenumerationen för vÄr webbplats Helloworld och navigera till avsnittet Git:

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  2. Klistra in lÀnken till vÄrt Github-lager i fÀltet "Remote Git repository" och Àndra standardmappen httpdocs till en annan (till exempel, /httpdocs/hw_back):

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  3. Kopiera SSH-public key frÄn föregÄende steg och lÀgg till sÀtt in den i instÀllningarna för Github.
  4. Klicka pÄ OK pÄ skÀrmen under punkt 2, efter vilket du tas till sidan för lagret i Plesk. Nu mÄste vi stÀlla in uppdateringen av lagret vid commit till master-grenen. För detta gÄr vi till Repository Settings och sparar vÀrdet Webhook URL (det kommer att behövas senare för att konfigurera Github Actions):

    CI/CD i Github Actions för ett projekt pÄ Flask+Angular

  5. I fÀltet Actions pÄ skÀrmen frÄn föregÄende punkt, skriv in skriptet för att starta distributionen:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    dÀr:

    {REPOSITORY_ABSOLUTE_PATH} — vĂ€gen till prod-mappen för backend-lagret pĂ„ servern;
    {ENV} — miljö (dev/prod), i vĂ„rt fall prod;
    {DOCKER_REGISTRY_HOST} — vĂ€rden för vĂ„rt docker-lager
    {TG_BOT_TOKEN} — token för Telegram-botten;
    {TG_CHAT_ID} — ID för chatten/kanalen för att skicka notifieringar.

    Exempel pÄ skript:

    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. LÀgg till anvÀndaren frÄn vÄr prenumeration i Docker-gruppen (sÄ att han kan hantera containrar):
    sudo usermod -aG docker helloworld_admin

Utvecklingsmiljön för backend-repositoriet och frontend stÀlls in pÄ samma sÀtt.

Deploy-pipeline i Github Actions

LÄt oss gÄ vidare med att konfigurera första delen av vÄr CI/CD-pipeline i Github Actions.

Backend

Pipelinen beskrivs i filen deploy.yml.

Men innan vi gÄr igenom den behöver vi fylla i de nödvÀndiga hemliga variablerna i Github. För detta gÄr vi till InstÀllningar -> Hemliga:

  • DOCKER_REGISTRY — vĂ€rd för vĂ„rt Docker-repositorium (docker.helloworld.ru);
  • DOCKER_LOGIN — inloggning till Docker-repositoriet;
  • DOCKER_PASSWORD — lösenordet till det;
  • DEPLOY_HOST — vĂ€rd dĂ€r Plesk-administrationspanelen Ă€r tillgĂ€nglig (exempel: helloworld.ru:8443 eller 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN — token för att deploya till prod-repositoriet pĂ„ servern (vi fick det i Deploy till Plesk punkt 4);
  • DEPLOY_BACK_DEV_TOKEN — token för att deploya till dev-repositoriet pĂ„ servern.

Deploy-processen Àr enkel och bestÄr av tre huvudsteg:

  • bygge och publicering av bilden i vĂ„rt repositorium;
  • körning av tester i containern baserat pĂ„ den nybyggda bilden;
  • deployering till rĂ€tt miljö beroende pĂ„ grenen (dev/master).

Frontend

Filen deploy.yml för frontend-repositoriet skiljer sig inte mycket frÄn backend-versionen. Den saknar steget med att köra tester och namnen pÄ tokens för deployering Àndras. Hemligheterna för frontend-repositoriet mÄste förresten fyllas i separat.

WebbplatsinstÀllning

Proxytrafik genom Nginx

NÄvÀl, vi har kommit till slutet. Det ÄterstÄr bara att stÀlla in proxytrafik för inkommande och utgÄende trafik till vÄr container genom Nginx. Denna process har vi redan gÄtt igenom i punkt 5 i Docker Registry-instÀllningarna. Samma sak mÄste upprepas för backend- och frontend-delarna i dev- och prod-miljöerna.

Jag kommer att visa skÀrmdumpar av instÀllningarna.

Backend

CI/CD i Github Actions för ett projekt pÄ Flask+Angular

Frontend

CI/CD i Github Actions för ett projekt pÄ Flask+Angular
Viktig anmĂ€rkning. I frontend-containern kommer alla URL:er att proxas, förutom de som börjar med /api/ — de kommer att proxas till backend-containern (dĂ€rför mĂ„ste i backend-containern alla handhavanden börja med /api/).

Sammanfattning

Nu bör vÄr webbplats vara tillgÀnglig pÄ adresserna helloworld.ru och dev.helloworld.ru (prod- och dev-miljöer respektive).

Sammanfattningsvis har vi lÀrt oss hur man förbereder en enkel applikation pÄ Flask och Angular och hur man stÀller in en pipeline i Github Actions för att lansera den pÄ en server som styrs av Plesk.

Jag vill ocksÄ dela lÀnkar till reporna med koden: backend, frontend.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster