CI/CD i Github Actions til et projekt på Flask+Angular

CI/CD i Github Actions til et projekt på Flask+Angular
I denne artikel vil jeg dele min erfaring med at indstille CI/CD ved hjælp af Plesk kontrolpanelet og Github Actions. I dag skal vi lære at deployere et simpelt projekt med det uformelle navn «Helloworld». Det er skrevet med Python-rammen Flask, med arbejdere på Celery og frontend på Angular 8.

Links til repositories: backend, frontend.

I den første del af artiklen vil vi se på vores projekt og dets dele. I den anden vil vi finde ud af, hvordan man konfigurerer Plesk og installerer de nødvendige udvidelser og komponenter (DB, RabbitMQ, Redis, Docker osv.).

I den tredje del vil vi endelig undersøge, hvordan man konfigurerer en pipeline til at deployere vores projekt på serveren i dev- og prod-miljø. Og så vil vi køre hjemmesiden på serveren.

Og ja, jeg glemte at præsentere mig selv. Jeg hedder Oleg Borzov, jeg er fullstack-udvikler i CRM-teamet for boliglånsmanagere hos Domklik.

Projektoversigt

Lad os først se på de to repositories for projektet — backend og frontend — og få et indblik i koden.

Backend-delen: Flask+Celery

Til backend-delen har jeg valgt en ret populær kombination blandt Python-udviklere: Flask framework (til API) og Celery (til opgavekø). SQLAlchemy bruges som ORM. Alembic anvendes til migrationer. Til validering af JSON i hænderne — Marshmallow.

I repository Der er en Readme.md-fil med en detaljeret beskrivelse af strukturen og instruktioner til at starte projektet.

API-webdelen er forholdsvis simpel og består af 6 endpoints:

  • /ping — til at kontrollere tilgængelighed;
  • endpoints til registrering, autorisering, deautorisering og til at få den autoriserede bruger;
  • et endpoint til at sende email, der placerer en opgave i Celery-køen.

Celery-delen er endnu enklere, der er kun én opgave send_mail_task.

I mappen /conf der er to undermapper:

  • docker med to Docker-filer (base.dockerfile til at bygge et grundlæggende billede, der sjældent ændres, og Dockerfile til de vigtigste builds);
  • .env_files — med filer til miljøvariabler for forskellige miljøer.

I rodmappen af projektet findes der fire docker-compose-filer:

  • docker-compose.local.db.yml til at starte en lokal database til udvikling;
  • docker-compose.local.workers.yml til lokalt at starte arbejdere, database, Redis og RabbitMQ;
  • docker-compose.test.yml til at køre tests under implementering;
  • docker-compose.yml til deployment.

Og den sidste interessante mappe for os — .ci-cd. I den ligger shell-scripts til deployment:

  • deploy.sh — kørsel af migrationer og deployment. Kører på serveren efter build og test i Github Actions;
  • rollback.sh — tilbageførsel af containere til den tidligere version af build;
  • curl_tg.sh — sending notifications about deployment on Telegram.

Frontend på Angular

Repository med front er meget enklere end back. Fronten består af tre sider:

  • Forsiden med en formular til at sende e-mail og en logout-knap.
  • Login-side.
  • Registreringsside.

Forsiden ser undselig ud:

CI/CD i Github Actions til et projekt på Flask+Angular
I roden ligger der to filer Dockerfile og docker-compose.yml, samt en velkendt mappe .ci-cd med et lidt mindre antal scripts end i backrepositoryt (scripts til testkørsel er fjernet).

Opret projekt i Plesk

Lad os begynde med at konfigurere Plesk og oprette et abonnement til vores website.

Installation af udvidelser

I Plesk har vi brug for fire udvidelser:

  • Docker til at administrere og visuelt vise tilstanden af containere i Plesk adminpanelet;
  • Git til at konfigurere deployment-trinene på serveren;
  • Let's Encrypt til generering (og automatisk forlængelse) af gratis TLS-certifikater;
  • Firewall til konfiguration af filter for indkommende trafik.

De kan installeres gennem Plesk adminpanelet under Udvidelser:

