CI/CD en accións de Github para un proxecto Flask+Angular

CI/CD en accións de Github para un proxecto Flask+Angular
Neste artigo, compartirei a miña experiencia na configuración de CI/CD usando o Panel de control de Plesk e as accións de Github. Hoxe aprenderemos a implementar un proxecto sinxelo co nome sinxelo "Helloworld". Está escrito no framework Flask Python, con traballadores de Celery e unha interface Angular 8.

Ligazóns a repositorios: backend, frontend.

Na primeira parte do artigo, analizaremos o noso proxecto e as súas partes. No segundo, descubriremos como configurar Plesk e instalar as extensións e compoñentes necesarios (DB, RabbitMQ, Redis, Docker, etc.).

Na terceira parte, finalmente descubriremos como configurar unha canalización para implementar o noso proxecto nun servidor nun ambiente de desenvolvemento e produción. E despois lanzaremos o sitio no servidor.

E si, esquecín presentarme. Chámome Oleg Borzov, son un programador fullstack no equipo de CRM para xestores de hipotecas de Domclick.

Descrición xeral do proxecto

En primeiro lugar, vexamos dous repositorios de proxectos - backend e front - e repasemos o código.

Fondo: frasco + apio

Para a parte traseira, tomei un grupo que é bastante popular entre os desenvolvedores de Python: o framework Flask (para a API) e Celery (para a cola de tarefas). SQLAchemy úsase como ORM. O alambic úsase para as migracións. Para validación JSON en controladores - Marshmallow.

В repositorios hai un ficheiro Readme.md cunha descrición detallada da estrutura e instrucións para executar o proxecto.

API de parte web bastante sinxelo, consta de 6 bolígrafos:

  • /ping - para comprobar a dispoñibilidade;
  • manexa o rexistro, autorización, desautorización e obtención dun usuario autorizado;
  • un identificador de correo electrónico que pon unha tarefa na cola de apio.

Parte de apio aínda máis fácil, só hai un problema send_mail_task.

No cartafol /conf hai dous subcartafoles:

  • docker con dous Dockerfiles (base.dockerfile para construír unha imaxe base que raramente cambia e Dockerfile para conxuntos principais);
  • .env_files - con ficheiros con variables de ambiente para diferentes ambientes.

Hai catro ficheiros docker-compose na raíz do proxecto:

  • docker-compose.local.db.yml crear unha base de datos local para o desenvolvemento;
  • docker-compose.local.workers.yml para a crianza local do traballador, base de datos, Redis e RabbitMQ;
  • docker-compose.test.yml para realizar probas durante a implantación;
  • docker-compose.yml para o despregamento.

E o último cartafol que nos interesa... .ci-cd. Contén scripts de shell para a súa implantación:

  • deploy.sh — Lanzamento da migración e despregamento. Execútase no servidor despois de construír e executar probas en Github Actions;
  • rollback.sh - retrotraer os contedores á versión anterior da montaxe;
  • curl_tg.sh - envío de notificacións de implantación a Telegram.

Frontend en Angular

Repositorio con fronte moito máis sinxelo que o de Beck. A fronte consta de tres páxinas:

  • Páxina principal cun formulario para enviar correo electrónico e un botón de saída.
  • Páxina de inicio de sesión.
  • Páxina de rexistro.

A páxina principal parece ascética:

CI/CD en accións de Github para un proxecto Flask+Angular
Hai dous ficheiros na raíz Dockerfile и docker-compose.yml, así como o cartafol coñecido .ci-cd con un pouco menos de scripts que no repositorio posterior (elimináronse scripts para realizar probas).

Comezando un proxecto en Plesk

Comecemos configurando Plesk e creando unha subscrición para o noso sitio.

Instalación de extensións

En Plesk, necesitamos catro extensións:

  • Docker para xestionar e mostrar visualmente o estado dos contedores no panel de administración de Plesk;
  • Git para configurar o paso de implantación no servidor;
  • Let's Encrypt para xerar (e renovar automaticamente) certificados TLS gratuítos;
  • Firewall para configurar o filtrado do tráfico entrante.

Pode instalalos a través do panel de administración de Plesk na sección Extensións:

