CI/CD in Github-acties voor een Flask+Angular-project

CI/CD in Github-acties voor een Flask+Angular-project
In dit artikel deel ik mijn ervaring met het instellen van CI/CD met behulp van het Plesk-configuratiescherm en Github Actions. Vandaag zullen we leren hoe we een eenvoudig project kunnen implementeren met de ongecompliceerde naam "Helloworld". Het is geschreven in het Flask Python-framework, met Celery-werkers en een Angular 8-frontend.

Links naar opslagplaatsen: back-end, voorkant.

In het eerste deel van het artikel zullen we ons project en zijn onderdelen bekijken. In de tweede zullen we uitzoeken hoe Plesk moet worden ingesteld en de benodigde extensies en componenten moeten worden geïnstalleerd (DB, RabbitMQ, Redis, Docker, enz.).

In het derde deel zullen we eindelijk uitzoeken hoe we een pijplijn kunnen opzetten voor het implementeren van ons project op een server in een dev- en prod-omgeving. En dan lanceren we de site op de server.

En ja, ik vergat mezelf voor te stellen. Mijn naam is Oleg Borzov, ik ben een fullstack ontwikkelaar in het CRM-team voor hypotheekmanagers bij Domclick.

Projectoverzicht

Laten we eerst eens kijken naar twee projectrepository's - backend en front - en de code doornemen.

Backend: Flask+Selderij

Voor het achterste gedeelte heb ik een aantal genomen dat behoorlijk populair is onder Python-ontwikkelaars: het Flask-framework (voor de API) en Celery (voor de taakwachtrij). SQLAchemy wordt gebruikt als ORM. Alambic wordt gebruikt voor migraties. Voor JSON-validatie in handgrepen - Marshmallow.

В opslagplaatsen er is een Readme.md-bestand met een gedetailleerde beschrijving van de structuur en instructies voor het uitvoeren van het project.

Webonderdeel-API vrij ongecompliceerd, bestaat uit 6 pennen:

  • /ping - beschikbaarheid controleren;
  • handvatten voor registratie, autorisatie, de-autorisatie en het verkrijgen van een geautoriseerde gebruiker;
  • een e-mailhandle die een taak in de wachtrij van Celery plaatst.

Selderij gedeelte nog eenvoudiger, er is maar één probleem send_mail_task.

In map /conf er zijn twee submappen:

  • docker met twee Dockerfiles (base.dockerfile om een ​​zelden veranderend basisbeeld op te bouwen en Dockerfile voor hoofdsamenstellingen);
  • .env_files - met bestanden met omgevingsvariabelen voor verschillende omgevingen.

Er zijn vier docker-compose-bestanden in de hoofdmap van het project:

  • docker-compose.local.db.yml een lokale database opzetten voor ontwikkeling;
  • docker-compose.local.workers.yml voor lokale opvoeding van de werknemer, database, Redis en RabbitMQ;
  • docker-compose.test.yml om tests uit te voeren tijdens de implementatie;
  • docker-compose.yml voor inzet.

En de laatste map waarin we geïnteresseerd zijn - .ci-cd. Het bevat shell-scripts voor implementatie:

  • deploy.sh — lancering van migratie en implementatie. Draait op de server na het bouwen en uitvoeren van tests in Github Actions;
  • rollback.sh - rollback van containers naar de vorige versie van de assembly;
  • curl_tg.sh - het verzenden van implementatiemeldingen naar Telegram.

Frontend op Angular

Opslagplaats met voorkant veel eenvoudiger dan die van Beck. De voorkant bestaat uit drie pagina's:

  • Hoofdpagina met een formulier voor het verzenden van e-mail en een exit-knop.
  • Login pagina.
  • Registratie pagina.

De hoofdpagina ziet er ascetisch uit:

CI/CD in Github-acties voor een Flask+Angular-project
Er zijn twee bestanden in de root Dockerfile и docker-compose.yml, evenals de vertrouwde map .ci-cd met iets minder scripts dan in de back-repository (verwijderde scripts voor het uitvoeren van tests).

Een project starten in Plesk

Laten we beginnen met het opzetten van Plesk en het aanmaken van een abonnement voor onze site.

Extensies installeren

In Plesk hebben we vier extensies nodig:

  • Docker om de status van containers te beheren en visueel weer te geven in het Plesk-beheerderspaneel;
  • Git om de implementatiestap op de server te configureren;
  • Let's Encrypt om gratis TLS-certificaten te genereren (en automatisch te verlengen);
  • Firewall om het filteren van inkomend verkeer te configureren.

