CI/CD în Acțiuni Github pentru un proiect Flask+Angular

CI/CD în Acțiuni Github pentru un proiect Flask+Angular
În acest articol, voi împărtăși experiența mea de configurare CI/CD utilizând panoul de control Plesk și Github Actions. Astăzi vom învăța cum să implementăm un proiect simplu cu numele simplu „Helloworld”. Este scris în cadrul Flask Python, cu lucrători de țelină și un front-end Angular 8.

Link-uri către depozite: backend, în față.

În prima parte a articolului, vom analiza proiectul nostru și părțile sale. În al doilea, ne vom da seama cum să setăm Plesk și să instalăm extensiile și componentele necesare (DB, RabbitMQ, Redis, Docker etc.).

În cea de-a treia parte, vom descoperi în sfârșit cum să configuram o conductă pentru implementarea proiectului nostru pe un server într-un mediu de dezvoltare și producție. Și apoi vom lansa site-ul pe server.

Și da, am uitat să mă prezint. Numele meu este Oleg Borzov, sunt dezvoltator fullstack în echipa CRM pentru managerii de credite ipotecare de la Domclick.

Prezentare generală a proiectului

Mai întâi, să ne uităm la două depozite de proiecte - backend și front - și să trecem peste cod.

Backend: balon + țelină

Pentru partea din spate, am luat o grămadă care este destul de populară printre dezvoltatorii Python: framework-ul Flask (pentru API) și Celery (pentru coada de activități). SQLAchemy este folosit ca ORM. Alambicul este folosit pentru migrații. Pentru validarea JSON în mânere - Marshmallow.

В depozite există un fișier Readme.md cu o descriere detaliată a structurii și instrucțiuni pentru rularea proiectului.

API Web Part destul de simplu, constă din 6 stilouri:

  • /ping - pentru a verifica disponibilitatea;
  • manere pentru înregistrare, autorizare, dezautorizare și obținerea unui utilizator autorizat;
  • un handle de e-mail care pune o sarcină în coada de țelină.

Parte de țelină si mai usor, exista o singura problema send_mail_task.

În folder /conf există două subdirectoare:

  • docker cu două Dockerfile (base.dockerfile pentru a construi o imagine de bază care se schimbă rar și Dockerfile pentru ansambluri principale);
  • .env_files - cu fișiere cu variabile de mediu pentru diferite medii.

Există patru fișiere docker-compose la rădăcina proiectului:

  • docker-compose.local.db.yml să creeze o bază de date locală pentru dezvoltare;
  • docker-compose.local.workers.yml pentru ridicarea locală a lucrătorului, baza de date, Redis și RabbitMQ;
  • docker-compose.test.yml pentru a rula teste în timpul implementării;
  • docker-compose.yml pentru desfășurare.

Și ultimul folder care ne interesează - .ci-cd. Conține scripturi shell pentru implementare:

  • deploy.sh — lansarea migrației și implementării. Rulează pe server după construirea și rularea testelor în Github Actions;
  • rollback.sh - derularea containerelor la versiunea anterioară a ansamblului;
  • curl_tg.sh - trimiterea notificărilor de implementare către Telegram.

Frontend pe Angular

Depozit cu față mult mai simplu decât al lui Beck. Fața este formată din trei pagini:

  • Pagina principală cu un formular pentru trimiterea e-mailului și un buton de ieșire.
  • Pagina de logare.
  • Pagina de înregistrare.

Pagina principală pare ascetică:

CI/CD în Acțiuni Github pentru un proiect Flask+Angular
Există două fișiere la rădăcină Dockerfile и docker-compose.yml, precum și folderul familiar .ci-cd cu puțin mai puține scripturi decât în ​​depozitul din spate (scripturi eliminate pentru rularea testelor).

Pornirea unui proiect în Plesk

Să începem prin a configura Plesk și a crea un abonament pentru site-ul nostru.

Instalarea extensiilor

În Plesk, avem nevoie de patru extensii:

  • Docker pentru a gestiona și afișa vizual starea containerelor în panoul de administrare Plesk;
  • Git pentru a configura pasul de implementare pe server;
  • Let's Encrypt pentru a genera (și reînnoi automat) certificate TLS gratuite;
  • Firewall pentru a configura filtrarea traficului de intrare.

