CI/CD a les accions de Github per a un projecte Flask+Angular

CI/CD a les accions de Github per a un projecte Flask+Angular
En aquest article, compartiré la meva experiència de configuració de CI/CD mitjançant el tauler de control de Plesk i les accions de Github. Avui aprendrem a desplegar un projecte senzill amb el nom senzill "Helloworld". Està escrit al framework Flask Python, amb treballadors de Celery i una interfície Angular 8.

Enllaços als repositoris: backend, interfície.

A la primera part de l'article, veurem el nostre projecte i les seves parts. En el segon, descobrirem com configurar Plesk i instal·lar les extensions i components necessaris (DB, RabbitMQ, Redis, Docker, etc.).

A la tercera part, finalment descobrirem com configurar un pipeline per desplegar el nostre projecte a un servidor en un entorn de desenvolupament i producció. I després llançarem el lloc al servidor.

I sí, m'he oblidat de presentar-me. Em dic Oleg Borzov, sóc desenvolupador fullstack a l'equip de CRM per a gestors d'hipoteques de Domclick.

Descripció general del projecte

En primer lloc, mirem dos repositoris del projecte: backend i front, i repassem el codi.

Backend: Flask+Api

Per a la part posterior, vaig agafar un munt que és força popular entre els desenvolupadors de Python: el framework Flask (per a l'API) i Celery (per a la cua de tasques). SQLAchemy s'utilitza com a ORM. L'alambic s'utilitza per a les migracions. Per a la validació JSON a les nanses - Marshmallow.

В repositoris hi ha un fitxer Readme.md amb una descripció detallada de l'estructura i instruccions per executar el projecte.

API de part web bastant senzill, consta de 6 bolígrafs:

  • /ping - per comprovar la disponibilitat;
  • maneig de registre, autorització, desautorització i obtenció d'un usuari autoritzat;
  • un controlador de correu electrònic que posa una tasca a la cua d'api.

Part d'api encara més fàcil, només hi ha un problema send_mail_task.

A la carpeta /conf hi ha dues subcarpetes:

  • docker amb dos Dockerfiles (base.dockerfile per construir una imatge base que rarament canvia i Dockerfile per a assemblees principals);
  • .env_files - amb fitxers amb variables d'entorn per a diferents entorns.

Hi ha quatre fitxers docker-compose a l'arrel del projecte:

  • docker-compose.local.db.yml crear una base de dades local per al desenvolupament;
  • docker-compose.local.workers.yml per a la criança local del treballador, base de dades, Redis i RabbitMQ;
  • docker-compose.test.yml per executar proves durant el desplegament;
  • docker-compose.yml per al desplegament.

I l'última carpeta que ens interessa... .ci-cd. Conté scripts d'intèrpret d'ordres per al desplegament:

  • deploy.sh — Llançament de la migració i el desplegament. S'executa al servidor després de crear i executar proves a Github Actions;
  • rollback.sh - retrocés dels contenidors a la versió anterior del conjunt;
  • curl_tg.sh - enviament de notificacions de desplegament a Telegram.

Frontend a Angular

Repositori amb frontal molt més senzill que el de Beck. El front consta de tres pàgines:

  • Pàgina principal amb un formulari per enviar correu electrònic i un botó de sortida.
  • Pàgina d'inici de sessió.
  • Pàgina de registre.

La pàgina principal sembla ascètica:

CI/CD a les accions de Github per a un projecte Flask+Angular
Hi ha dos fitxers a l'arrel Dockerfile и docker-compose.yml, així com la carpeta familiar .ci-cd amb una mica menys d'scripts que al repositori posterior (s'han eliminat els scripts per executar proves).

Iniciant un projecte a Plesk

Comencem configurant Plesk i creant una subscripció per al nostre lloc.

Instal·lació d'extensions

A Plesk, necessitem quatre extensions:

  • Docker per gestionar i mostrar visualment l'estat dels contenidors al tauler d'administració de Plesk;
  • Git per configurar el pas de desplegament al servidor;
  • Let's Encrypt per generar (i renovar automàticament) certificats TLS gratuïts;
  • Firewall per configurar el filtratge del trànsit entrant.

Podeu instal·lar-los a través del tauler d'administració de Plesk a la secció Extensions:

CI/CD a les accions de Github per a un projecte Flask+Angular
No tindrem en compte la configuració detallada de les extensions, la configuració predeterminada servirà per als nostres propòsits de demostració.

Creeu una subscripció i un lloc

A continuació, hem de crear una subscripció per al nostre lloc web helloworld.ru i afegir-hi el subdomini dev.helloworld.ru.

  1. Creeu una subscripció per al domini helloworld.ru i especifiqueu la contrasenya d'inici de sessió per a l'usuari del sistema:

    CI/CD a les accions de Github per a un projecte Flask+Angular
    Marqueu la casella a la part inferior de la pàgina Assegureu el domini amb Let's Encryptsi volem configurar HTTPS per al lloc:

    CI/CD a les accions de Github per a un projecte Flask+Angular

  2. A continuació, en aquesta subscripció, creeu un subdomini dev.helloworld.ru (per al qual també podeu emetre un certificat TLS gratuït):

    CI/CD a les accions de Github per a un projecte Flask+Angular

Instal·lació de components del servidor

Tenim un servidor amb SO Debian Stretch 9.12 i el panell de control instal·lat Plesk Obsidian 18.0.27.

Hem d'instal·lar i configurar per al nostre projecte:

  • PostgreSQL (en el nostre cas, hi haurà un servidor amb dues bases de dades per a entorns de desenvolupament i producció).
  • RabbitMQ (la mateixa, mateixa instància amb diferents vhosts per a entorns).
  • Dues instàncies de Redis (per a entorns de desenvolupament i producció).
  • Docker Registry (per a l'emmagatzematge local d'imatges Docker construïdes).
  • IU per al registre de Docker.

PostgreSQL

Plesk ja ve amb PostgreSQL DBMS, però no la versió més recent (en el moment d'escriure Plesk Obsidian recolzat versions de Postgres 8.4–10.8). Volem la darrera versió per a la nostra aplicació (12.3 en el moment d'escriure aquest article), així que l'instal·larem manualment.

Hi ha moltes instruccions detallades per instal·lar Postgres a Debian a la xarxa (exemple), així que no els descriuré en detall, només donaré les ordres:

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

Tenint en compte que PostgreSQL té una configuració predeterminada més aviat mediocre, cal corregir la configuració. Això ens ajudarà calculadora: heu de controlar els paràmetres del vostre servidor i substituir els paràmetres del fitxer /etc/postgresql/12/main/postgresql.confals que s'ofereixen. Cal assenyalar aquí que aquestes calculadores no són una bala màgica i la base s'hauria d'ajustar amb més precisió, en funció del vostre maquinari, aplicació i complexitat de la consulta. Però això és suficient per començar.

A més de les configuracions proposades per la calculadora, també hi canviem postgresql.confel port predeterminat 5432 a un altre (en el nostre exemple - 53983).

Després de canviar el fitxer de configuració, reinicieu postgresql-server amb l'ordre:

service postgresql restart

Hem instal·lat i configurat PostgreSQL. Ara creem una base de dades, usuaris per a entorns de desenvolupament i producció, i donem als usuaris drets per gestionar la base de dades:

$ 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

ConillMQ

Passem a instal·lar RabbitMQ, un agent de missatges per a Celery. Instal·lar-lo a Debian és bastant senzill:

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

Després de la instal·lació, hem de crear vhosts, usuaris i concedir els drets necessaris:

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

Ara instal·lem i configurem l'últim component de la nostra aplicació: Redis. S'utilitzarà com a backend per emmagatzemar els resultats de les tasques d'api.

Crearem dos contenidors Docker amb Redis per a entorns de desenvolupament i producció utilitzant l'extensió Docker per a Plesk.

  1. Anem a Plesk, anem a la secció Extensions, busquem l'extensió Docker i la instal·lem (necessitem una versió gratuïta):

    CI/CD a les accions de Github per a un projecte Flask+Angular

  2. Aneu a l'extensió instal·lada, cerqueu la imatge mitjançant la cerca redis bitnami i instal·leu la darrera versió:

    CI/CD a les accions de Github per a un projecte Flask+Angular

  3. Entrem al contenidor descarregat i ajustem la configuració: especifiquem el port, la mida màxima de RAM assignada, la contrasenya a les variables d'entorn i muntem el volum:

    CI/CD a les accions de Github per a un projecte Flask+Angular

  4. Realitzem els passos 2-3 per al contenidor de productes, a la configuració només canviem els paràmetres: port, contrasenya, mida de RAM i camí a la carpeta de volums del servidor:

    CI/CD a les accions de Github per a un projecte Flask+Angular

Registre Docker

A més dels serveis bàsics, seria bo posar el vostre propi dipòsit d'imatges Docker al servidor. Afortunadament, ara l'espai del servidor és força barat (segurament més barat que una subscripció a DockerHub) i el procés de configuració d'un dipòsit privat és molt senzill.

Volem tenir:

Per a això:

  1. Creem dos subdominis a Plesk a la nostra subscripció: docker.helloworld.ru i docker-ui.helloworld.ru, i configurem els certificats Let's Encrypt per a ells.
  2. Afegiu el fitxer a la carpeta del subdomini docker.helloworld.ru docker-compose.yml amb contingut com aquest:
    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. Sota SSH, generarem el fitxer .htpasswd per a l'autorització bàsica al repositori de Docker:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Recollir i aixecar contenidors:
    docker-compose up -d
  5. I hem de redirigir Nginx als nostres contenidors. Això es pot fer mitjançant Plesk.

Cal fer els passos següents per als subdominis docker.helloworld.ru i docker-ui.helloworld.ru:

A la secció Eines Dev el nostre lloc va a Regles de proxy Docker:

CI/CD a les accions de Github per a un projecte Flask+Angular
I afegiu una regla per enviar el trànsit entrant al nostre contenidor:

CI/CD a les accions de Github per a un projecte Flask+Angular

  1. Comprovem que podem iniciar sessió al nostre contenidor des de la màquina local:
    $ 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. Comprovem també el funcionament del subdomini docker-ui.helloworld.ru:

    CI/CD a les accions de Github per a un projecte Flask+Angular
    Quan feu clic a Explora repositoris, el navegador mostrarà una finestra d'autorització on haureu d'introduir el nom d'usuari i la contrasenya del repositori. Després d'això, serem transferits a una pàgina amb una llista de repositoris (de moment, estarà buida per a tu):

    CI/CD a les accions de Github per a un projecte Flask+Angular

Obertura de ports a Plesk Firewall

Després d'instal·lar i configurar els components, hem d'obrir ports perquè els components siguin accessibles des dels contenidors Docker i la xarxa externa.

Vegem com fer-ho amb l'extensió del tallafoc per a Plesk que hem instal·lat anteriorment.

  1. Anar a Eines i configuració > Configuració > Tallafoc:
    CI/CD a les accions de Github per a un projecte Flask+Angular
  2. Anar a Modifiqueu les regles del tallafoc de Plesk > Afegeix una regla personalitzada i obriu els ports TCP següents per a la subxarxa Docker (172.0.0.0 / 8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD a les accions de Github per a un projecte Flask+Angular

  3. També afegirem una regla que obrirà els ports PostgreSQL i els panells de gestió de RabbitMQ al món exterior:

    CI/CD a les accions de Github per a un projecte Flask+Angular

  4. Apliqueu les regles amb el botó Aplica els canvis:

    CI/CD a les accions de Github per a un projecte Flask+Angular

Configuració de CI/CD a Github Actions

Anem a la part més interessant: configurar un pipeline d'integració contínua i lliurar el nostre projecte al servidor.

Aquesta canalització constarà de dues parts:

  • crear una imatge i executar proves (per al backend) - al costat de Github;
  • executant migracions (per al backend) i desplegant contenidors al servidor.

Desplegueu a Plesk

Tractem primer el segon punt (perquè el primer en depèn).

Configurarem el procés de desplegament mitjançant l'extensió Git per a Plesk.

Penseu en un exemple amb un entorn Prod per a un dipòsit de backend.

  1. Anem a la subscripció del nostre lloc web Helloworld i anem a la subsecció Git:

    CI/CD a les accions de Github per a un projecte Flask+Angular

  2. Inseriu un enllaç al nostre dipòsit Gitub al camp "Repositori Git remot" i canvieu la carpeta predeterminada httpdocs a un altre (p. ex. /httpdocs/hw_back):

    CI/CD a les accions de Github per a un projecte Flask+Angular

  3. Copieu la clau pública SSH del pas anterior i afegir està a la configuració de Github.
  4. Feu clic a D'acord a la pantalla al pas 2, després serem redirigits a la pàgina del repositori de Plesk. Ara hem de configurar el repositori perquè s'actualitzi en commits a la branca mestra. Per fer-ho, aneu a Configuració del repositori i guarda el valor Webhook URL (el necessitarem més endavant quan configurem les accions de Github):

    CI/CD a les accions de Github per a un projecte Flask+Angular

  5. Al camp Accions de la pantalla del paràgraf anterior, introduïu l'script per iniciar el desplegament:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    on:

    {REPOSITORY_ABSOLUTE_PATH} - camí a la carpeta prod del dipòsit de fons del servidor;
    {ENV} - entorn (dev/prod), en el nostre cas prod;
    {DOCKER_REGISTRY_HOST} - l'amfitrió del nostre repositori Docker
    {TG_BOT_TOKEN} — Fitxa de bot de Telegram;
    {TG_CHAT_ID} — ID del xat/canal per enviar notificacions.

    Exemple de guió:

    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. Afegiu un usuari de la nostra subscripció al grup Docker (perquè pugui gestionar els contenidors):
    sudo usermod -aG docker helloworld_admin

L'entorn de desenvolupament per al dipòsit de backend i el frontend es configuren de la mateixa manera.

Canal de desplegament a Github Actions

Passem a configurar la primera part del nostre pipeline CI/CD a Github Actions.

Backend

La canonada es descriu a fitxer deploy.yml.

Però abans d'analitzar-lo, omplim les variables secretes que necessitem a Github. Per fer-ho, aneu a Configuració -> Secrets:

  • DOCKER_REGISTRY - l'amfitrió del nostre dipòsit Docker (docker.helloworld.ru);
  • DOCKER_LOGIN - inicieu sessió al repositori de Docker;
  • DOCKER_PASSWORD - contrasenya;
  • DEPLOY_HOST — amfitrió on el tauler d'administració de Plesk està disponible (exemple: helloworld.com: 8443 o 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - un testimoni per al desplegament al prod-repository del servidor (l'hem obtingut a Deployment in Plesk p. 4);
  • DEPLOY_BACK_DEV_TOKEN - testimoni per al desplegament al repositori de desenvolupament del servidor.

El procés de desplegament és senzill i consta de tres passos principals:

  • construir i publicar la imatge al nostre repositori;
  • executar proves en un contenidor basat en una imatge acabada de construir;
  • desplegament a l'entorn desitjat en funció de la branca (dev/master).

frontend

El fitxer deploy.yml per al dipòsit frontal poc diferent de Beck. Li falta un pas amb l'execució de proves i canvia els noms dels testimonis per al desplegament. Per cert, els secrets del dipòsit frontal s'han d'omplir per separat.

Configuració del lloc

Trànsit intermediari a través de Nginx

Bé, hem arribat al final. Només queda configurar el proxy del trànsit entrant i sortint al nostre contenidor a través de Nginx. Ja hem tractat aquest procés al pas 5 de la configuració del registre Docker. El mateix s'ha de repetir per a les parts posterior i frontal en entorns de desenvolupament i prod.

Us proporcionaré captures de pantalla de la configuració.

Backend

CI/CD a les accions de Github per a un projecte Flask+Angular

frontend

CI/CD a les accions de Github per a un projecte Flask+Angular
Aclariment important. Tots els URL s'enviaran al contenidor de la interfície, excepte els que comencen per /api/ - estaran aproximats al contenidor posterior (per tant al contenidor posterior, tots els manipuladors han de començar /api/).

Resultats de

Ara el nostre lloc hauria d'estar disponible a helloworld.ru i dev.helloworld.ru (entorns de producció i desenvolupament, respectivament).

En total, vam aprendre a preparar una aplicació senzilla a Flask i Angular i a configurar una canalització a Github Actions per desplegar-la a un servidor amb Plesk.

Duplicaré els enllaços als repositoris amb el codi: backend, interfície.

Font: www.habr.com

Afegeix comentari