U kunt ze installeren via het Plesk-beheerderspaneel in het gedeelte Extensies:

CI/CD in Github-acties voor een Flask+Angular-project
We houden geen rekening met de gedetailleerde instellingen voor extensies, de standaardinstellingen zijn voldoende voor onze demodoeleinden.

Maak een abonnement en site aan

Vervolgens moeten we een abonnement maken voor onze helloworld.ru-website en daar het dev.helloworld.ru-subdomein toevoegen.

  1. Maak een abonnement aan voor het domein helloworld.ru en specificeer het inlogwachtwoord voor de systeemgebruiker:

    CI/CD in Github-acties voor een Flask+Angular-project
    Vink het vakje onderaan de pagina aan Beveilig het domein met Let's Encryptals we HTTPS voor de site willen instellen:

    CI/CD in Github-acties voor een Flask+Angular-project

  2. Maak vervolgens in dit abonnement een subdomein dev.helloworld.ru aan (waarvoor u ook een gratis TLS-certificaat kunt uitgeven):

    CI/CD in Github-acties voor een Flask+Angular-project

Servercomponenten installeren

We hebben een server met Besturingssysteem Debian Stretch 9.12 en geïnstalleerd bedieningspaneel Plesk Obsidiaan 18.0.27.

We moeten installeren en configureren voor ons project:

  • PostgreSQL (in ons geval is er één server met twee databases voor dev- en prod-omgevingen).
  • RabbitMQ (dezelfde, dezelfde instantie met verschillende vhosts voor omgevingen).
  • Twee Redis-instanties (voor dev- en prod-omgevingen).
  • Docker Registry (voor lokale opslag van ingebouwde Docker-images).
  • UI voor Docker-register.

PostgreSQL

Plesk wordt al geleverd met PostgreSQL DBMS, maar niet de nieuwste versie (op het moment van schrijven Plesk Obsidian ondersteund Postgres-versies 8.4–10.8). We willen de nieuwste versie voor onze applicatie (12.3 op het moment van schrijven), dus we zullen deze handmatig installeren.

Er zijn veel gedetailleerde instructies voor het installeren van Postgres op Debian op het net (voorbeeld), dus ik zal ze niet in detail beschrijven, ik zal alleen de commando's geven:

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

Aangezien PostgreSQL nogal middelmatige standaardinstellingen heeft, is het noodzakelijk om de configuratie te corrigeren. Dit zal ons helpen rekenmachine: u moet de parameters van uw server invoeren en de instellingen in het bestand vervangen /etc/postgresql/12/main/postgresql.confaan die aangeboden. Hierbij moet worden opgemerkt dat dergelijke rekenmachines geen wondermiddel zijn en dat de basis nauwkeuriger moet worden afgestemd op basis van uw hardware, toepassing en complexiteit van de zoekopdracht. Maar dit is genoeg om te beginnen.

Naast de instellingen voorgesteld door de rekenmachine, veranderen we ook in postgresql.confde standaardpoort 5432 naar een andere (in ons voorbeeld - 53983).

Herstart postgresql-server na het wijzigen van het configuratiebestand met de opdracht:

service postgresql restart

We hebben PostgreSQL geïnstalleerd en geconfigureerd. Laten we nu een database maken, gebruikers voor dev- en prod-omgevingen, en gebruikers rechten geven om de database te beheren:

$ 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

Laten we verder gaan met het installeren van RabbitMQ, een berichtenmakelaar voor Celery. Het installeren op Debian is vrij eenvoudig:

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

Na de installatie moeten we creëren vhosts, gebruikers en verleen de nodige rechten:

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

Laten we nu het laatste onderdeel voor onze applicatie installeren en configureren - Redis. Het zal worden gebruikt als een backend voor het opslaan van de resultaten van Celery-taken.

We zullen twee Docker-containers verhogen met Redis voor dev- en prod-omgevingen met behulp van de extensie Docker voor Plesk.

  1. We gaan naar Plesk, gaan naar het gedeelte Extensies, zoeken naar de Docker-extensie en installeren deze (we hebben een gratis versie nodig):

    CI/CD in Github-acties voor een Flask+Angular-project

  2. Ga naar de geïnstalleerde extensie, zoek de afbeelding via de zoekopdracht redis bitnami en installeer de laatste versie:

    CI/CD in Github-acties voor een Flask+Angular-project

  3. We gaan naar de gedownloade container en passen de configuratie aan: specificeer de poort, de maximale toegewezen RAM-grootte, het wachtwoord in de omgevingsvariabelen en koppel het volume:

    CI/CD in Github-acties voor een Flask+Angular-project

  4. We voeren stappen 2-3 uit voor de prod-container, in de instellingen wijzigen we alleen de parameters: poort, wachtwoord, RAM-grootte en pad naar de volumemap op de server:

    CI/CD in Github-acties voor een Flask+Angular-project