Le puteți instala prin panoul de administrare Plesk din secțiunea Extensii:

CI/CD în Acțiuni Github pentru un proiect Flask+Angular
Nu vom lua în considerare setările detaliate pentru extensii, setările implicite vor fi potrivite pentru scopurile noastre demo.

Creați un abonament și un site

Apoi, trebuie să creăm un abonament pentru site-ul nostru helloworld.ru și să adăugăm acolo subdomeniul dev.helloworld.ru.

  1. Creați un abonament pentru domeniul helloworld.ru și specificați parola de conectare pentru utilizatorul sistemului:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular
    Bifați caseta din partea de jos a paginii Securizează domeniul cu Let's Encryptdacă vrem să setăm HTTPS pentru site:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  2. Apoi, în acest abonament, creați un subdomeniu dev.helloworld.ru (pentru care puteți elibera și un certificat TLS gratuit):

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

Instalarea componentelor serverului

Avem un server cu OS Debian Stretch 9.12 și instalat panoul de control Plesk Obsidian 18.0.27.

Trebuie să instalăm și să configurăm pentru proiectul nostru:

  • PostgreSQL (în cazul nostru, va exista un server cu două baze de date pentru mediile de dezvoltare și producție).
  • RabbitMQ (aceeași, aceeași instanță cu vhost-uri diferite pentru medii).
  • Două instanțe Redis (pentru medii de dezvoltare și producție).
  • Docker Registry (pentru stocarea locală a imaginilor Docker construite).
  • UI pentru registrul Docker.

PostgreSQL

Plesk vine deja cu PostgreSQL DBMS, dar nu cea mai recentă versiune (la momentul scrierii Plesk Obsidian sprijinit Versiunile Postgres 8.4–10.8). Dorim cea mai recentă versiune pentru aplicația noastră (12.3 la momentul scrierii acestui articol), așa că o vom instala manual.

Există o mulțime de instrucțiuni detaliate pentru instalarea Postgres pe Debian pe net (exemplu), așa că nu le voi descrie în detaliu, voi da doar comenzile:

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

Având în vedere că PostgreSQL are setări implicite destul de mediocre, este necesară corectarea configurației. Acest lucru ne va ajuta calculator: trebuie să introduceți parametrii serverului dvs. și să înlocuiți setările din fișier /etc/postgresql/12/main/postgresql.confcelor oferite. Trebuie remarcat aici că astfel de calculatoare nu sunt un glonț magic, iar baza ar trebui reglată mai precis, pe baza hardware-ului, aplicației și complexității interogărilor. Dar acest lucru este suficient pentru a începe.

Pe lângă setările propuse de calculator, mai schimbăm postgresql.confportul implicit 5432 la altul (în exemplul nostru - 53983).

După modificarea fișierului de configurare, reporniți postgresql-server cu comanda:

service postgresql restart

Am instalat și configurat PostgreSQL. Acum să creăm o bază de date, utilizatori pentru medii de dezvoltare și producție și să acordăm utilizatorilor drepturi de a gestiona baza de date:

$ 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

Iepure MQ

Să trecem la instalarea RabbitMQ, un broker de mesaje pentru Celery. Instalarea acestuia pe Debian este destul de simplă:

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

După instalare, trebuie să creăm vhosts, utilizatorilor și acordați drepturile necesare:

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

Acum haideți să instalăm și să configurăm ultima componentă pentru aplicația noastră - Redis. Va fi folosit ca backend pentru stocarea rezultatelor sarcinilor de țelină.

Vom ridica două containere Docker cu Redis pentru medii de dezvoltare și producție folosind extensia Docker pentru Plesk.

  1. Mergem la Plesk, mergem la secțiunea Extensii, căutăm extensia Docker și o instalăm (avem nevoie de o versiune gratuită):

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  2. Accesați extensia instalată, găsiți imaginea prin căutare redis bitnami și instalează cea mai recentă versiune:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  3. Intrăm în containerul descărcat și ajustăm configurația: specificăm portul, dimensiunea maximă a RAM alocată, parola în variabilele de mediu și montăm volumul:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  4. Efectuăm pașii 2-3 pentru containerul de produse, în setări modificăm doar parametrii: port, parolă, dimensiunea RAM și calea către folderul de volum de pe server:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

