CI/CD i Github Actions for et Flask+Angular-prosjekt

CI/CD i Github Actions for et Flask+Angular-prosjekt
I denne artikkelen vil jeg dele min erfaring med å sette opp CI/CD ved å bruke Plesk Control Panel og Github Actions. I dag skal vi lære hvordan du distribuerer et enkelt prosjekt med det ukompliserte navnet "Helloworld". Den er skrevet i Flask Python-rammeverket, med Selleri-arbeidere og en Angular 8-frontend.

Lenker til arkiver: baksiden, frontend.

I den første delen av artikkelen skal vi se på prosjektet vårt og dets deler. I den andre vil vi finne ut hvordan du setter opp Plesk og installerer de nødvendige utvidelsene og komponentene (DB, RabbitMQ, Redis, Docker, etc.).

I den tredje delen skal vi endelig finne ut hvordan vi setter opp en pipeline for å distribuere prosjektet vårt til en server i et dev- og prod-miljø. Og så vil vi starte siden på serveren.

Og ja, jeg glemte å presentere meg selv. Mitt navn er Oleg Borzov, jeg er en fullstack-utvikler i CRM-teamet for boliglånsforvaltere hos Domclick.

Prosjektoversikt

Først, la oss se på to prosjektlagre - backend og front - og gå over koden.

Bakside: Kolbe+selleri

For baksiden tok jeg en gjeng som er ganske populær blant Python-utviklere: Flask-rammeverket (for API) og Selleri (for oppgavekøen). SQLAchemy brukes som ORM. Alembic brukes til migrasjoner. For JSON-validering i håndtak - Marshmallow.

В depoter det er en Readme.md-fil med en detaljert beskrivelse av strukturen og instruksjoner for å kjøre prosjektet.

Web Part API ganske enkelt, består av 6 penner:

  • /ping - for å sjekke tilgjengelighet;
  • håndterer for registrering, autorisasjon, avautorisering og innhenting av en autorisert bruker;
  • et e-posthåndtak som setter en oppgave i selleri-køen.

Selleri del enda enklere, det er bare ett problem send_mail_task.

I mappe /konf det er to undermapper:

  • docker med to dockerfiler (base.dockerfile å bygge et sjeldent skiftende basisbilde og Dockerfile for hovedenheter);
  • .env_files - med filer med miljøvariabler for ulike miljøer.

Det er fire docker-compose-filer i roten av prosjektet:

  • docker-compose.local.db.yml å opprette en lokal database for utvikling;
  • docker-compose.local.workers.yml for lokal heving av arbeideren, databasen, Redis og RabbitMQ;
  • docker-compose.test.yml å kjøre tester under distribusjon;
  • docker-compose.yml for utplassering.

Og den siste mappen vi er interessert i - .ci-cd. Den inneholder shell-skript for distribusjon:

  • deploy.sh — lansering av migrering og distribusjon. Kjører på serveren etter å ha bygget og kjørt tester i Github Actions;
  • rollback.sh - tilbakerulling av containere til forrige versjon av sammenstillingen;
  • curl_tg.sh - sende distribusjonsvarsler til Telegram.

Frontend på Angular

Depot med front mye enklere enn Becks. Forsiden består av tre sider:

  • Hovedside med skjema for sending av e-post og avslutningsknapp.
  • Påloggingsside.
  • Registreringsside.

Hovedsiden ser asketisk ut:

CI/CD i Github Actions for et Flask+Angular-prosjekt
Det er to filer ved roten Dockerfile и docker-compose.yml, samt den kjente mappen .ci-cd med litt færre skript enn i bakre repository (fjernede skript for å kjøre tester).

Starter et prosjekt i Plesk

La oss starte med å sette opp Plesk og opprette et abonnement for nettstedet vårt.

Installere utvidelser

I Plesk trenger vi fire utvidelser:

  • Docker å administrere og visuelt vise statusen til containere i Plesk-administrasjonspanelet;
  • Git å konfigurere distribusjonstrinnet på serveren;
  • Let's Encrypt å generere (og automatisk fornye) gratis TLS-sertifikater;
  • Firewall for å konfigurere filtrering av innkommende trafikk.

Du kan installere dem gjennom Plesk-administrasjonspanelet i utvidelsesdelen:

CI/CD i Github Actions for et Flask+Angular-prosjekt
Vi vil ikke vurdere de detaljerte innstillingene for utvidelser, standardinnstillingene vil gjøre for våre demoformål.

Opprett et abonnement og nettsted

Deretter må vi opprette et abonnement for nettstedet vårt helloworld.ru og legge til dev.helloworld.ru-underdomenet der.

  1. Opprett et abonnement for helloworld.ru-domenet og spesifiser innloggingspassordet for systembrukeren:

    CI/CD i Github Actions for et Flask+Angular-prosjekt
    Kryss av i boksen nederst på siden Sikre domenet med Let's Encrypthvis vi ønsker å sette opp HTTPS for nettstedet:

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  2. Deretter, i dette abonnementet, oppretter du et underdomene dev.helloworld.ru (som du også kan utstede et gratis TLS-sertifikat for):

    CI/CD i Github Actions for et Flask+Angular-prosjekt

Installere serverkomponenter

Vi har en server med OS Debian Stretch 9.12 og installert kontrollpanel Plesk Obsidian 18.0.27.

Vi må installere og konfigurere for prosjektet vårt:

  • PostgreSQL (i vårt tilfelle vil det være én server med to databaser for dev- og prod-miljøer).
  • RabbitMQ (samme, samme forekomst med forskjellige vhosts for miljøer).
  • To Redis-forekomster (for dev- og prod-miljøer).
  • Docker Registry (for lokal lagring av innebygde Docker-bilder).
  • UI for Docker-registeret.

PostgreSQL

Plesk kommer allerede med PostgreSQL DBMS, men ikke den nyeste versjonen (i skrivende stund Plesk Obsidian støttes Postgres versjoner 8.4–10.8). Vi ønsker den nyeste versjonen for applikasjonen vår (12.3 når dette skrives), så vi vil installere den manuelt.

Det er mange detaljerte instruksjoner for å installere Postgres på Debian på nettet (eksempel), så jeg vil ikke beskrive dem i detalj, jeg vil bare gi kommandoene:

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

Tatt i betraktning at PostgreSQL har ganske middelmådige standardinnstillinger, er det nødvendig å korrigere konfigurasjonen. Dette vil hjelpe oss kalkulator: du må kjøre inn parametrene til serveren din og erstatte innstillingene i filen /etc/postgresql/12/main/postgresql.conftil de som tilbys. Det skal bemerkes her at slike kalkulatorer ikke er en magisk kule, og basen bør justeres mer presist, basert på maskinvaren, applikasjonen og søkekompleksiteten din. Men dette er nok til å komme i gang.

I tillegg til innstillingene foreslått av kalkulatoren, endrer vi også inn postgresql.confstandardporten 5432 til en annen (i vårt eksempel - 53983).

Etter å ha endret konfigurasjonsfilen, start postgresql-server på nytt med kommandoen:

service postgresql restart

Vi har installert og konfigurert PostgreSQL. La oss nå lage en database, brukere for dev- og prod-miljøer, og gi brukere rettigheter til å 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

Kanin MQ

La oss gå videre til å installere RabbitMQ, en meldingsmegler for selleri. Å installere det på Debian er ganske enkelt:

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

Etter installasjonen må vi lage vhosts, brukere og gi de nødvendige rettighetene:

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

La oss nå installere og konfigurere den siste komponenten for applikasjonen vår - Redis. Den vil bli brukt som en backend for å lagre resultatene av sellerioppgaver.

Vi vil heve to Docker-beholdere med Redis for utviklings- og produksjonsmiljøer ved å bruke utvidelsen Docker for Plesk.

  1. Vi går til Plesk, går til Extensions-delen, ser etter Docker-utvidelsen og installerer den (vi trenger en gratisversjon):

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  2. Gå til den installerte utvidelsen, finn bildet gjennom søket redis bitnami og installer den nyeste versjonen:

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  3. Vi går inn i den nedlastede beholderen og justerer konfigurasjonen: spesifiser porten, den maksimale tildelte RAM-størrelsen, passordet i miljøvariablene, og monter volumet:

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  4. Vi utfører trinn 2-3 for prod-beholderen, i innstillingene endrer vi bare parametrene: port, passord, RAM-størrelse og bane til volummappen på serveren:

    CI/CD i Github Actions for et Flask+Angular-prosjekt