CI/CD i Github Actions til et projekt på Flask+Angular
Vi vil ikke gennemgå detaljerne ved installationen af udvidelserne; de standardindstillinger, vi får, er tilstrækkelige til vores demoformål.

Oprettelse af abonnement og hjemmeside

Dernæst skal vi oprette et abonnement til vores hjemmeside helloworld.ru og tilføje underdomænet dev.helloworld.ru.

  1. Vi opretter abonnementet for domænet helloworld.ru og angiver login-adgangskode for systembrugeren:

    CI/CD i Github Actions til et projekt på Flask+Angular
    Nederst på siden sætter vi et flueben Secure the domain with Let’s Encrypt, hvis vi ønsker at konfigurere HTTPS til vores hjemmeside:

    CI/CD i Github Actions til et projekt på Flask+Angular

  2. Dernæst opretter vi underdomænet dev.helloworld.ru i dette abonnement (for hvilket der også kan udstedes et gratis TLS-certifikat):

    CI/CD i Github Actions til et projekt på Flask+Angular

Installation af serverkomponenter

Vi har en server med OS Debian Stretch 9.12 og den installerede kontrolpanel Plesk Obsidian 18.0.27.

Vi skal installere og konfigurere følgende til vores projekt:

  • PostgreSQL (i vores tilfælde vil der være én server med to databaser til dev- og prod-miljøet).
  • RabbitMQ (samme princip, en instans med forskellige vhosts til miljøer).
  • To instanser af Redis (til dev- og prod-miljø).
  • Docker Registry (til lokal lagring af bygget Docker-images).
  • UI-interface til Docker registry.

PostgreSQL

Med Plesk følger en PostgreSQL-database, men ikke den nyeste version (på tidspunktet for skrivning understøttede Plesk Obsidian Postgres versioner 8.4–10.8). Vi ønsker dog den nyeste version (12.3 på tidspunktet for skrivningen), så vi vil installere den manuelt. Der er mange detaljerede instruktioner til installation af Postgres på Debian online (

), så jeg vil ikke beskrive dem i detaljer, men blot præsenterer kommandoerne:eksempel), så jeg vil ikke gå i detaljer om dem, jeg vil blot give kommandoerne:

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

I betragtning af, at PostgreSQL har ret middelmådige standardindstillinger, er det vigtigt at justere konfigurationen. Dette vil hjælpe os med beregner: du skal indtaste dine servers parametre og erstatte indstillingerne i filen /etc/postgresql/12/main/postgresql.confmed de foreslåede. Her skal det nævnes, at sådanne kalkulatorer ikke er en magisk løsning, og databasen bør justeres mere præcist baseret på dit hardware, applikationer og kompleksiteten af forespørgsler. Men til en start er dette tilstrækkeligt.

Udover de foreslåede indstillinger fra kalkulatoren ændrer vi også i postgresql.confden standardport 5432 til en anden (i vores eksempel — 53983).

Efter ændringen af konfigurationsfilen genstarter vi postgresql-serveren med kommandoen:

service postgresql restart

Vi har installeret og konfigureret PostgreSQL. Nu opretter vi databaser, brugere til dev- og prod-miljøer, og giver brugerne rettigheder til at administrere 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

Lad os gå videre til installationen af RabbitMQ — beskedbroker til Celery. Det installeres temmelig let 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 skal vi oprette vhosts, brugere og tildele de nødvendige rettigheder:

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 skal vi installere og konfigurere den sidste komponent til vores applikation — Redis. Den vil blive brugt som backend til opbevaring af resultaterne fra Celery-opgaver.

Vi vil opsætte to Docker-containere med Redis til dev- og prod-miljøer ved hjælp af udvidelsen Docker til Plesk.

  1. Vi går ind i Plesk, navigerer til sektionen Udvidelser, søger efter udvidelsen Docker og installerer den (vi har brug for den gratis version):

    CI/CD i Github Actions til et projekt på Flask+Angular

  2. Vi går til den installerede udvidelse, finder via søgning billedet redis bitnami og installerer den nyeste version:

    CI/CD i Github Actions til et projekt på Flask+Angular

  3. Vi går ind i den downloadede container og justerer konfigurationen: angiver port, maksimal tildelt RAM, adgangskoden i miljøvariablerne, og monterer volumen:

    CI/CD i Github Actions til et projekt på Flask+Angular

  4. Udfør trin 2-3 for prod-containeren, i indstillingerne ændrer vi kun parametrene: port, adgangskode, ram størrelse og stien til mappingsmappen på serveren:

    CI/CD i Github Actions til et projekt på Flask+Angular

