
Neste artigo, compartilharei minha experiência de configuração de CI/CD usando o Plesk Control Panel e o Github Actions. Hoje vamos aprender como implantar um projeto simples com o nome descomplicado "Helloworld". Ele é escrito na estrutura Flask Python, com trabalhadores Celery e um frontend Angular 8.
Links para repositórios: , .
Na primeira parte do artigo, veremos nosso projeto e suas partes. Na segunda, descobriremos como configurar o Plesk e instalar as extensões e componentes necessários (DB, RabbitMQ, Redis, Docker, etc.).
Na terceira parte, finalmente descobriremos como configurar um pipeline para implantar nosso projeto em um servidor em um ambiente de desenvolvimento e produção. E então vamos lançar o site no servidor.
E sim, esqueci de me apresentar. Meu nome é Oleg Borzov, sou desenvolvedor fullstack na equipe de CRM para gerentes de hipotecas da Domclick.
Visão geral do projeto
Primeiro, vamos olhar para dois repositórios de projeto - back-end e front-end - e examinar o código.
Back-end: Frasco + Aipo
Para a parte de trás, peguei um monte bastante popular entre os desenvolvedores Python: a estrutura Flask (para a API) e Celery (para a fila de tarefas). SQLAchemy é usado como ORM. O alambique é usado para migrações. Para validação JSON em handles - Marshmallow.
В existe um arquivo Readme.md com uma descrição detalhada da estrutura e instruções para executar o projeto.
bastante simples, consiste em 6 canetas:
/ping- para verificar a disponibilidade;- trata de registro, autorização, desautorização e obtenção de um usuário autorizado;
- um identificador de e-mail que coloca uma tarefa na fila do aipo.
ainda mais fácil, só há um problema send_mail_task.
Na pasta existem duas subpastas:
dockercom dois Dockerfiles (base.dockerfilepara construir uma imagem base que raramente muda eDockerfilepara montagens principais);.env_files- com arquivos com variáveis de ambiente para diferentes ambientes.
Existem quatro arquivos docker-compose na raiz do projeto:
docker-compose.local.db.ymllevantar um banco de dados local para desenvolvimento;docker-compose.local.workers.ymlpara levantamento local do worker, banco de dados, Redis e RabbitMQ;docker-compose.test.ymlpara executar testes durante a implantação;docker-compose.ymlpara implantação.
E a última pasta em que estamos interessados - . Ele contém scripts de shell para implantação:
deploy.sh— lançamento da migração e implantação. Executa no servidor após construir e executar testes no Github Actions;rollback.sh- reversão de contêineres para a versão anterior do assembly;curl_tg.sh- envio de notificações de implantação para o Telegram.
Front-end em Angular
muito mais simples do que o de Beck. A frente é composta por três páginas:
- Página principal com formulário para envio de e-mail e botão de saída.
- Página de login.
- Página de registro.
A página principal parece ascética:

Existem dois arquivos na raiz Dockerfile и docker-compose.yml, bem como a pasta familiar .ci-cd com um pouco menos de scripts do que no repositório anterior (scripts removidos para execução de testes).
Iniciando um projeto no Plesk
Vamos começar configurando o Plesk e criando uma assinatura para nosso site.
Instalando extensões
No Plesk, precisamos de quatro extensões:
Dockerpara gerenciar e exibir visualmente o status dos contêineres no painel de administração do Plesk;Gitconfigurar a etapa de implantação no servidor;Let's Encryptpara gerar (e renovar automaticamente) certificados TLS gratuitos;Firewallpara configurar a filtragem do tráfego de entrada.
Você pode instalá-los através do painel de administração do Plesk na seção Extensões:

Não vamos considerar as configurações detalhadas para extensões, as configurações padrão servirão para nossos propósitos de demonstração.
Crie uma assinatura e um site
Em seguida, precisamos criar uma assinatura para nosso site helloworld.ru e adicionar o subdomínio dev.helloworld.ru lá.
- Crie uma assinatura para o domínio helloworld.ru e especifique a senha de login para o usuário do sistema:

Marque a caixa na parte inferior da página Proteja o domínio com Let's Encryptse quisermos configurar HTTPS para o site:
- Em seguida, nesta assinatura, crie um subdomínio dev.helloworld.ru (para o qual você também pode emitir um certificado TLS gratuito):

