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.
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.
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:
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:
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.
Opprett et abonnement for helloworld.ru-domenet og spesifiser innloggingspassordet for systembrukeren:
Kryss av i boksen nederst på siden Sikre domenet med Let's Encrypthvis vi ønsker å sette opp HTTPS for nettstedet:
Deretter, i dette abonnementet, oppretter du et underdomene dev.helloworld.ru (som du også kan utstede et gratis TLS-sertifikat for):
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:
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:
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.
Vi går til Plesk, går til Extensions-delen, ser etter Docker-utvidelsen og installerer den (vi trenger en gratisversjon):
Gå til den installerte utvidelsen, finn bildet gjennom søket redis bitnami og installer den nyeste versjonen:
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:
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:
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.
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.
Legg til filen i underdomene mappen docker.helloworld.ru docker-compose.yml med innhold som dette:
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:
Og legg til en regel for innkommende trafikk som proxy til containeren vår:
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
La oss også sjekke driften av underdomenet docker-ui.helloworld.ru:
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):
Å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.
Gå til Verktøy og innstillinger > Innstillinger > Brannmur:
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
Vi vil også legge til en regel som vil åpne PostgreSQL-porter og RabbitMQ-administrasjonspaneler til omverdenen:
Bruk reglene ved å bruke knappen Bruk endringer:
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.
Vi går til abonnementet på Helloworld-nettstedet vårt og går til Git-underseksjonen:
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):
Kopier den offentlige SSH-nøkkelen fra forrige trinn og legge det er i Github-innstillingene.
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):
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
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.
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
Frontend
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.