CI/CD en accións de Github para un proxecto Flask+Angular
Non consideraremos a configuración detallada das extensións, a configuración predeterminada servirá para os nosos fins de demostración.

Crea unha subscrición e un sitio

A continuación, necesitamos crear unha subscrición para o noso sitio web helloworld.ru e engadir alí o subdominio dev.helloworld.ru.

  1. Cree unha subscrición para o dominio helloworld.ru e especifique o contrasinal de inicio de sesión para o usuario do sistema:

    CI/CD en accións de Github para un proxecto Flask+Angular
    Marque a caixa na parte inferior da páxina Protexe o dominio con Let's Encryptse queremos configurar HTTPS para o sitio:

    CI/CD en accións de Github para un proxecto Flask+Angular

  2. A continuación, nesta subscrición, crea un subdominio dev.helloworld.ru (para o que tamén podes emitir un certificado TLS gratuíto):

    CI/CD en accións de Github para un proxecto Flask+Angular

Instalación de compoñentes do servidor

Temos un servidor con OS Debian Stretch 9.12 e panel de control instalado Plesk Obsidian 18.0.27.

Necesitamos instalar e configurar para o noso proxecto:

  • PostgreSQL (no noso caso, haberá un servidor con dúas bases de datos para entornos de desenvolvemento e produción).
  • RabbitMQ (mesmo, mesma instancia con vhosts diferentes para ambientes).
  • Dúas instancias de Redis (para entornos de desenvolvemento e produción).
  • Rexistro de Docker (para o almacenamento local de imaxes de Docker construídas).
  • IU para o rexistro de Docker.

PostgreSQL

Plesk xa vén con PostgreSQL DBMS, pero non a última versión (no momento de escribir Plesk Obsidian apoiado versións de Postgres 8.4–10.8). Queremos a última versión para a nosa aplicación (12.3 no momento de escribir este artigo), polo que instalarémola manualmente.

Hai moitas instrucións detalladas para instalar Postgres en Debian na rede (exemplo), así que non os describirei en detalle, só darei os comandos:

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

Tendo en conta que PostgreSQL ten unha configuración predeterminada bastante mediocre, é necesario corrixir a configuración. Isto axudaranos calculadora: necesitas controlar os parámetros do teu servidor e substituír a configuración do ficheiro /etc/postgresql/12/main/postgresql.confaos ofrecidos. Cabe sinalar aquí que tales calculadoras non son unha bala máxica e que a base debería axustarse con máis precisión, en función do seu hardware, aplicación e complexidade de consulta. Pero isto é suficiente para comezar.

Ademais dos axustes propostos pola calculadora, tamén cambiamos postgresql.confo porto predeterminado 5432 a outro (no noso exemplo - 53983).

Despois de cambiar o ficheiro de configuración, reinicie postgresql-server co comando:

service postgresql restart

Instalamos e configuramos PostgreSQL. Agora imos crear unha base de datos, usuarios para ambientes de desenvolvemento e produción, e darlle aos usuarios dereitos para xestionar a base de datos:

$ 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

CoelloMQ

Pasemos á instalación de RabbitMQ, un corredor de mensaxes para Celery. Instalalo en Debian é bastante sinxelo:

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

Despois da instalación, necesitamos crear vhosts, usuarios e conceder os dereitos necesarios:

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

Agora imos instalar e configurar o último compoñente para a nosa aplicación - Redis. Usarase como backend para almacenar os resultados das tarefas de Celery.

Crearemos dous contedores Docker con Redis para entornos de desenvolvemento e produción usando a extensión Docker para Plesk.

  1. Imos a Plesk, imos á sección Extensións, buscamos a extensión Docker e instalamos (necesitamos unha versión gratuíta):

    CI/CD en accións de Github para un proxecto Flask+Angular

  2. Vaia á extensión instalada, busque a imaxe a través da busca redis bitnami e instala a última versión:

    CI/CD en accións de Github para un proxecto Flask+Angular

  3. Entramos no contedor descargado e axustamos a configuración: especificamos o porto, o tamaño máximo de RAM asignado, o contrasinal nas variables de ambiente e montamos o volume:

    CI/CD en accións de Github para un proxecto Flask+Angular

  4. Realizamos os pasos 2-3 para o contenedor de produtos, na configuración só cambiamos os parámetros: porto, contrasinal, tamaño da RAM e camiño ao cartafol de volumes do servidor:

    CI/CD en accións de Github para un proxecto Flask+Angular

