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

CI/CD i Github Actions til et Flask+Angular-projekt
I denne artikel vil jeg dele min erfaring med at opsætte CI/CD ved hjælp af Plesk Kontrolpanel og Github Actions. I dag vil vi lære, hvordan man implementerer et simpelt projekt med det ukomplicerede navn "Helloworld". Det er skrevet i Flask Python-rammen med Selleri-arbejdere og en Angular 8-frontend.

Links til repositories: bagende, frontend.

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

I den tredje del vil vi endelig finde ud af, hvordan man opsætter en pipeline til at implementere vores projekt til en server i et udvikler- og prod-miljø. Og så starter vi siden på serveren.

Og ja, jeg glemte at præsentere mig selv. Mit navn er Oleg Borzov, jeg er fuldstackudvikler i CRM-teamet for realkreditforvaltere hos Domclick.

Projektoversigt

Lad os først se på to projektlagre - backend og front - og gennemgå koden.

Backend: Flaske+Selleri

Til den bagerste del tog jeg en flok, der er ret populær blandt Python-udviklere: Flask-rammeværket (til API'en) og Selleri (til opgavekøen). SQLAchemy bruges som ORM. Alembic bruges til migrationer. Til JSON-validering i håndtag - Marshmallow.

В depoter der er en Readme.md-fil med en detaljeret beskrivelse af strukturen og instruktioner til at køre projektet.

Web Part API ret ukompliceret, består af 6 penne:

  • /ping - at kontrollere tilgængelighed;
  • håndterer registrering, autorisation, de-autorisation og opnåelse af en autoriseret bruger;
  • et e-mail-håndtag, der sætter en opgave i Selleri-køen.

Selleri del endnu nemmere er der kun ét problem send_mail_task.

I mappe /konf der er to undermapper:

  • docker med to dockerfiler (base.dockerfile at opbygge et sjældent skiftende basisbillede og Dockerfile til hovedenheder);
  • .env_files - med filer med miljøvariabler til forskellige miljøer.

Der er fire docker-compose-filer i roden af ​​projektet:

  • docker-compose.local.db.yml at oprette en lokal database til udvikling;
  • docker-compose.local.workers.yml til lokal opdragelse af arbejderen, databasen, Redis og RabbitMQ;
  • docker-compose.test.yml at køre test under implementering;
  • docker-compose.yml til indsættelse.

Og den sidste folder vi er interesserede i - .ci-cd. Den indeholder shell-scripts til implementering:

  • deploy.sh — lancering af migrering og implementering. Kører på serveren efter opbygning og kørsel af test i Github Actions;
  • rollback.sh - tilbagerulning af containere til den tidligere version af samlingen;
  • curl_tg.sh - afsendelse af implementeringsmeddelelser til Telegram.

Frontend på Angular

Depot med front meget enklere end Becks. Forsiden består af tre sider:

  • Hovedside med en formular til afsendelse af e-mail og en exit-knap.
  • Login side.
  • Tilmeldingsside.

Hovedsiden ser asketisk ud:

CI/CD i Github Actions til et Flask+Angular-projekt
Der er to filer ved roden Dockerfile и docker-compose.yml, samt den velkendte mappe .ci-cd med lidt færre scripts end i baglageret (fjernede scripts til at køre test).

Starter et projekt i Plesk

Lad os starte med at konfigurere Plesk og oprette et abonnement til vores side.

Installation af udvidelser

I Plesk har vi brug for fire udvidelser:

  • Docker at administrere og visuelt vise status for containere i Plesks administrationspanel;
  • Git at konfigurere implementeringstrinnet på serveren;
  • Let's Encrypt at generere (og automatisk forny) gratis TLS-certifikater;
  • Firewall at konfigurere filtrering af indgående trafik.

Du kan installere dem via Plesks administrationspanel i sektionen Udvidelser:

CI/CD i Github Actions til et Flask+Angular-projekt
Vi vil ikke overveje detaljerede indstillinger for udvidelser, standardindstillingerne vil gøre det til vores demoformål.

Opret et abonnement og et websted

Dernæst skal vi oprette et abonnement på vores helloworld.ru-websted og tilføje dev.helloworld.ru-underdomænet der.

  1. Opret et abonnement for domænet helloworld.ru og angiv login-adgangskoden for systembrugeren:

    CI/CD i Github Actions til et Flask+Angular-projekt
    Sæt kryds i feltet nederst på siden Sikre domænet med Let's Encrypthvis vi ønsker at konfigurere HTTPS for webstedet:

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

  2. I dette abonnement skal du derefter oprette et underdomæne dev.helloworld.ru (som du også kan udstede et gratis TLS-certifikat til):

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

Installation af serverkomponenter

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

Vi skal installere og konfigurere til vores projekt:

  • PostgreSQL (i vores tilfælde vil der være én server med to databaser til dev- og prod-miljøer).
  • RabbitMQ (samme, samme instans med forskellige vhosts for miljøer).
  • To Redis-forekomster (til dev- og prod-miljøer).
  • Docker Registry (til lokal lagring af indbyggede Docker-billeder).
  • UI til Docker registry.

PostgreSQL

Plesk kommer allerede med PostgreSQL DBMS, men ikke den nyeste version (i skrivende stund Plesk Obsidian understøttes Postgres versioner 8.4–10.8). Vi ønsker den seneste version til vores applikation (12.3 på tidspunktet for dette skrivende), så vi installerer det manuelt.

Der er en masse detaljerede instruktioner til installation af Postgres på Debian på nettet (eksempel), så jeg vil ikke beskrive dem i detaljer, jeg vil bare 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 nødvendigt at rette konfigurationen. Dette vil hjælpe os lommeregner: du skal køre i parametrene på din server og erstatte indstillingerne i filen /etc/postgresql/12/main/postgresql.conftil de tilbudte. Det skal bemærkes her, at sådanne lommeregnere ikke er en magisk kugle, og basen bør indstilles mere præcist baseret på din hardware, applikation og forespørgselskompleksitet. Men dette er nok til at komme i gang.

Ud over de indstillinger, som beregneren foreslår, ændrer vi også ind postgresql.confstandardporten 5432 til en anden (i vores eksempel - 53983).

Efter at have ændret konfigurationsfilen, genstart postgresql-server med kommandoen:

service postgresql restart

Vi har installeret og konfigureret PostgreSQL. Lad os nu oprette en database, brugere til dev- og prod-miljøer og give brugere 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 at installere RabbitMQ, en meddelelsesmægler for Selleri. Det er ret simpelt at installere det 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 give 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 ".*" ".*" ".*"

Omfor

Lad os nu installere og konfigurere den sidste komponent til vores applikation - Redis. Det vil blive brugt som en backend til lagring af resultaterne af selleri-opgaver.

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

  1. Vi går til Plesk, går til sektionen Udvidelser, ser efter Docker-udvidelsen og installerer den (vi har brug for en gratis version):

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

  2. Gå til den installerede udvidelse, find billedet gennem søgningen redis bitnami og installer den nyeste version:

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

  3. Vi går ind i den downloadede container og justerer konfigurationen: angiv porten, den maksimale tildelte RAM-størrelse, adgangskoden i miljøvariablerne, og monter volumen:

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

  4. Vi udfører trin 2-3 for prod-beholderen, i indstillingerne ændrer vi kun parametrene: port, adgangskode, RAM-størrelse og sti til volumenmappen på serveren:

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

Docker Registry

Ud over grundlæggende tjenester ville det være rart at lægge dit eget Docker-billedlager på serveren. Heldigvis er serverplads nu ret billig (sikkert billigere end et DockerHub-abonnement), og processen med at oprette et privat depot er meget enkel.

Vi ønsker at have:

For at gøre dette:

  1. Lad os oprette to underdomæner i Plesk i vores abonnement: docker.helloworld.ru og docker-ui.helloworld.ru, og konfigurere Let's Encrypt-certifikater for dem.
  2. Tilføj filen til underdomænemappen docker.helloworld.ru docker-compose.yml med indhold som dette:
    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. Under SSH vil vi generere .htpasswd-filen til grundlæggende autorisation i Docker-lageret:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Saml og løft beholdere:
    docker-compose up -d
  5. Og vi skal omdirigere Nginx til vores containere. Dette kan gøres gennem Plesk.

Følgende trin skal udføres for underdomænerne docker.helloworld.ru og docker-ui.helloworld.ru:

I afsnit Dev værktøjer vores side gå til Docker proxy regler:

CI/CD i Github Actions til et Flask+Angular-projekt
Og føj en regel til proxy for indgående trafik til vores container:

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

  1. Vi tjekker, at vi kan logge på vores container fra den lokale maskine:
    $ 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. Lad os også tjekke driften af ​​docker-ui.helloworld.ru underdomænet:

    CI/CD i Github Actions til et Flask+Angular-projekt
    Når du klikker på Gennemse lagre, vil browseren vise et autorisationsvindue, hvor du skal indtaste brugernavnet og adgangskoden til lageret. Derefter vil vi blive overført til en side med en liste over depoter (i øjeblikket vil den være tom for dig):

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

Åbning af porte i Plesk Firewall

Efter installation og konfiguration af komponenterne skal vi åbne porte, så komponenterne er tilgængelige fra Docker-containere og det eksterne netværk.

Lad os se, hvordan du gør dette ved at bruge Firewall-udvidelsen til Plesk, som vi installerede tidligere.

  1. Gå til Værktøjer og indstillinger > Indstillinger > Firewall:
    CI/CD i Github Actions til et Flask+Angular-projekt
  2. Gå til Rediger Plesk Firewall-regler > Tilføj tilpasset regel og åbn følgende TCP-porte til Docker-undernettet (172.0.0.0 / 8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

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

  3. Vi tilføjer også en regel, der åbner PostgreSQL-porte og RabbitMQ-styringspaneler til omverdenen:

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

  4. Anvend reglerne ved at bruge knappen Anvend ændringer:

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

Opsætning af CI/CD i Github Actions

Lad os komme ned til den mest interessante del - opsætning af en kontinuerlig integrationspipeline og levering af vores projekt til serveren.

Denne pipeline vil bestå af to dele:

  • at bygge et billede og køre test (til backend) - på Github-siden;
  • kører migreringer (til backend) og udrulning af containere - på serveren.

Implementer til Plesk

Lad os først behandle det andet punkt (fordi det første afhænger af det).

Vi konfigurerer implementeringsprocessen ved hjælp af Git-udvidelsen til Plesk.

Overvej et eksempel med et Prod-miljø til et backend-lager.

  1. Vi går til abonnementet på vores Helloworld-websted og går til Git-underafsnittet:

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

  2. Indsæt et link til vores Github-lager i feltet "Remote Git-lager" og skift standardmappen httpdocs til en anden (f. /httpdocs/hw_back):

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

  3. Kopier SSH Public-nøglen fra det forrige trin og tilføje det er i Github-indstillingerne.
  4. Klik på OK på skærmen i trin 2, hvorefter vi bliver omdirigeret til lagersiden i Plesk. Nu skal vi konfigurere lageret til at blive opdateret på commits til mastergrenen. For at gøre dette, gå til Indstillinger for lager og gem værdien Webhook URL (vi får brug for det senere, når vi opsætter Github Actions):

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

  5. I feltet Handlinger på skærmen fra forrige afsnit skal du indtaste scriptet for at starte implementeringen:
    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} - sti til prod-mappen i backend-lageret på serveren;
    {ENV} - miljø (dev / prod), i vores tilfælde prod;
    {DOCKER_REGISTRY_HOST} - værten for vores docker-depot
    {TG_BOT_TOKEN} — Telegram bot-token;
    {TG_CHAT_ID} — ID for chatten/kanalen til afsendelse af 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. Tilføj en bruger fra vores abonnement til Docker-gruppen (så de kan administrere containere):
    sudo usermod -aG docker helloworld_admin

Dev-miljøet for backend-lageret og frontend er sat op på samme måde.

Implementeringspipeline i Github Actions

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

Bagende

Rørledningen er beskrevet i deploy.yml fil.

Men før vi analyserer det, lad os udfylde de hemmelige variabler, vi har brug for i Github. For at gøre dette, gå til Indstillinger -> Hemmeligheder:

  • DOCKER_REGISTRY - værten for vores Docker-depot (docker.helloworld.ru);
  • DOCKER_LOGIN - log ind på Docker-depotet;
  • DOCKER_PASSWORD - adgangskode til det;
  • DEPLOY_HOST — vært, hvor Plesk-administrationspanelet er tilgængeligt (eksempel: helloworld.com:8443 eller 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - et token til udrulning til prod-lageret på serveren (vi fik det i Deployment i Plesk s. 4);
  • DEPLOY_BACK_DEV_TOKEN - token til udrulning til dev-lageret på serveren.

Implementeringsprocessen er enkel og består af tre hovedtrin:

  • opbygning og publicering af billedet i vores repository;
  • køre test i en container baseret på et nybygget billede;
  • udrulning til det ønskede miljø afhængigt af grenen (dev/master).

frontend

Deploy.yml-filen til frontlageret lidt anderledes end Becks. Det mangler et trin med at køre test og ændrer navnene på tokens til implementering. Hemmeligheder til frontdepotet skal i øvrigt udfyldes separat.

Opsætning af websted

Proxytrafik gennem Nginx

Nå, vi er nået til slutningen. Det er kun tilbage at konfigurere proxying af indgående og udgående trafik til vores container gennem Nginx. Vi har allerede dækket denne proces i trin 5 af Docker Registry-opsætningen. Det samme bør gentages for de bagerste og forreste dele i dev- og prod-miljøer.

Jeg vil give skærmbilleder af indstillingerne.

Bagende

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

frontend

CI/CD i Github Actions til et Flask+Angular-projekt
Vigtig afklaring. Alle URL'er vil blive proxy til frontend-containeren, undtagen dem der starter med /api/ - de vil blive sendt til bagbeholderen (altså i bagbeholderen skal alle handlere starte med /api/).

Resultaterne af

Nu skulle vores side være tilgængelig på helloworld.ru og dev.helloworld.ru (henholdsvis prod- og dev-miljøer).

I alt lærte vi, hvordan man forbereder en simpel applikation i Flask og Angular og opsætter en pipeline i Github Actions for at rulle den ud til en server, der kører Plesk.

Jeg vil duplikere links til depoterne med koden: bagende, frontend.

Kilde: www.habr.com

Tilføj en kommentar