CI/CD в Github действия за Flask+Angular проект

CI/CD в Github действия за Flask+Angular проект
В тази статия ще споделя опита си от настройката на CI/CD с помощта на контролния панел на Plesk и Github Actions. Днес ще научим как да разположим прост проект с неусложненото име "Helloworld". Написан е в рамката на Flask Python, с работници на Celery и интерфейс Angular 8.

Връзки към хранилища: бекенд, интерфейс.

В първата част на статията ще разгледаме нашия проект и неговите части. Във втория ще разберем как да настроим Plesk и да инсталираме необходимите разширения и компоненти (DB, RabbitMQ, Redis, Docker и др.).

В третата част най-накрая ще разберем как да настроим тръбопровод за внедряване на нашия проект на сървър в dev и prod среда. И тогава ще стартираме сайта на сървъра.

И да, забравих да се представя. Казвам се Олег Борзов, аз съм fullstack разработчик в CRM екипа за ипотечни мениджъри в Domclick.

Преглед на проекта

Първо, нека да разгледаме две хранилища на проекти - backend и front - и да прегледаме кода.

Бекенд: Flask+Celery

За задната част взех куп, който е доста популярен сред разработчиците на Python: рамката на Flask (за API) и Celery (за опашката със задачи). SQLAchemy се използва като ORM. Alembic се използва за миграции. За валидиране на JSON в дръжки - Marshmallow.

В хранилища има файл Readme.md с подробно описание на структурата и инструкции за изпълнение на проекта.

API за уеб части доста проста, състои се от 6 химикалки:

  • /ping - за проверка на наличността;
  • дръжки за регистрация, авторизация, деавторизация и получаване на оторизиран потребител;
  • имейл манипулатор, който поставя задача в опашката Celery.

Целина част още по-лесно, има само един проблем send_mail_task.

В папка /конф има две подпапки:

  • docker с два Docker файла (base.dockerfile за изграждане на рядко променящо се основно изображение и Dockerfile за основни възли);
  • .env_files - с файлове с променливи на средата за различни среди.

Има четири docker-compose файла в основата на проекта:

  • docker-compose.local.db.yml създаване на локална база данни за развитие;
  • docker-compose.local.workers.yml за локално повдигане на работник, база данни, Redis и RabbitMQ;
  • docker-compose.test.yml за провеждане на тестове по време на внедряване;
  • docker-compose.yml за разгръщане.

И последната папка, която ни интересува - .ci-cd. Той съдържа shell скриптове за внедряване:

  • deploy.sh — стартиране на миграция и внедряване. Изпълнява се на сървъра след изграждане и провеждане на тестове в Github Actions;
  • rollback.sh - връщане на контейнери към предишната версия на монтажа;
  • curl_tg.sh - изпращане на известия за внедряване към Telegram.

Frontend на Angular

Хранилище с пред много по-проста от тази на Бек. Предната част се състои от три страници:

  • Основна страница с форма за изпращане на имейл и бутон за изход.
  • Страница за вход.
  • Страница за регистрация.

Главната страница изглежда аскетично:

CI/CD в Github действия за Flask+Angular проект
В основата има два файла Dockerfile и docker-compose.yml, както и познатата папка .ci-cd с малко по-малко скриптове, отколкото в задното хранилище (премахнати скриптове за изпълнение на тестове).

Стартиране на проект в Plesk

Нека започнем, като настроим Plesk и създадем абонамент за нашия сайт.

Инсталиране на разширения

В Plesk имаме нужда от четири разширения:

  • Docker за управление и визуално показване на състоянието на контейнери в административния панел на Plesk;
  • Git за конфигуриране на стъпката на внедряване на сървъра;
  • Let's Encrypt за генериране (и автоматично подновяване) на безплатни TLS сертификати;
  • Firewall за конфигуриране на филтриране на входящия трафик.

Можете да ги инсталирате през административния панел на Plesk в секцията Разширения:

CI/CD в Github действия за Flask+Angular проект
Няма да разглеждаме подробните настройки за разширения, настройките по подразбиране ще свършат работа за нашите демонстрационни цели.