Rexistro Docker

Ademais dos servizos básicos, sería bo poñer o teu propio repositorio de imaxes Docker no servidor. Afortunadamente, agora o espazo do servidor é bastante barato (sen dúbida máis barato que unha subscrición a DockerHub) e o proceso de configuración dun repositorio privado é moi sinxelo.

Queremos ter:

Para iso:

  1. Creemos dous subdominios en Plesk na nosa subscrición: docker.helloworld.ru e docker-ui.helloworld.ru, e configuremos os certificados Let's Encrypt para eles.
  2. Engade o ficheiro ao cartafol do subdominio docker.helloworld.ru docker-compose.yml con contido coma este:
    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. En SSH, xeraremos o ficheiro .htpasswd para a autorización básica no repositorio de Docker:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Recollida e levantamento de contedores:
    docker-compose up -d
  5. E necesitamos redirixir Nginx aos nosos contedores. Isto pódese facer a través de Plesk.

Deben realizarse os seguintes pasos para os subdominios docker.helloworld.ru e docker-ui.helloworld.ru:

Na sección Ferramentas Dev ir ao noso sitio Regras do proxy de Docker:

CI/CD en accións de Github para un proxecto Flask+Angular
E engade unha regra para proxy o tráfico entrante ao noso contedor:

CI/CD en accións de Github para un proxecto Flask+Angular

  1. Comprobamos que podemos iniciar sesión no noso contedor desde a 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. Comprobemos tamén o funcionamento do subdominio docker-ui.helloworld.ru:

    CI/CD en accións de Github para un proxecto Flask+Angular
    Cando fas clic en Explorar repositorios, o navegador mostrará unha xanela de autorización na que terás que introducir o nome de usuario e o contrasinal do repositorio. Despois diso, trasladarémonos a unha páxina cunha lista de repositorios (polo momento, estará baleira para ti):

    CI/CD en accións de Github para un proxecto Flask+Angular

Apertura de portos en Plesk Firewall

Despois de instalar e configurar os compoñentes, necesitamos abrir portos para que os compoñentes sexan accesibles desde os contedores Docker e a rede externa.

