
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: , .
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.
В hai un ficheiro Readme.md cunha descrición detallada da estrutura e instrucións para executar o proxecto.
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.
aínda máis fácil, só hai un problema send_mail_task.
No cartafol hai dous subcartafoles:
dockercon dous Dockerfiles (base.dockerfilepara construír unha imaxe base que raramente cambia eDockerfilepara 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.ymlcrear unha base de datos local para o desenvolvemento;docker-compose.local.workers.ymlpara a crianza local do traballador, base de datos, Redis e RabbitMQ;docker-compose.test.ymlpara realizar probas durante a implantación;docker-compose.ymlpara o despregamento.
E o último cartafol que nos interesa... . 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
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:

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:
Dockerpara xestionar e mostrar visualmente o estado dos contedores no panel de administración de Plesk;Gitpara configurar o paso de implantación no servidor;Let's Encryptpara xerar (e renovar automaticamente) certificados TLS gratuítos;Firewallpara configurar o filtrado do tráfico entrante.
Pode instalalos a través do panel de administración de Plesk na sección Extensións:

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.
- Cree unha subscrición para o dominio helloworld.ru e especifique o contrasinal de inicio de sesión para o usuario do sistema:

Marque a caixa na parte inferior da páxina Protexe o dominio con Let's Encryptse queremos configurar HTTPS para o sitio:
- A continuación, nesta subscrición, crea un subdominio dev.helloworld.ru (para o que tamén podes emitir un certificado TLS gratuíto):

Instalación de compoñentes do servidor
Temos un servidor con OS Debian Estiramento 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 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.
Instrucións detalladas sobre a instalación de Postgres en Debian Hai moito diso en internet (), 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 : 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 intermediario de mensaxes para Celery. Está instalado 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.
- Imos a Plesk, imos á sección Extensións, buscamos a extensión Docker e instalamos (necesitamos unha versión gratuíta):

- Vaia á extensión instalada, busque a imaxe a través da busca
redis bitnamie instala a última versión:
- 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:

- 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:

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:
- repositorio Docker protexido con contrasinal accesible nun subdominio ;
- IU para ver imaxes no repositorio, dispoñible en .
Para iso:
- 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.
- Engade o ficheiro ao cartafol do subdominio docker.helloworld.ru
docker-compose.ymlcon 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' - 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 - Recollida e levantamento de contedores:
docker-compose up -d - 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:

E engade unha regra para proxy o tráfico entrante ao noso contedor:

- 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 - Comprobemos tamén o funcionamento do subdominio docker-ui.helloworld.ru:

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):
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.
- Ir a Ferramentas e configuración > Configuración > Firewall:

- 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
- Tamén engadiremos unha regra que abrirá os portos PostgreSQL e os paneis de xestión de RabbitMQ ao mundo exterior:

- Aplica as regras usando o botón Aplicar cambios:

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.
- Imos á subscrición do noso sitio web de Helloworld e imos á subsección de Git:

- Insira unha ligazón ao noso repositorio Github no campo "Repositorio Git remoto" e cambia o cartafol predeterminado
httpdocsa outro (p. ex./httpdocs/hw_back):
- Copia a chave pública SSH do paso anterior e está na configuración de Github.
- 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):
- 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 casoprod;
{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 - 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 .
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: : 8443 ou :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
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

Interface

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: , .
Fonte: www.habr.com