Registrul Docker

Pe lângă serviciile de bază, ar fi bine să vă puneți propriul depozit de imagini Docker pe server. Din fericire, spațiul pe server este acum destul de ieftin (cu siguranță mai ieftin decât un abonament DockerHub), iar procesul de configurare a unui depozit privat este foarte simplu.

Vrem să avem:

Pentru a face acest lucru:

  1. Să creăm două subdomenii în Plesk în abonamentul nostru: docker.helloworld.ru și docker-ui.helloworld.ru și să configuram certificatele Let's Encrypt pentru ele.
  2. Adăugați fișierul în folderul subdomeniului docker.helloworld.ru docker-compose.yml cu conținut ca acesta:
    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. Sub SSH, vom genera fișierul .htpasswd pentru autorizarea de bază în depozitul Docker:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Colectați și ridicați containerele:
    docker-compose up -d
  5. Și trebuie să redirecționăm Nginx către containerele noastre. Acest lucru se poate face prin Plesk.

Următorii pași trebuie efectuati pentru subdomeniile docker.helloworld.ru și docker-ui.helloworld.ru:

În secțiunea Instrumente Dev accesați site-ul nostru Reguli Docker Proxy:

CI/CD în Acțiuni Github pentru un proiect Flask+Angular
Și adăugați o regulă pentru a proxy traficul de intrare în containerul nostru:

CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  1. Verificăm că ne putem conecta la containerul nostru de pe mașina 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. Să verificăm și funcționarea subdomeniului docker-ui.helloworld.ru:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular
    Când faceți clic pe Răsfoire depozite, browserul va afișa o fereastră de autorizare în care va trebui să introduceți numele de utilizator și parola pentru depozit. După aceea, vom fi transferați pe o pagină cu o listă de depozite (deocamdată, aceasta va fi goală pentru tine):

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

Deschiderea porturilor în Plesk Firewall

După instalarea și configurarea componentelor, trebuie să deschidem porturi astfel încât componentele să fie accesibile din containerele Docker și din rețeaua externă.