Docker-register

Naast de basisdiensten zou het fijn zijn om je eigen Docker image repository op de server te zetten. Gelukkig is serverruimte nu vrij goedkoop (zeker goedkoper dan een DockerHub-abonnement) en is het opzetten van een privérepository heel eenvoudig.

We willen hebben:

Om dit te doen:

  1. Laten we twee subdomeinen maken in Plesk in ons abonnement: docker.helloworld.ru en docker-ui.helloworld.ru, en Let's Encrypt-certificaten voor hen configureren.
  2. Voeg het bestand toe aan de subdomeinmap docker.helloworld.ru docker-compose.yml met inhoud als deze:
    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. Onder SSH genereren we het .htpasswd-bestand voor basisautorisatie in de Docker-repository:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Containers verzamelen en optillen:
    docker-compose up -d
  5. En we moeten Nginx omleiden naar onze containers. Dit kan via Plesk.

De volgende stappen moeten worden uitgevoerd voor de subdomeinen docker.helloworld.ru en docker-ui.helloworld.ru:

In paragraaf Dev Tools onze site ga naar Docker-proxyregels:

CI/CD in Github-acties voor een Flask+Angular-project
En voeg een regel toe om binnenkomend verkeer naar onze container te proxyen:

CI/CD in Github-acties voor een Flask+Angular-project

  1. We controleren of we kunnen inloggen op onze container vanaf de lokale machine:
    $ 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. Laten we ook de werking van het subdomein docker-ui.helloworld.ru controleren:

    CI/CD in Github-acties voor een Flask+Angular-project
    Wanneer u op Bladeren door repository's klikt, geeft de browser een autorisatievenster weer waarin u de gebruikersnaam en het wachtwoord voor de repository moet invoeren. Daarna worden we overgebracht naar een pagina met een lijst met repositories (voorlopig is deze voor u leeg):

    CI/CD in Github-acties voor een Flask+Angular-project

Poorten openen in Plesk Firewall

Na het installeren en configureren van de componenten moeten we poorten openen zodat de componenten toegankelijk zijn vanuit Docker-containers en het externe netwerk.

Laten we eens kijken hoe we dit kunnen doen met de Firewall-extensie voor Plesk die we eerder hebben geïnstalleerd.

  1. Ga naar Tools & instellingen > Instellingen > Firewall:
    CI/CD in Github-acties voor een Flask+Angular-project
  2. Ga naar Pas Plesk Firewall-regels aan > Voeg aangepaste regel toe en open de volgende TCP-poorten voor het Docker-subnet (172.0.0.0 / 8):
    KonijnMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD in Github-acties voor een Flask+Angular-project

  3. We zullen ook een regel toevoegen die PostgreSQL-poorten en RabbitMQ-beheerpanelen opent voor de buitenwereld:

    CI/CD in Github-acties voor een Flask+Angular-project

  4. Pas de regels toe met de knop Wijzigingen toepassen:

    CI/CD in Github-acties voor een Flask+Angular-project

CI/CD instellen in Github Actions

Laten we naar het meest interessante deel gaan: het opzetten van een continue integratiepijplijn en het leveren van ons project aan de server.

Deze pijplijn bestaat uit twee delen:

  • een afbeelding bouwen en tests uitvoeren (voor de backend) - aan de kant van Github;
  • migraties uitvoeren (voor de backend) en containers implementeren - op de server.

Implementeer naar Plesk

Laten we eerst het tweede punt behandelen (omdat het eerste ervan afhangt).

We zullen het implementatieproces configureren met behulp van de Git-extensie voor Plesk.