Създайте абонамент и сайт

След това трябва да създадем абонамент за нашия уебсайт helloworld.ru и да добавим поддомейна dev.helloworld.ru там.

  1. Създайте абонамент за домейна helloworld.ru и посочете паролата за вход за системния потребител:

    CI/CD в Github действия за Flask+Angular проект
    Поставете отметка в квадратчето в долната част на страницата Защитете домейна с Let's Encryptако искаме да настроим HTTPS за сайта:

    CI/CD в Github действия за Flask+Angular проект

  2. След това в този абонамент създайте поддомейн dev.helloworld.ru (за който можете също да издадете безплатен TLS сертификат):

    CI/CD в Github действия за Flask+Angular проект

Инсталиране на сървърни компоненти

Имаме сървър с OS Debian Stretch 9.12 и монтиран контролен панел Плеск Обсидиан 18.0.27.

Трябва да инсталираме и конфигурираме за нашия проект:

  • PostgreSQL (в нашия случай ще има един сървър с две бази данни за dev и prod среди).
  • RabbitMQ (същият, същия екземпляр с различни vhost за среди).
  • Два екземпляра на Redis (за dev и prod среди).
  • Docker регистър (за локално съхранение на изградени Docker изображения).
  • Потребителски интерфейс за регистър на Docker.

PostgreSQL

Plesk вече идва с PostgreSQL DBMS, но не и с най-новата версия (по време на писане на Plesk Obsidian поддържан Postgres версии 8.4–10.8). Искаме най-новата версия за нашето приложение (12.3 към момента на писане), така че ще я инсталираме ръчно.

В нета има много подробни инструкции за инсталиране на Postgres на Debian (пример), така че няма да ги описвам подробно, а само ще дам командите:

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

Като се има предвид, че PostgreSQL има доста посредствени настройки по подразбиране, е необходимо да се коригира конфигурацията. Това ще ни помогне калкулатор: трябва да въведете параметрите на вашия сървър и да замените настройките във файла /etc/postgresql/12/main/postgresql.confкъм предлаганите. Тук трябва да се отбележи, че такива калкулатори не са магически куршум и базата трябва да бъде настроена по-прецизно въз основа на вашия хардуер, приложение и сложност на заявката. Но това е достатъчно, за да започнете.

В допълнение към настройките, предложени от калкулатора, ние също променяме postgresql.confпорта по подразбиране 5432 към друг (в нашия пример - 53983).

След като промените конфигурационния файл, рестартирайте postgresql-сървъра с командата:

service postgresql restart

Инсталирахме и конфигурирахме PostgreSQL. Сега нека създадем база данни, потребители за dev и prod среди и да дадем права на потребителите да управляват базата данни:

$ 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

Нека да преминем към инсталирането на RabbitMQ, брокер на съобщения за Celery. Инсталирането му в Debian е доста лесно:

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

След инсталирането трябва да създадем vhosts, потребители и предоставяне на необходимите права:

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

Сега нека инсталираме и конфигурираме последния компонент за нашето приложение - Redis. Той ще се използва като бекенд за съхраняване на резултатите от задачите на Celery.

Ще създадем два Docker контейнера с Redis за dev и prod среди, използвайки разширението Docker за Plesk.

  1. Отиваме в Plesk, отиваме в секцията Разширения, търсим разширението Docker и го инсталираме (имаме нужда от безплатна версия):

    CI/CD в Github действия за Flask+Angular проект

  2. Отидете до инсталираното разширение, намерете изображението чрез търсенето redis bitnami и инсталирайте най-новата версия:

    CI/CD в Github действия за Flask+Angular проект

  3. Влизаме в изтегления контейнер и коригираме конфигурацията: посочете порта, максималния разпределен размер на RAM, паролата в променливите на средата и монтирайте тома:

    CI/CD в Github действия за Flask+Angular проект

  4. Изпълняваме стъпки 2-3 за продуктовия контейнер, в настройките променяме само параметрите: порт, парола, размер на RAM и път до папката на тома на сървъра:

    CI/CD в Github действия за Flask+Angular проект