Docker Registry

Udover de grundlæggende tjenester ville det være godt at have et eget Docker-billede repository på serveren. Heldigvis er pladsen på servere nu rimeligt billig (meget billigere end et abonnement på DockerHub), og processen med at installere et privat repository er meget enkel.

Vi ønsker, at vi har installeret:

For dette:

  1. Vi opretter to subdomæner i vores Plesk-abonnement: docker.helloworld.ru og docker-ui.helloworld.ru, og konfigurerer certifikaterne fra Let’s Encrypt for dem.
  2. I mappen for subdomænet docker.helloworld.ru tilføjer vi filen docker-compose.yml med følgende indhold:
    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. Via SSH genererer vi .htpasswd-filen til Basic-godkendelse i Docker-repositoryet:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Vi bygger og starter containerne:
    docker-compose up -d
  5. Og vi skal omdirigere Nginx til vores containere. Dette kan gøres via Plesk.

De følgende handlinger skal udføres for subdomænerne docker.helloworld.ru og docker-ui.helloworld.ru:

I sektionen Dev Tools går ind under vores websted på Docker Proxy Rules:

CI/CD i Github Actions til et projekt på Flask+Angular
Og vi tilføjer en regel for at proxy indgående trafik til vores container:

CI/CD i Github Actions til et projekt på Flask+Angular

  1. Vi tjekker, at vi kan logge ind i vores container fra den lokale maskine:
    $ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password
    ADVARSEL! Brug af --password via CLI er usikkert. Brug --password-stdin.
    Login lykkedes
  2. Vi tjekker også funktionen af subdomænet docker-ui.helloworld.ru:

    CI/CD i Github Actions til et projekt på Flask+Angular
    Når du klikker på Browse repositories, viser browseren et vindue til godkendelse, hvor du skal indtaste brugernavn og adgangskode til repository'et. Derefter bliver du omdirigeret til siden med listen over repositories (den vil være tom for dig indtil videre):

    CI/CD i Github Actions til et projekt på Flask+Angular

Åbn porte i Plesk Firewall

Efter installation og opsætning af komponenter skal vi åbne porte, så komponenterne kan tilgås fra Docker-containere og det eksterne netværk.