Overweeg een voorbeeld met een Prod-omgeving voor een Backend-repository.

  1. We gaan naar het abonnement van onze Helloworld-website en gaan naar de subsectie Git:

    CI/CD in Github-acties voor een Flask+Angular-project

  2. Plaats een link naar onze Github-repository in het veld "Remote Git-repository" en wijzig de standaardmap httpdocs naar een ander (bijv. /httpdocs/hw_back):

    CI/CD in Github-acties voor een Flask+Angular-project

  3. Kopieer de openbare SSH-sleutel uit de vorige stap en toevoegen het is in Github-instellingen.
  4. Klik op OK op het scherm in stap 2, waarna we worden doorgestuurd naar de repository-pagina in Plesk. Nu moeten we de repository configureren om te worden bijgewerkt bij commits naar de master branch. Ga hiervoor naar Opslagplaats instellingen en sla de waarde op Webhook URL (we hebben het later nodig bij het instellen van Github Actions):

    CI/CD in Github-acties voor een Flask+Angular-project

  5. Voer in het veld Acties op het scherm uit de vorige paragraaf het script in om de implementatie te starten:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    waar:

    {REPOSITORY_ABSOLUTE_PATH} - pad naar de prod-map van de backend-repository op de server;
    {ENV} - omgeving (dev / prod), in ons geval prod;
    {DOCKER_REGISTRY_HOST} - de host van onze docker-repository
    {TG_BOT_TOKEN} — Telegram-bottoken;
    {TG_CHAT_ID} — ID van de chat/het kanaal voor het verzenden van meldingen.

    Scriptvoorbeeld:

    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. Voeg een gebruiker uit ons abonnement toe aan de Docker-groep (zodat ze containers kunnen beheren):
    sudo usermod -aG docker helloworld_admin

De ontwikkelomgeving voor de backend repository en de frontend zijn op dezelfde manier ingericht.

Implementatiepijplijn in Github Actions

Laten we verder gaan met het opzetten van het eerste deel van onze CI/CD-pijplijn in Github Actions.

backend

De pijpleiding wordt beschreven in deploy.yml-bestand.

Maar laten we, voordat we het gaan ontleden, de geheime variabelen invullen die we nodig hebben in Github. Ga hiervoor naar Instellingen -> Geheimen:

  • DOCKER_REGISTRY - de host van onze Docker-repository (docker.helloworld.ru);
  • DOCKER_LOGIN - log in op de Docker-repository;
  • DOCKER_PASSWORD - wachtwoord ervoor;
  • DEPLOY_HOST — host waar het Plesk-beheerderspaneel beschikbaar is (voorbeeld: hallowereld.ru:8443 of 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - een token voor implementatie naar de prod-repository op de server (we hebben het in Implementatie in Plesk p. 4);
  • DEPLOY_BACK_DEV_TOKEN - token voor implementatie naar de dev-repository op de server.

Het implementatieproces is eenvoudig en bestaat uit drie hoofdstappen:

  • het bouwen en publiceren van de afbeelding in onze repository;
  • tests uitvoeren in een container op basis van een vers gebouwde afbeelding;
  • implementatie naar de gewenste omgeving, afhankelijk van de branch (dev/master).

Frontend

Het bestand deploy.yml voor de frontrepository beetje anders dan die van Beck. Het mist een stap met het uitvoeren van tests en verandert de namen van tokens voor implementatie. Geheimen voor de frontrepository moeten trouwens apart worden ingevuld.

Site-opstelling

Proxy verkeer via Nginx

Nou, we zijn aan het einde gekomen. Het blijft alleen om de proxying van inkomend en uitgaand verkeer naar onze container via Nginx te configureren. We hebben dit proces al behandeld in stap 5 van de installatie van Docker Registry. Hetzelfde moet worden herhaald voor de voor- en achterkant in dev- en prod-omgevingen.

Ik zal screenshots van de instellingen verstrekken.

backend

CI/CD in Github-acties voor een Flask+Angular-project

Frontend

CI/CD in Github-acties voor een Flask+Angular-project
ажное очнение. Alle URL's worden via een proxy naar de frontend-container geleid, behalve de URL's die beginnen met /api/ - ze worden geproxyeerd naar de achterste container (dus in de achterste container moeten alle handlers beginnen met /api/).

Resultaten van

Nu zou onze site beschikbaar moeten zijn op helloworld.ru en dev.helloworld.ru (respectievelijk prod- en dev-omgevingen).

In totaal hebben we geleerd hoe we een eenvoudige applicatie in Flask en Angular kunnen voorbereiden en hoe we een pijplijn in Github Actions kunnen opzetten om deze uit te rollen naar een server waarop Plesk draait.

Ik zal de links naar de repositories dupliceren met de code: back-end, voorkant.

Bron: www.habr.com

Voeg een reactie