Docker-registeret

I tillegg til grunnleggende tjenester, ville det være fint å sette ditt eget Docker-bildelager på serveren. Heldigvis er serverplass nå ganske billig (sikkert billigere enn et DockerHub-abonnement), og prosessen med å sette opp et privat depot er veldig enkelt.

Vi ønsker å ha:

For å gjøre dette:

  1. La oss opprette to underdomener i Plesk i vårt abonnement: docker.helloworld.ru og docker-ui.helloworld.ru, og konfigurere Let's Encrypt-sertifikater for dem.
  2. Legg til filen i underdomene mappen docker.helloworld.ru docker-compose.yml med innhold 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 for grunnleggende autorisasjon i Docker-depotet:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Samle og løft beholdere:
    docker-compose up -d
  5. Og vi må omdirigere Nginx til containerne våre. Dette kan gjøres gjennom Plesk.

Følgende trinn må utføres for underdomenene docker.helloworld.ru og docker-ui.helloworld.ru:

I avsnitt Dev-verktøy nettstedet vårt gå til Docker proxy-regler:

CI/CD i Github Actions for et Flask+Angular-prosjekt
Og legg til en regel for innkommende trafikk som proxy til containeren vår:

CI/CD i Github Actions for et Flask+Angular-prosjekt

  1. Vi sjekker at vi kan logge på containeren vår fra den lokale 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. La oss også sjekke driften av underdomenet docker-ui.helloworld.ru:

    CI/CD i Github Actions for et Flask+Angular-prosjekt
    Når du klikker på Bla gjennom depoter, vil nettleseren vise et autorisasjonsvindu der du må angi brukernavn og passord for depotet. Etter det vil vi bli overført til en side med en liste over depoter (foreløpig vil den være tom for deg):

    CI/CD i Github Actions for et Flask+Angular-prosjekt

Åpner porter i Plesk Firewall

Etter å ha installert og konfigurert komponentene, må vi åpne porter slik at komponentene er tilgjengelige fra Docker-beholdere og det eksterne nettverket.