Să vedem cum să facem acest lucru folosind extensia Firewall pentru Plesk pe care am instalat-o mai devreme.

  1. Mergi la Instrumente și setări > Setări > Paravan de protecție:
    CI/CD în Acțiuni Github pentru un proiect Flask+Angular
  2. Mergi la Modificați regulile Plesk Firewall > Adăugați o regulă personalizată și deschideți următoarele porturi TCP pentru subrețeaua Docker (172.0.0.0 / 8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  3. Vom adăuga, de asemenea, o regulă care va deschide porturile PostgreSQL și panourile de gestionare RabbitMQ către lumea exterioară:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  4. Aplicați regulile folosind butonul Aplicați modificări:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

Configurarea CI/CD în Github Actions

Să trecem la partea cea mai interesantă - crearea unei conducte de integrare continuă și livrarea proiectului nostru pe server.

Această conductă va consta din două părți:

  • construirea unei imagini și rularea testelor (pentru backend) - pe partea Github;
  • rularea migrațiilor (pentru backend) și implementarea containerelor - pe server.

Implementați pe Plesk

Să ne ocupăm mai întâi de al doilea punct (pentru că primul depinde de el).

Vom configura procesul de implementare folosind extensia Git pentru Plesk.

Luați în considerare un exemplu cu un mediu Prod pentru un depozit de backend.

  1. Mergem la abonamentul site-ului nostru Helloworld și mergem la subsecțiunea Git:

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  2. Introduceți un link către depozitul nostru Github în câmpul „Depozitar Git la distanță” și schimbați folderul implicit httpdocs la altul (ex. /httpdocs/hw_back):

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  3. Copiați cheia publică SSH de la pasul anterior și adăuga este în setările Github.
  4. Faceți clic pe OK pe ecran la pasul 2, după care vom fi redirecționați către pagina de depozit din Plesk. Acum trebuie să configuram depozitul pentru a fi actualizat la comiterea în ramura principală. Pentru a face acest lucru, accesați Setări pentru depozit și salvați valoarea Webhook URL (vom avea nevoie de el mai târziu când configurați Github Actions):

    CI/CD în Acțiuni Github pentru un proiect Flask+Angular

  5. În câmpul Acțiuni de pe ecran din paragraful anterior, introduceți scriptul pentru a lansa implementarea:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    în cazul în care:

    {REPOSITORY_ABSOLUTE_PATH} - calea către folderul prod al depozitului backend de pe server;
    {ENV} - mediu (dev/prod), în cazul nostru prod;
    {DOCKER_REGISTRY_HOST} - gazda depozitului nostru docker
    {TG_BOT_TOKEN} — Jeton de bot Telegram;
    {TG_CHAT_ID} — ID-ul chat-ului/canalului pentru trimiterea notificărilor.

    Exemplu de 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
  6. Adăugați un utilizator din abonamentul nostru la grupul Docker (pentru a putea gestiona containerele):
    sudo usermod -aG docker helloworld_admin

Mediul de dezvoltare pentru depozitul de backend și frontend-ul sunt configurate în același mod.

Conducta de implementare în Github Actions

Să trecem la configurarea primei părți a conductei noastre CI/CD în Github Actions.

Backend

Conducta este descrisă în fișierul deploy.yml.

Dar înainte de a-l analiza, să completăm variabilele Secret de care avem nevoie în Github. Pentru a face acest lucru, accesați Setări -> Secrete:

  • DOCKER_REGISTRY - gazda depozitului nostru Docker (docker.helloworld.ru);
  • DOCKER_LOGIN - conectați-vă la depozitul Docker;
  • DOCKER_PASSWORD - parola acestuia;
  • DEPLOY_HOST — gazdă unde este disponibil panoul de administrare Plesk (exemplu: helloworld.com: 8443 sau 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - un token pentru implementare în prod-repository de pe server (l-am primit în Deployment in Plesk p. 4);
  • DEPLOY_BACK_DEV_TOKEN - token pentru implementare în depozitul de dezvoltare de pe server.

Procesul de implementare este simplu și constă din trei pași principali:

  • construirea și publicarea imaginii în depozitul nostru;
  • rularea de teste într-un container pe baza unei imagini proaspăt construite;
  • implementare în mediul dorit în funcție de ramură (dev/master).

Frontend

Fișierul deploy.yml pentru depozitul frontal puțin diferit de cel al lui Beck. Îi lipsește un pas cu rularea testelor și schimbă numele token-urilor pentru implementare. Apropo, secretele pentru depozitul frontal trebuie completate separat.

Configurarea site-ului

Traficul proxy prin Nginx

Ei bine, am ajuns la final. Rămâne doar să configurați proxy traficul de intrare și de ieșire către containerul nostru prin Nginx. Am acoperit deja acest proces la pasul 5 din configurarea Docker Registry. Același lucru ar trebui repetat pentru părțile din spate și din față în mediile de dezvoltare și producție.

Voi oferi capturi de ecran ale setărilor.

Backend

CI/CD în Acțiuni Github pentru un proiect Flask+Angular

Frontend

CI/CD în Acțiuni Github pentru un proiect Flask+Angular
Lămurire importantă. Toate adresele URL vor fi trimise proxy către containerul de interfață, cu excepția celor care încep cu /api/ - vor fi proxy de containerul din spate (deci în containerul din spate, toți manipulatorii trebuie să înceapă cu /api/).

Rezultatele

Acum, site-ul nostru ar trebui să fie disponibil la helloworld.ru și dev.helloworld.ru (prod- și, respectiv, dev-medii).

În total, am învățat cum să pregătim o aplicație simplă în Flask și Angular și să configuram o conductă în Github Actions pentru a o implementa pe un server care rulează Plesk.

Voi duplica link-urile către depozite cu codul: backend, în față.

Sursa: www.habr.com

Adauga un comentariu