
En aquest article, compartiré la meva experiència de configuració de CI/CD mitjançant el tauler de control de Plesk i les accions de Github. Avui aprendrem a desplegar un projecte senzill amb el nom senzill "Helloworld". Està escrit al framework Flask Python, amb treballadors de Celery i una interfície Angular 8.
Enllaços als repositoris: , .
A la primera part de l'article, veurem el nostre projecte i les seves parts. En el segon, descobrirem com configurar Plesk i instal·lar les extensions i components necessaris (DB, RabbitMQ, Redis, Docker, etc.).
A la tercera part, finalment descobrirem com configurar un pipeline per desplegar el nostre projecte a un servidor en un entorn de desenvolupament i producció. I després llançarem el lloc al servidor.
I sí, m'he oblidat de presentar-me. Em dic Oleg Borzov, sóc desenvolupador fullstack a l'equip de CRM per a gestors d'hipoteques de Domclick.
Descripció general del projecte
En primer lloc, mirem dos repositoris del projecte: backend i front, i repassem el codi.
Backend: Flask+Api
Per a la part posterior, vaig agafar un munt que és força popular entre els desenvolupadors de Python: el framework Flask (per a l'API) i Celery (per a la cua de tasques). SQLAchemy s'utilitza com a ORM. L'alambic s'utilitza per a les migracions. Per a la validació JSON a les nanses - Marshmallow.
В hi ha un fitxer Readme.md amb una descripció detallada de l'estructura i instruccions per executar el projecte.
bastant senzill, consta de 6 bolígrafs:
/ping- per comprovar la disponibilitat;- maneig de registre, autorització, desautorització i obtenció d'un usuari autoritzat;
- un controlador de correu electrònic que posa una tasca a la cua d'api.
encara més fàcil, només hi ha un problema send_mail_task.
A la carpeta hi ha dues subcarpetes:
dockeramb dos Dockerfiles (base.dockerfileper construir una imatge base que rarament canvia iDockerfileper a assemblees principals);.env_files- amb fitxers amb variables d'entorn per a diferents entorns.
Hi ha quatre fitxers docker-compose a l'arrel del projecte:
docker-compose.local.db.ymlcrear una base de dades local per al desenvolupament;docker-compose.local.workers.ymlper a la criança local del treballador, base de dades, Redis i RabbitMQ;docker-compose.test.ymlper executar proves durant el desplegament;docker-compose.ymlper al desplegament.
I l'última carpeta que ens interessa... . Conté scripts d'intèrpret d'ordres per al desplegament:
deploy.sh— Llançament de la migració i el desplegament. S'executa al servidor després de crear i executar proves a Github Actions;rollback.sh- retrocés dels contenidors a la versió anterior del conjunt;curl_tg.sh- enviament de notificacions de desplegament a Telegram.
Frontend a Angular
molt més senzill que el de Beck. El front consta de tres pàgines:
- Pàgina principal amb un formulari per enviar correu electrònic i un botó de sortida.
- Pàgina d'inici de sessió.
- Pàgina de registre.
La pàgina principal sembla ascètica:

Hi ha dos fitxers a l'arrel Dockerfile и docker-compose.yml, així com la carpeta familiar .ci-cd amb una mica menys d'scripts que al repositori posterior (s'han eliminat els scripts per executar proves).
Iniciant un projecte a Plesk
Comencem configurant Plesk i creant una subscripció per al nostre lloc.
Instal·lació d'extensions
A Plesk, necessitem quatre extensions:
Dockerper gestionar i mostrar visualment l'estat dels contenidors al tauler d'administració de Plesk;Gitper configurar el pas de desplegament al servidor;Let's Encryptper generar (i renovar automàticament) certificats TLS gratuïts;Firewallper configurar el filtratge del trànsit entrant.
Podeu instal·lar-los a través del tauler d'administració de Plesk a la secció Extensions:

No tindrem en compte la configuració detallada de les extensions, la configuració predeterminada servirà per als nostres propòsits de demostració.
Creeu una subscripció i un lloc
A continuació, hem de crear una subscripció per al nostre lloc web helloworld.ru i afegir-hi el subdomini dev.helloworld.ru.
- Creeu una subscripció per al domini helloworld.ru i especifiqueu la contrasenya d'inici de sessió per a l'usuari del sistema:

Marqueu la casella a la part inferior de la pàgina Assegureu el domini amb Let's Encryptsi volem configurar HTTPS per al lloc:
- A continuació, en aquesta subscripció, creeu un subdomini dev.helloworld.ru (per al qual també podeu emetre un certificat TLS gratuït):

Instal·lació de components del servidor
Tenim un servidor amb OS Debian Estirament 9.12 i el panell de control instal·lat Plesk Obsidian 18.0.27.
Hem d'instal·lar i configurar per al nostre projecte:
- PostgreSQL (en el nostre cas, hi haurà un servidor amb dues bases de dades per a entorns de desenvolupament i producció).
- RabbitMQ (la mateixa, mateixa instància amb diferents vhosts per a entorns).
- Dues instàncies de Redis (per a entorns de desenvolupament i producció).
- Docker Registry (per a l'emmagatzematge local d'imatges Docker construïdes).
- IU per al registre de Docker.
PostgreSQL
Plesk ja ve amb PostgreSQL DBMS, però no la versió més recent (en el moment d'escriure Plesk Obsidian versions de Postgres 8.4–10.8). Volem la darrera versió per a la nostra aplicació (12.3 en el moment d'escriure aquest article), així que l'instal·larem manualment.
Instruccions detallades sobre la instal·lació de Postgres a Debian n'hi ha molt a Internet (), així que no els descriuré en detall, només donaré les ordres:
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
Tenint en compte que PostgreSQL té una configuració predeterminada més aviat mediocre, cal corregir la configuració. Això ens ajudarà : heu de controlar els paràmetres del vostre servidor i substituir els paràmetres del fitxer /etc/postgresql/12/main/postgresql.confals que s'ofereixen. Cal assenyalar aquí que aquestes calculadores no són una bala màgica i la base s'hauria d'ajustar amb més precisió, en funció del vostre maquinari, aplicació i complexitat de la consulta. Però això és suficient per començar.
A més de les configuracions proposades per la calculadora, també hi canviem postgresql.confel port predeterminat 5432 a un altre (en el nostre exemple - 53983).
Després de canviar el fitxer de configuració, reinicieu postgresql-server amb l'ordre:
service postgresql restart
Hem instal·lat i configurat PostgreSQL. Ara creem una base de dades, usuaris per a entorns de desenvolupament i producció, i donem als usuaris drets per gestionar la base de dades:
$ 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
ConillMQ
Passem a la instal·lació de RabbitMQ, un intermediari de missatges per a Celery. Està instal·lat a Debian És força senzill:
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
Després de la instal·lació, hem de crear vhosts, usuaris i concedir els drets necessaris:
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
Ara instal·lem i configurem l'últim component de la nostra aplicació: Redis. S'utilitzarà com a backend per emmagatzemar els resultats de les tasques d'api.
Crearem dos contenidors Docker amb Redis per a entorns de desenvolupament i producció utilitzant l'extensió Docker per a Plesk.
- Anem a Plesk, anem a la secció Extensions, busquem l'extensió Docker i la instal·lem (necessitem una versió gratuïta):

- Aneu a l'extensió instal·lada, cerqueu la imatge mitjançant la cerca
redis bitnamii instal·leu la darrera versió:
- Entrem al contenidor descarregat i ajustem la configuració: especifiquem el port, la mida màxima de RAM assignada, la contrasenya a les variables d'entorn i muntem el volum:

- Realitzem els passos 2-3 per al contenidor de productes, a la configuració només canviem els paràmetres: port, contrasenya, mida de RAM i camí a la carpeta de volums del servidor:

Registre Docker
A més dels serveis bàsics, seria bo posar el vostre propi dipòsit d'imatges Docker al servidor. Afortunadament, ara l'espai del servidor és força barat (segurament més barat que una subscripció a DockerHub) i el procés de configuració d'un dipòsit privat és molt senzill.
Volem tenir:
- Repositori Docker protegit amb contrasenya accessible en un subdomini ;
- Interfície d'usuari per visualitzar imatges al repositori, disponible a .
Per a això:
- Creem dos subdominis a Plesk a la nostra subscripció: docker.helloworld.ru i docker-ui.helloworld.ru, i configurem els certificats Let's Encrypt per a ells.
- Afegiu el fitxer a la carpeta del subdomini docker.helloworld.ru
docker-compose.ymlamb contingut com aquest: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' - Sota SSH, generarem el fitxer .htpasswd per a l'autorització bàsica al repositori de Docker:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Recollir i aixecar contenidors:
docker-compose up -d - I hem de redirigir Nginx als nostres contenidors. Això es pot fer mitjançant Plesk.
Cal fer els passos següents per als subdominis docker.helloworld.ru i docker-ui.helloworld.ru:
A la secció Eines Dev el nostre lloc va a Regles de proxy Docker:

I afegiu una regla per enviar el trànsit entrant al nostre contenidor:

- Comprovem que podem iniciar sessió al nostre contenidor des de la 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 - Comprovem també el funcionament del subdomini docker-ui.helloworld.ru:

Quan feu clic a Explora repositoris, el navegador mostrarà una finestra d'autorització on haureu d'introduir el nom d'usuari i la contrasenya del repositori. Després d'això, serem transferits a una pàgina amb una llista de repositoris (de moment, estarà buida per a tu):
Obertura de ports a Plesk Firewall
Després d'instal·lar i configurar els components, hem d'obrir ports perquè els components siguin accessibles des dels contenidors Docker i la xarxa externa.
Vegem com fer-ho amb l'extensió del tallafoc per a Plesk que hem instal·lat anteriorment.
- Anar a Eines i configuració > Configuració > Tallafoc:

- Anar a Modifiqueu les regles del tallafoc de Plesk > Afegeix una regla personalitzada i obriu els ports TCP següents per a la subxarxa Docker (172.0.0.0 / 8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- També afegirem una regla que obrirà els ports PostgreSQL i els panells de gestió de RabbitMQ al món exterior:

- Apliqueu les regles amb el botó Aplica els canvis:

Configuració de CI/CD a Github Actions
Anem a la part més interessant: configurar un pipeline d'integració contínua i lliurar el nostre projecte al servidor.
Aquesta canalització constarà de dues parts:
- crear una imatge i executar proves (per al backend) - al costat de Github;
- executant migracions (per al backend) i desplegant contenidors al servidor.
Desplegueu a Plesk
Tractem primer el segon punt (perquè el primer en depèn).
Configurarem el procés de desplegament mitjançant l'extensió Git per a Plesk.
Penseu en un exemple amb un entorn Prod per a un dipòsit de backend.
- Anem a la subscripció del nostre lloc web Helloworld i anem a la subsecció Git:

- Inseriu un enllaç al nostre dipòsit Gitub al camp "Repositori Git remot" i canvieu la carpeta predeterminada
httpdocsa un altre (p. ex./httpdocs/hw_back):
- Copieu la clau pública SSH del pas anterior i està a la configuració de Github.
- Feu clic a D'acord a la pantalla al pas 2, després serem redirigits a la pàgina del repositori de Plesk. Ara hem de configurar el repositori perquè s'actualitzi en commits a la branca mestra. Per fer-ho, aneu a Configuració del repositori i guarda el valor
Webhook URL(el necessitarem més endavant quan configurem les accions de Github):
- Al camp Accions de la pantalla del paràgraf anterior, introduïu l'script per iniciar el desplegament:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}on:
{REPOSITORY_ABSOLUTE_PATH}- camí a la carpeta prod del dipòsit de fons del servidor;
{ENV}- entorn (dev/prod), en el nostre casprod;
{DOCKER_REGISTRY_HOST}- l'amfitrió del nostre repositori Docker
{TG_BOT_TOKEN}— Fitxa de bot de Telegram;
{TG_CHAT_ID}— ID del xat/canal per enviar notificacions.Exemple de guió:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - Afegiu un usuari de la nostra subscripció al grup Docker (perquè pugui gestionar els contenidors):
sudo usermod -aG docker helloworld_admin
L'entorn de desenvolupament per al dipòsit de backend i el frontend es configuren de la mateixa manera.
Canal de desplegament a Github Actions
Passem a configurar la primera part del nostre pipeline CI/CD a Github Actions.
Backend
La canonada es descriu a .
Però abans d'analitzar-lo, omplim les variables secretes que necessitem a Github. Per fer-ho, aneu a Configuració -> Secrets:
DOCKER_REGISTRY- l'amfitrió del nostre dipòsit Docker (docker.helloworld.ru);DOCKER_LOGIN- inicieu sessió al repositori de Docker;DOCKER_PASSWORD- contrasenya;DEPLOY_HOST— amfitrió on el tauler d'administració de Plesk està disponible (exemple: : 8443 o :8443);DEPLOY_BACK_PROD_TOKEN- un testimoni per al desplegament al prod-repository del servidor (l'hem obtingut a Deployment in Plesk p. 4);DEPLOY_BACK_DEV_TOKEN- testimoni per al desplegament al repositori de desenvolupament del servidor.
El procés de desplegament és senzill i consta de tres passos principals:
- construir i publicar la imatge al nostre repositori;
- executar proves en un contenidor basat en una imatge acabada de construir;
- desplegament a l'entorn desitjat en funció de la branca (dev/master).
frontend
poc diferent de Beck. Li falta un pas amb l'execució de proves i canvia els noms dels testimonis per al desplegament. Per cert, els secrets del dipòsit frontal s'han d'omplir per separat.
Configuració del lloc
Trànsit intermediari a través de Nginx
Bé, hem arribat al final. Només queda configurar el proxy del trànsit entrant i sortint al nostre contenidor a través de Nginx. Ja hem tractat aquest procés al pas 5 de la configuració del registre Docker. El mateix s'ha de repetir per a les parts posterior i frontal en entorns de desenvolupament i prod.
Us proporcionaré captures de pantalla de la configuració.
Backend

frontend

Aclariment important. Tots els URL s'enviaran al contenidor de la interfície, excepte els que comencen per /api/ - estaran aproximats al contenidor posterior (per tant al contenidor posterior, tots els manipuladors han de començar /api/).
Resultats de
Ara el nostre lloc hauria d'estar disponible a helloworld.ru i dev.helloworld.ru (entorns de producció i desenvolupament, respectivament).
En total, vam aprendre a preparar una aplicació senzilla a Flask i Angular i a configurar una canalització a Github Actions per desplegar-la a un servidor amb Plesk.
Duplicaré els enllaços als repositoris amb el codi: , .
Font: www.habr.com