Докер регистър

В допълнение към основните услуги, би било хубаво да поставите свое собствено хранилище за изображения на Docker на сървъра. За щастие сървърното пространство сега е доста евтино (със сигурност по-евтино от абонамент за DockerHub), а процесът на създаване на частно хранилище е много прост.

Искаме да имаме:

  • защитено с парола Docker хранилище, достъпно на поддомейн https://docker.helloworld.ru;
  • Потребителски интерфейс за преглед на изображения в хранилището, достъпен на https://docker-ui.helloworld.ru.

За да направите това:

  1. Нека създадем два поддомейна в Plesk в нашия абонамент: docker.helloworld.ru и docker-ui.helloworld.ru и да конфигурираме Let's Encrypt сертификати за тях.
  2. Добавете файла към папката на поддомейн docker.helloworld.ru docker-compose.yml със съдържание като това:
    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. Под SSH ще генерираме файла .htpasswd за основно оторизиране в хранилището на Docker:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Събиране и повдигане на контейнери:
    docker-compose up -d
  5. И трябва да пренасочим Nginx към нашите контейнери. Това може да стане чрез Plesk.

Трябва да се направят следните стъпки за поддомейните docker.helloworld.ru и docker-ui.helloworld.ru:

В раздел Инструменти за разработчици отидете на нашия сайт Правила за прокси сървър на Docker:

CI/CD в Github действия за Flask+Angular проект
И добавете правило за прокси входящ трафик към нашия контейнер:

CI/CD в Github действия за Flask+Angular проект

  1. Проверяваме дали можем да влезем в нашия контейнер от локалната машина:
    $ 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. Нека също да проверим работата на поддомейна docker-ui.helloworld.ru:

    CI/CD в Github действия за Flask+Angular проект
    Когато щракнете върху Преглед на хранилищата, браузърът ще покаже прозорец за оторизация, където ще трябва да въведете потребителското име и паролата за хранилището. След това ще бъдем прехвърлени на страница със списък с хранилища (засега той ще бъде празен за вас):

    CI/CD в Github действия за Flask+Angular проект

Отваряне на портове в Plesk Firewall

След като инсталираме и конфигурираме компонентите, трябва да отворим портове, така че компонентите да са достъпни от Docker контейнери и външната мрежа.