La oss se hvordan du gjør dette ved å bruke brannmurutvidelsen for Plesk som vi installerte tidligere.

  1. Gå til Verktøy og innstillinger > Innstillinger > Brannmur:
    CI/CD i Github Actions for et Flask+Angular-prosjekt
  2. Gå til Endre Plesk-brannmurregler > Legg til egendefinert regel og åpne følgende TCP-porter for Docker-undernettet (172.0.0.0 / 8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  3. Vi vil også legge til en regel som vil åpne PostgreSQL-porter og RabbitMQ-administrasjonspaneler til omverdenen:

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  4. Bruk reglene ved å bruke knappen Bruk endringer:

    CI/CD i Github Actions for et Flask+Angular-prosjekt

Sette opp CI/CD i Github Actions

La oss komme ned til den mest interessante delen - å sette opp en kontinuerlig integrasjonspipeline og levere prosjektet vårt til serveren.

Denne rørledningen vil bestå av to deler:

  • bygge et bilde og kjøre tester (for backend) - på Github-siden;
  • kjører migreringer (for backend) og distribuerer containere - på serveren.

Distribuer til Plesk

La oss ta for oss det andre punktet først (fordi det første avhenger av det).

Vi vil konfigurere distribusjonsprosessen ved å bruke Git-utvidelsen for Plesk.

Tenk på et eksempel med et Prod-miljø for et Backend-depot.

  1. Vi går til abonnementet på Helloworld-nettstedet vårt og går til Git-underseksjonen:

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  2. Sett inn en lenke til Github-depotet vårt i "Remote Git-repository"-feltet og endre standardmappen httpdocs til en annen (f. /httpdocs/hw_back):

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  3. Kopier den offentlige SSH-nøkkelen fra forrige trinn og legge det er i Github-innstillingene.
  4. Klikk OK på skjermen i trinn 2, hvoretter vi blir omdirigert til repository-siden i Plesk. Nå må vi konfigurere depotet til å oppdateres på commits til hovedgrenen. For å gjøre dette, gå til Lagringsinnstillinger og lagre verdien Webhook URL (vi trenger det senere når vi setter opp Github Actions):

    CI/CD i Github Actions for et Flask+Angular-prosjekt

  5. I Handlinger-feltet på skjermen fra forrige avsnitt skriver du inn skriptet for å starte distribusjonen:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    der:

    {REPOSITORY_ABSOLUTE_PATH} - bane til prod-mappen til backend-depotet på serveren;
    {ENV} - miljø (dev / prod), i vårt tilfelle prod;
    {DOCKER_REGISTRY_HOST} - verten for vårt docker-lager
    {TG_BOT_TOKEN} — Telegram bot-token;
    {TG_CHAT_ID} — ID for chatten/kanalen for å sende varsler.

    Skripteksempel:

    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. Legg til en bruker fra vårt abonnement til Docker-gruppen (slik at de kan administrere containere):
    sudo usermod -aG docker helloworld_admin

Utviklermiljøet for backend-depotet og frontend er satt opp på samme måte.

Implementeringspipeline i Github Actions

La oss gå videre til å sette opp den første delen av vår CI/CD-pipeline i Github Actions.

Backend

Rørledningen er beskrevet i deploy.yml-filen.

Men før vi analyserer det, la oss fylle ut de hemmelige variablene vi trenger i Github. For å gjøre dette, gå til Innstillinger -> Hemmeligheter:

  • DOCKER_REGISTRY - verten for Docker-depotet vårt (docker.helloworld.ru);
  • DOCKER_LOGIN - logg inn på Docker-depotet;
  • DOCKER_PASSWORD - passord til det;
  • DEPLOY_HOST — vert der Plesk-administrasjonspanelet er tilgjengelig (eksempel: helloworld.com: 8443 eller 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - et token for distribusjon til prod-repository på serveren (vi fikk det i Deployment in Plesk s. 4);
  • DEPLOY_BACK_DEV_TOKEN - token for distribusjon til dev-lageret på serveren.

Implementeringsprosessen er enkel og består av tre hovedtrinn:

  • bygge og publisere bildet i vårt depot;
  • kjører tester i en beholder basert på et nybygd bilde;
  • distribusjon til ønsket miljø avhengig av grenen (dev/master).

Frontend

Deploy.yml-filen for frontlageret litt annerledes enn Becks. Den mangler et trinn med å kjøre tester og endrer navnene på tokens for distribusjon. Hemmeligheter for frontdepotet må forresten fylles ut separat.

Nettstedsoppsett

Proxy-trafikk gjennom Nginx

Vel, vi har kommet til slutten. Det gjenstår bare å konfigurere proxying av innkommende og utgående trafikk til containeren vår gjennom Nginx. Vi har allerede dekket denne prosessen i trinn 5 av Docker Registry-oppsettet. Det samme bør gjentas for bak- og frontdelene i dev- og prod-miljøer.

Jeg vil gi skjermbilder av innstillingene.

Backend

CI/CD i Github Actions for et Flask+Angular-prosjekt

Frontend

CI/CD i Github Actions for et Flask+Angular-prosjekt
Viktig avklaring. Alle nettadresser vil bli proksert til frontend-beholderen, bortsett fra de som begynner med /api/ - de vil bli sendt til den bakre beholderen (så i bakbeholderen skal alle behandlere starte med /api/).

Resultater av

Nå skal nettstedet vårt være tilgjengelig på helloworld.ru og dev.helloworld.ru (henholdsvis prod- og dev-miljøer).

Totalt lærte vi å klargjøre en enkel applikasjon i Flask og Angular og sette opp en pipeline i Github Actions for å rulle den ut til en server som kjører Plesk.

Jeg vil duplisere lenkene til depotene med koden: baksiden, frontend.

Kilde: www.habr.com

Legg til en kommentar