Vexamos como facelo usando a extensión Firewall para Plesk que instalamos anteriormente.

  1. Ir a Ferramentas e configuración > Configuración > Firewall:
    CI/CD en accións de Github para un proxecto Flask+Angular
  2. Ir a Modificar as regras do Firewall de Plesk > Engadir unha regra personalizada e abra os seguintes portos TCP para a subrede Docker (172.0.0.0 / 8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD en accións de Github para un proxecto Flask+Angular

  3. Tamén engadiremos unha regra que abrirá os portos PostgreSQL e os paneis de xestión de RabbitMQ ao mundo exterior:

    CI/CD en accións de Github para un proxecto Flask+Angular

  4. Aplica as regras usando o botón Aplicar cambios:

    CI/CD en accións de Github para un proxecto Flask+Angular

Configurando CI/CD en Github Actions

Pasemos á parte máis interesante: configurar unha canalización de integración continua e entregar o noso proxecto ao servidor.

Esta canalización constará de dúas partes:

  • construír unha imaxe e realizar probas (para o backend) - no lado de Github;
  • executando migracións (para o backend) e despregando contedores no servidor.

Implementar en Plesk

Ocupémonos primeiro do segundo punto (porque o primeiro depende del).

Configuraremos o proceso de implantación usando a extensión Git para Plesk.

Considere un exemplo cun ambiente Prod para un repositorio de backend.

  1. Imos á subscrición do noso sitio web de Helloworld e imos á subsección de Git:

    CI/CD en accións de Github para un proxecto Flask+Angular

  2. Insira unha ligazón ao noso repositorio Github no campo "Repositorio Git remoto" e cambia o cartafol predeterminado httpdocs a outro (p. ex. /httpdocs/hw_back):

    CI/CD en accións de Github para un proxecto Flask+Angular

  3. Copia a chave pública SSH do paso anterior e engadir está na configuración de Github.
  4. Fai clic en Aceptar na pantalla no paso 2, despois de que seremos redirixidos á páxina do repositorio en Plesk. Agora necesitamos configurar o repositorio para que se actualice nos commits na rama mestra. Para iso, vai a Configuración do repositorio e gardar o valor Webhook URL (necesitarémolo máis tarde cando configuremos Github Actions):

    CI/CD en accións de Github para un proxecto Flask+Angular

  5. No campo Accións da pantalla do parágrafo anterior, introduza o script para iniciar a implementación:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    en que:

    {REPOSITORY_ABSOLUTE_PATH} - ruta ao cartafol prod do repositorio de backend no servidor;
    {ENV} - ambiente (dev/prod), no noso caso prod;
    {DOCKER_REGISTRY_HOST} - o anfitrión do noso repositorio docker
    {TG_BOT_TOKEN} — Token de bot de Telegram;
    {TG_CHAT_ID} — ID do chat/canle para enviar notificacións.

    Exemplo de guión:

    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. Engade un usuario da nosa subscrición ao grupo Docker (para que poida xestionar contedores):
    sudo usermod -aG docker helloworld_admin

O ambiente de desenvolvemento para o repositorio de backend e o frontend confírmanse da mesma forma.

Canalización de implantación en Github Actions

Pasemos a configurar a primeira parte da nosa canalización de CI/CD en Github Actions.

motor

A canalización descríbese en ficheiro deploy.yml.

Pero antes de analizalo, imos cubrir as variables secretas que necesitamos en Github. Para iso, vai a Configuración -> Segredos:

  • DOCKER_REGISTRY - o anfitrión do noso repositorio Docker (docker.helloworld.ru);
  • DOCKER_LOGIN - iniciar sesión no repositorio de Docker;
  • DOCKER_PASSWORD - contrasinal para el;
  • DEPLOY_HOST — host onde o panel de administración de Plesk está dispoñible (exemplo: olaworld.com: 8443 ou 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - un token para a implantación no repositorio de produtos no servidor (obtemos en Implementación en Plesk, p. 4);
  • DEPLOY_BACK_DEV_TOKEN - token para a súa implantación no repositorio de desenvolvemento no servidor.

O proceso de implantación é sinxelo e consta de tres pasos principais:

  • construír e publicar a imaxe no noso repositorio;
  • realizar probas nun contedor baseado nunha imaxe recén construída;
  • despregamento no ambiente desexado dependendo da rama (dev/master).

Interface

O ficheiro deploy.yml para o repositorio frontal pouco diferente ao de Beck. Falta un paso para executar probas e cambia os nomes dos tokens para a súa implantación. Por certo, os segredos para o repositorio frontal deben cubrirse por separado.

Configuración do sitio

Proxy de tráfico a través de Nginx

Ben, chegamos ao final. Só queda configurar o proxy do tráfico entrante e saínte ao noso contedor a través de Nginx. Xa cubrimos este proceso no paso 5 da configuración do Rexistro de Docker. O mesmo debe repetirse para as partes traseira e frontal en ambientes de desenvolvemento e produción.

Vou proporcionar capturas de pantalla da configuración.

motor

CI/CD en accións de Github para un proxecto Flask+Angular

Interface

CI/CD en accións de Github para un proxecto Flask+Angular
Importante aclaración. Todos os URL serán enviados ao contenedor frontend, excepto os que comezan por /api/ - estarán aproximados ao recipiente traseiro (así no contedor traseiro, todos os manipuladores deben comezar /api/).

Resultados de

Agora o noso sitio debería estar dispoñible en helloworld.ru e dev.helloworld.ru (entornos de produción e desenvolvemento, respectivamente).

En total, aprendemos a preparar unha aplicación sinxela en Flask e Angular e a configurar unha canalización en Github Actions para implementala nun servidor que executa Plesk.

Vou duplicar as ligazóns aos repositorios co código: backend, frontend.

Fonte: www.habr.com

Engadir un comentario