Нека видим как да направим това с помощта на разширението Firewall за Plesk, което инсталирахме по-рано.

  1. Отидете на Инструменти и настройки > Настройки > Защитна стена:
    CI/CD в Github действия за Flask+Angular проект
  2. Отидете на Промяна на правилата на защитната стена на Plesk > Добавяне на персонализирано правило и отворете следните TCP портове за подмрежата Docker (172.0.0.0 / 8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD в Github действия за Flask+Angular проект

  3. Ще добавим и правило, което ще отвори PostgreSQL портове и панели за управление на RabbitMQ към външния свят:

    CI/CD в Github действия за Flask+Angular проект

  4. Приложете правилата, като използвате бутона Прилагане на промените:

    CI/CD в Github действия за Flask+Angular проект

Настройване на CI/CD в Github Actions

Нека да преминем към най-интересната част - настройка на конвейер за непрекъсната интеграция и доставяне на нашия проект до сървъра.

Този тръбопровод ще се състои от две части:

  • изграждане на изображение и стартиране на тестове (за бекенда) - от страна на Github;
  • стартиране на миграции (за бекенда) и разполагане на контейнери - на сървъра.

Разположете в Plesk

Нека първо да разгледаме втората точка (защото първата зависи от нея).

Ще конфигурираме процеса на внедряване с помощта на разширението Git за Plesk.

Помислете за пример с Prod среда за Backend хранилище.

  1. Отиваме в абонамента на нашия уебсайт Helloworld и отиваме в подраздела Git:

    CI/CD в Github действия за Flask+Angular проект

  2. Вмъкнете връзка към нашето Github хранилище в полето „Remote Git repository“ и променете папката по подразбиране httpdocs на друг (напр. /httpdocs/hw_back):

    CI/CD в Github действия за Flask+Angular проект

  3. Копирайте SSH публичния ключ от предишната стъпка и добавете това е в настройките на Github.
  4. Натискаме OK на екрана в стъпка 2, след което се прехвърляме на страницата на хранилището в Plesk. Сега трябва да конфигурираме хранилището да се актуализира при ангажименти към главния клон. За да направите това, отидете на Настройки на хранилището и запазете стойността Webhook URL (ще ни трябва по-късно, когато настройваме Github Actions):

    CI/CD в Github действия за Flask+Angular проект

  5. В полето Действия на екрана от предишния параграф въведете скрипта, за да стартирате внедряването:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    където:

    {REPOSITORY_ABSOLUTE_PATH} - път до папката prod на backend хранилището на сървъра;
    {ENV} - среда (dev / prod), в нашия случай prod;
    {DOCKER_REGISTRY_HOST} - хост на нашето докер хранилище
    {TG_BOT_TOKEN} — Telegram бот токен;
    {TG_CHAT_ID} — ID на чата/канала за изпращане на известия.

    Пример за скрипт:

    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. Добавете потребител от нашия абонамент към групата Docker (за да могат да управляват контейнери):
    sudo usermod -aG docker helloworld_admin

Dev средата за backend хранилището и frontend са настроени по същия начин.

Конвейер за внедряване в Github Actions

Нека да преминем към настройването на първата част от нашия CI/CD тръбопровод в Github Actions.

бекенда

Тръбопроводът е описан в файл deploy.yml.

Но преди да го анализираме, нека попълним Secret променливите, от които се нуждаем в Github. За да направите това, отидете на Настройки -> Тайни:

  • DOCKER_REGISTRY - хостът на нашето хранилище на Docker (docker.helloworld.ru);
  • DOCKER_LOGIN - влезте в хранилището на Docker;
  • DOCKER_PASSWORD - парола към него;
  • DEPLOY_HOST — хост, където е наличен административният панел на Plesk (пример: helloworld.com: 8443 или 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - токен за разгръщане в prod-репозитория на сървъра (получихме го в Разполагане в Plesk стр. 4);
  • DEPLOY_BACK_DEV_TOKEN - токен за внедряване в хранилището за разработчици на сървъра.

Процесът на внедряване е прост и се състои от три основни стъпки:

  • изграждане и публикуване на изображението в нашето хранилище;
  • провеждане на тестове в контейнер на базата на прясно изграден образ;
  • внедряване в желаната среда в зависимост от клона (dev/master).

Входния

Файлът deploy.yml за предното хранилище малко по-различен от този на Бек. Липсва стъпка с провеждане на тестове и променя имената на токените за внедряване. Тайните за предното хранилище, между другото, трябва да бъдат попълнени отделно.

Настройка на сайта

Прокси трафик през Nginx

Е, стигнахме до края. Остава само да конфигурирате проксирането на входящ и изходящ трафик към нашия контейнер чрез Nginx. Вече разгледахме този процес в стъпка 5 от настройката на регистъра на Docker. Същото трябва да се повтори за задната и предната част в dev и prod среди.

Ще предоставя екранни снимки на настройките.

бекенда

CI/CD в Github действия за Flask+Angular проект

Входния

CI/CD в Github действия за Flask+Angular проект
Важно уточнение. Всички URL адреси ще бъдат проксирани към контейнера на интерфейса, с изключение на тези, които започват с /api/ - те ще бъдат проксирани към задния контейнер (така в задния контейнер, всички манипулатори трябва да започват с /api/).

Резултати от

Сега нашият сайт трябва да е достъпен на helloworld.ru и dev.helloworld.ru (съответно производствени и разработчици).

Като цяло научихме как да подготвим просто приложение във Flask и Angular и да настроим тръбопровод в Github Actions, за да го внедрим на сървър, работещ с Plesk.

Ще дублирам връзките към хранилищата с кода: бекенд, интерфейс.

Източник: www.habr.com

Добавяне на нов коментар