Lad os se, hvordan det gøres med eksemplet på den firewall-udvidelse, vi tidligere installerede til Plesk.

  1. Vi går til Tools & Settings > Settings > Firewall:
    CI/CD i Github Actions til et projekt på Flask+Angular
  2. Vi går til Modificer Plesk Firewall-regler > Tilføj brugerdefineret regel og åbner de følgende TCP-porte for Docker-subnettet (172.0.0.0/8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD i Github Actions til et projekt på Flask+Angular

  3. Vi tilføjer også en regel, der åbner PostgreSQL-porte og managementpanelet for RabbitMQ for verden:

    CI/CD i Github Actions til et projekt på Flask+Angular

  4. Anvend reglerne ved at klikke på knappen Apply Changes:

    CI/CD i Github Actions til et projekt på Flask+Angular

Opsætning af CI/CD i Github Actions

Lad os gå til den mest interessante del - opsætningen af pipeline for kontinuerlig integration og deployment af vores projekt til serveren.

Denne pipeline vil bestå af to dele:

  • opbygning af billedet og kørsel af tests (for backend) - på GitHub-siden;
  • kørsel af migrationer (for backend) og deployment af containere - på serveren.

Deployment i Plesk

Lad os først kigge på den anden del (da den afhænger af den første).

Vi vil opsætte deployments gennem Git-udvidelsen til Plesk.

Lad os tage et eksempel med Prod-miljøet for Backend repository.

  1. Gå ind i vores Helloworld-websites abonnement og klik på Git-delen:

    CI/CD i Github Actions til et projekt på Flask+Angular

  2. Indsæt linket til vores GitHub-repository i feltet "Remote Git repository" og ændr standardmappen httpdocs til en anden (for eksempel, /httpdocs/hw_back):

    CI/CD i Github Actions til et projekt på Flask+Angular

  3. Kopier SSH Public key fra det forrige trin og tilføj den i indstillingerne for GitHub.
  4. Klik på OK på skærmen i punkt 2, hvorefter du bliver sendt til repository-siden i Plesk. Nu skal vi opsætte opdateringen af repository'et ved commits til master-grenen. For dette skal vi gå til Repository Settings og gemme værdien Webhook URL (vi får brug for den senere ved opsætningen af Github Actions):

    CI/CD i Github Actions til et projekt på Flask+Angular

  5. I Actions-feltet på skærmen fra det forrige punkt indtaster vi scriptet til at starte deployment:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    hvor:

    {REPOSITORY_ABSOLUTE_PATH} — stien til mappen for prod backend-repository på serveren;
    {ENV} — miljø (dev/prod), i vores tilfælde prod;
    {DOCKER_REGISTRY_HOST} — host til vores docker-repository
    {TG_BOT_TOKEN} — token for Telegram-bot;
    {TG_CHAT_ID} — ID for chat/kanal til at sende meddelelser.

    Eksempel på script:

    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. Vi tilføjer brugeren fra vores abonnement til Docker-gruppen (så han kan administrere containere):
    sudo usermod -aG docker helloworld_admin

Udviklingsmiljøet for backend-repositoriet og frontend konfigureres på samme måde.

Deploy-pipeline i Github Actions

Lad os gå videre til indstillingen af den første del af vores CI/CD-pipeline i Github Actions.

Backend

Pipelinen beskrives i filen deploy.yml.

Men før vi går i gang med det, skal vi udfylde de nødvendige Secret-variabler i Github. Gå til Indstillinger -> Hemmeligheder:

  • DOCKER_REGISTRY — værten for vores Docker-repository (docker.helloworld.ru);
  • DOCKER_LOGIN — login til Docker-repository;
  • DOCKER_PASSWORD — password til det;
  • DEPLOY_HOST — værten, hvor Plesk-administrationen er tilgængelig (f.eks.: helloworld.ru:8443 eller 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN — token til deployment i prod-repositoriet på serveren (vi fik det i Udrulning i Plesk punkt 4);
  • DEPLOY_BACK_DEV_TOKEN — token til deployment i dev-repositoriet på serveren.

Deploy-processen er enkel og består af tre hovedtrin:

  • opbygning og publicering af billedet i vores repository;
  • kørsel af tests i containeren baseret på det nyopbyggede billede;
  • udrulning til det relevante miljø afhængigt af grenen (dev/master).

Frontend

Filen deploy.yml for frontend-repositoriet adskiller sig ikke meget fra backend-versionen. Den mangler trin til kørsel af tests, og navneændringerne for tokens til deployment. Hemmelighederne for frontend-repositoriet skal desuden udfyldes separat.

Indstilling af webstedet

Proxiering af trafik gennem Nginx

Så er vi ved vejs ende. Det er kun tilbage at indstille proxiering af indkommende og udgående trafik i vores container gennem Nginx. Denne proces har vi allerede set på i punkt 5 i konfigurationen af Docker Registry. Det samme skal gentages for backend- og frontend-delen i dev- og prod-miljøerne.

Jeg viser skærmbilleder af indstillingerne.

Backend

CI/CD i Github Actions til et projekt på Flask+Angular

Frontend

CI/CD i Github Actions til et projekt på Flask+Angular
Vigtigt præciseret. I frontend-containeren vil alle URL'er, undtagen dem der starter med /api/ — blive proxieret til backend-containeren (derfor skal alle håndterere i backend-containeren begynde med /api/).

Resumé

Nu skal vores websted være tilgængeligt på adresserne helloworld.ru og dev.helloworld.ru (henholdsvis prod- og dev-miljø).

Vi har lært, hvordan man forbereder en simpel applikation på Flask og Angular, og hvordan man indstiller en pipeline i Github Actions til at udrulle den på en server, der styres af Plesk.

Jeg gentager links til repositoryerne med koden: backend, frontend.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster