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.
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.
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:
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:
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.
Opret et abonnement for domænet helloworld.ru og angiv login-adgangskoden for systembrugeren:
Sæt kryds i feltet nederst på siden Sikre domænet med Let's Encrypthvis vi ønsker at konfigurere HTTPS for webstedet:
I dette abonnement skal du derefter oprette et underdomæne dev.helloworld.ru (som du også kan udstede et gratis TLS-certifikat til):
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:
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:
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.
Vi går til Plesk, går til sektionen Udvidelser, ser efter Docker-udvidelsen og installerer den (vi har brug for en gratis version):
Gå til den installerede udvidelse, find billedet gennem søgningen redis bitnami og installer den nyeste version:
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:
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:
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.
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.
Tilføj filen til underdomænemappen docker.helloworld.ru docker-compose.yml med indhold som dette:
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:
Og føj en regel til proxy for indgående trafik til vores container:
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
Lad os også tjekke driften af docker-ui.helloworld.ru underdomænet:
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):
Å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.
Gå til Værktøjer og indstillinger > Indstillinger > Firewall:
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
Vi tilføjer også en regel, der åbner PostgreSQL-porte og RabbitMQ-styringspaneler til omverdenen:
Anvend reglerne ved at bruge knappen Anvend ændringer:
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.
Vi går til abonnementet på vores Helloworld-websted og går til Git-underafsnittet:
Indsæt et link til vores Github-lager i feltet "Remote Git-lager" og skift standardmappen httpdocs til en anden (f. /httpdocs/hw_back):
Kopier SSH Public-nøglen fra det forrige trin og tilføje det er i Github-indstillingerne.
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):
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
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.
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
frontend
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.