Instalando componentes do servidor
Temos um servidor com OS Debian Trecho 9.12 e painel de controle instalado Plesk Obsidiana 18.0.27.
Precisamos instalar e configurar para o nosso projeto:
- PostgreSQL (no nosso caso, haverá um servidor com dois bancos de dados para ambientes dev e prod).
- RabbitMQ (mesmo, mesma instância com diferentes vhosts para ambientes).
- Duas instâncias do Redis (para ambientes de desenvolvimento e produção).
- Docker Registry (para armazenamento local de imagens Docker construídas).
- Interface do usuário para o registro do Docker.
PostgreSQL
O Plesk já vem com o PostgreSQL DBMS, mas não a versão mais recente (no momento em que escrevi o Plesk Obsidian Postgres versões 8.4–10.8). Queremos a versão mais recente do nosso aplicativo (12.3 no momento em que este livro foi escrito), então vamos instalá-lo manualmente.
Instruções detalhadas sobre como instalar o Postgres em Debian Há muito disso na internet (), então não vou descrevê-los em detalhes, apenas 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
Considerando que o PostgreSQL possui configurações padrão bastante medíocres, é necessário corrigir a configuração. Isso vai nos ajudar : você precisa dirigir nos parâmetros do seu servidor e substituir as configurações no arquivo /etc/postgresql/12/main/postgresql.confaos oferecidos. Deve-se observar aqui que essas calculadoras não são mágicas e a base deve ser ajustada com mais precisão, com base no hardware, no aplicativo e na complexidade da consulta. Mas isso é o suficiente para começar.
Além das configurações propostas pela calculadora, também alteramos postgresql.confa porta padrão 5432 para outra (no nosso exemplo - 53983).
Após alterar o arquivo de configuração, reinicie o postgresql-server com o comando:
service postgresql restart
Instalamos e configuramos o PostgreSQL. Agora vamos criar um banco de dados, usuários para ambientes de desenvolvimento e produção, e dar aos usuários direitos para gerenciar o banco de dados:
$ 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
Vamos prosseguir com a instalação do RabbitMQ, um broker de mensagens para o Celery. Ele é instalado em Debian É bastante simples:
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
Após a instalação, precisamos criar vhosts, usuários e conceder os direitos necessários:
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 vamos instalar e configurar o último componente do nosso aplicativo - Redis. Ele será usado como um back-end para armazenar os resultados das tarefas do Celery.
Levantaremos dois containers Docker com Redis para ambientes dev e prod usando a extensão Docker para Plesk.
- Vamos ao Plesk, vamos à seção Extensões, procuramos a extensão Docker e a instalamos (precisamos de uma versão gratuita):

- Vá para a extensão instalada, encontre a imagem através da pesquisa
redis bitnamie instale a versão mais recente:
- Entramos no contêiner baixado e ajustamos a configuração: especifique a porta, o tamanho máximo de RAM alocado, a senha nas variáveis de ambiente e monte o volume:

- Executamos as etapas 2 a 3 para o contêiner prod, nas configurações alteramos apenas os parâmetros: porta, senha, tamanho da RAM e caminho para a pasta do volume no servidor:

Registro Docker
Além dos serviços básicos, seria bom colocar seu próprio repositório de imagens do Docker no servidor. Felizmente, o espaço do servidor agora é bastante barato (certamente mais barato do que uma assinatura do DockerHub) e o processo de configuração de um repositório privado é muito simples.
Queremos ter:
- repositório Docker protegido por senha acessível em um subdomínio ;
- UI para visualização de imagens no repositório, disponível em .
Para fazer isso:
- Vamos criar dois subdomínios no Plesk em nossa assinatura: docker.helloworld.ru e docker-ui.helloworld.ru e configurar os certificados Let's Encrypt para eles.
- Adicione o arquivo à pasta do subdomínio docker.helloworld.ru
docker-compose.ymlcom conteúdo como 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' - Sob SSH, iremos gerar o arquivo .htpasswd para autorização Basic no repositório Docker:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Recolher e levantar recipientes:
docker-compose up -d - E precisamos redirecionar o Nginx para nossos contêineres. Isso pode ser feito através do Plesk.
As etapas a seguir precisam ser executadas para os subdomínios docker.helloworld.ru e docker-ui.helloworld.ru:
Na seção Dev Tools nosso site ir para Regras de proxy do Docker:

E adicione uma regra para fazer proxy do tráfego de entrada para nosso contêiner:

- Verificamos se podemos fazer login em nosso contêiner a partir da 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 - Vamos também verificar o funcionamento do subdomínio docker-ui.helloworld.ru:

Ao clicar em Procurar repositórios, o navegador exibirá uma janela de autorização onde será necessário inserir o nome de usuário e a senha do repositório. Após isso, seremos redirecionados para uma página com uma lista de repositórios (por enquanto, ela estará vazia para você):
Abrindo portas no Firewall Plesk
Depois de instalar e configurar os componentes, precisamos abrir portas para que os componentes sejam acessíveis a partir de contêineres Docker e da rede externa.
Vamos ver como fazer isso usando a extensão do Firewall para Plesk que instalamos anteriormente.
- Ir para Ferramentas e configurações > Configurações > Firewall:

- Ir para Modificar regras de firewall do Plesk > Adicionar regra personalizada e abra as seguintes portas TCP para a sub-rede Docker (172.0.0.0 / 8):
CoelhoMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redes: 32785, 32786
- Também adicionaremos uma regra que abrirá portas PostgreSQL e painéis de gerenciamento RabbitMQ para o mundo externo:

- Aplique as regras usando o botão Aplicar alterações:

Configurando CI/CD no Github Actions
Vamos à parte mais interessante - configurar um pipeline de integração contínua e entregar nosso projeto ao servidor.
Este pipeline será composto por duas partes:
- construindo uma imagem e executando testes (para o backend) - no lado do Github;
- executando migrações (para o back-end) e implantando contêineres - no servidor.
Implantar no Plesk
Vamos lidar primeiro com o segundo ponto (porque o primeiro depende disso).
Vamos configurar o processo de implantação usando a extensão Git para Plesk.
Considere um exemplo com um ambiente Prod para um repositório Backend.
- Vamos para a assinatura do nosso site Helloworld e vamos para a subseção Git:

- Insira um link para nosso repositório Github no campo "Repositório Git Remoto" e altere a pasta padrão
httpdocspara outro (ex./httpdocs/hw_back):
- Copie a chave pública SSH da etapa anterior e está nas configurações do Github.
- Clique em OK na tela do passo 2, após o qual seremos redirecionados para a página do repositório no Plesk. Agora precisamos configurar o repositório para ser atualizado nos commits do branch master. Para fazer isso, vá para Configurações do repositório e salve o valor
Webhook URL(vamos precisar dele mais tarde ao configurar as ações do Github):
- No campo Ações da tela do parágrafo anterior, insira o script para iniciar a implantação:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}em que:
{REPOSITORY_ABSOLUTE_PATH}- caminho para a pasta prod do repositório back-end no servidor;
{ENV}- ambiente (dev/prod), no nosso casoprod;
{DOCKER_REGISTRY_HOST}- o host do nosso repositório docker
{TG_BOT_TOKEN}— Token do bot do Telegram;
{TG_CHAT_ID}— ID do chat/canal para envio de notificações.Exemplo de roteiro:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - Adicione um usuário de nossa assinatura ao grupo Docker (para que ele possa gerenciar contêineres):
sudo usermod -aG docker helloworld_admin
O ambiente de desenvolvimento para o repositório de back-end e o front-end são configurados da mesma maneira.
Pipeline de implantação no Github Actions
Vamos configurar a primeira parte do nosso pipeline de CI/CD no Github Actions.
Backend
O pipeline é descrito em .
Mas antes de analisá-lo, vamos preencher as variáveis secretas que precisamos no Github. Para fazer isso, vá para Configurações -> Segredos:
DOCKER_REGISTRY- o host do nosso repositório Docker (docker.helloworld.ru);DOCKER_LOGIN- faça login no repositório do Docker;DOCKER_PASSWORD- senha para ele;DEPLOY_HOST— host onde o painel de administração do Plesk está disponível (exemplo: : 8443 ou :8443);DEPLOY_BACK_PROD_TOKEN- um token para implantação no repositório prod no servidor (obtemos em Implantação no Plesk p. 4);DEPLOY_BACK_DEV_TOKEN- token para implantação no repositório dev no servidor.
O processo de implantação é simples e consiste em três etapas principais:
- construir e publicar a imagem em nosso repositório;
- executar testes em um contêiner com base em uma imagem recém-criada;
- implantação no ambiente desejado dependendo da ramificação (dev/master).
Frontend
pouco diferente do de Beck. Falta uma etapa com execução de testes e alteração dos nomes dos tokens para implantação. A propósito, os segredos do repositório frontal precisam ser preenchidos separadamente.
Configuração do site
Proxy de tráfego através do Nginx
Bem, chegamos ao fim. Resta apenas configurar o proxy do tráfego de entrada e saída para nosso contêiner por meio do Nginx. Já cobrimos esse processo na etapa 5 da configuração do Docker Registry. O mesmo deve ser repetido para as partes traseira e frontal em ambientes de desenvolvimento e produção.
Fornecerei capturas de tela das configurações.
Backend

Frontend

Esclarecimento importante. Todos os URLs terão proxy para o contêiner de front-end, exceto aqueles que começam com /api/ - eles serão proxy para o contêiner traseiro (assim no contêiner traseiro, todos os manipuladores devem começar com /api/).
Resultados de
Agora nosso site deve estar disponível em helloworld.ru e dev.helloworld.ru (prod- e dev-environments, respectivamente).
No total, aprendemos como preparar um aplicativo simples em Flask e Angular e configurar um pipeline no Github Actions para implementá-lo em um servidor executando o Plesk.
Vou duplicar os links para os repositórios com o código: , .
Fonte: habr.com
