
In diesem Artikel teile ich meine Erfahrung bei der Einrichtung von CI/CD mit der Plesk-Verwaltungskonsole und GitHub Actions. Heute lernen wir, ein einfaches Projekt mit dem wenig einfallsreichen Namen âHelloworldâ zu deployen. Es wurde mit dem Python-Framework Flask, mit Workern auf Celery und einem Frontend auf Angular 8 geschrieben.
Links zu den Repositories: , .
Im ersten Teil des Artikels werfen wir einen Blick auf unser Projekt und seine Teile. Im zweiten Teil werden wir uns damit beschÀftigen, wie man Plesk einrichtet und die erforderlichen Erweiterungen und Komponenten installiert (Datenbank, RabbitMQ, Redis, Docker usw.).
Im dritten Teil werden wir schlieĂlich klĂ€ren, wie man eine Pipeline zum Deployen unseres Projekts auf dem Server in die Dev- und Prod-Umgebung einrichtet. AnschlieĂend starten wir die Website auf dem Server.
Ăbrigens, ich habe vergessen, mich vorzustellen. Mein Name ist Oleg Borzov, ich bin Fullstack-Entwickler im CRM-Team fĂŒr Hypothekenmanager bei Domklik.
ProjektĂŒbersicht
ZunĂ€chst betrachten wir die beiden Repositories des Projekts â das Backend und das Frontend â und gehen den Code durch.
Backend-Teil: Flask+Celery
FĂŒr den Backend-Teil habe ich eine unter Python-Entwicklern recht beliebte Kombination gewĂ€hlt: Das Framework Flask (fĂŒr die API) und Celery (fĂŒr die Aufgabenwarteschlange). Als ORM kommt SQLAlchemy zum Einsatz. FĂŒr Migrationen wird Alembic verwendet. Zur Validierung von JSON in den Handlers â Marshmallow.
Im Es gibt eine Datei Readme.md mit einer ausfĂŒhrlichen Beschreibung der Struktur und Anweisungen zum Starten des Projekts.
eher einfach, besteht aus 6 Endpunkten:
/pingâ zum ĂberprĂŒfen der VerfĂŒgbarkeit;- Endpunkte fĂŒr Registrierung, Authentifizierung, De-Authentifizierung und Abruf des authentifizierten Benutzers;
- ein Endpunkt zum Versenden von E-Mails, der eine Aufgabe in die Celery-Warteschlange legt.
noch einfacher, es gibt nur eine Aufgabe send_mail_task.
Im Verzeichnis liegen zwei Unterordner:
dockermit zwei Docker-Dateien (base.dockerfilezum Erstellen eines selten geĂ€nderten Basisimages undDockerfilefĂŒr die Hauptbuilds);.env_filesâ mit Umgebungsvariablen-Dateien fĂŒr verschiedene Umgebungen.
Im Wurzelverzeichnis des Projekts befinden sich vier docker-compose-Dateien:
docker-compose.local.db.ymlzur Einrichtung einer lokalen Datenbank fĂŒr die Entwicklung;docker-compose.local.workers.ymlzum lokalen Hochfahren von Workern, Datenbank, Redis und RabbitMQ;docker-compose.test.ymlzum AusfĂŒhren von Tests beim Deployen;docker-compose.ymlzum Deployen.
Und der letzte interessante Ordner fĂŒr uns ist â . Darin befinden sich Shell-Skripte fĂŒr das Deployen:
deploy.shâ startet Migrationen und das Deployen. Wird auf dem Server nach dem Build und dem AusfĂŒhren von Tests in GitHub Actions ausgefĂŒhrt;rollback.shâ rollt die Container auf die vorherige Version des Builds zurĂŒck;curl_tg.shâ Benachrichtigungen ĂŒber das Deployment in Telegram senden.
Frontend in Angular
ist viel einfacher als das Backend. Das Frontend besteht aus drei Seiten:
- Die Hauptseite mit einem Formular zum Versenden von E-Mails und einem Abmeldebutton.
- Login-Seite.
- Registrierungsseite.
Die Hauptseite sieht minimalistisch aus:

Im Root-Verzeichnis liegen zwei Dateien Dockerfile und docker-compose.yml, sowie ein uns bekanntes Verzeichnis .ci-cd mit etwas weniger Skripten als im Backend-Repository (die Skripte zum Starten von Tests wurden entfernt).
Wir richten ein Projekt in Plesk ein
Beginnen wir mit der Konfiguration von Plesk und dem Erstellen eines Abonnements fĂŒr unsere Website.
Installation von Erweiterungen
In Plesk benötigen wir vier Erweiterungen:
Dockerzum Verwalten und visuellen Anzeigen des Zustands von Containern im Plesk-Adminbereich;Gitzur Konfiguration des Deployment-Schritts auf dem Server;Let's Encryptzur Generierung (und automatischen VerlÀngerung) kostenloser TLS-Zertifikate;Firewallzur Konfiguration der Filterung des eingehenden Datenverkehrs.
Sie können sie ĂŒber das Plesk-Adminpanel im Abschnitt Erweiterungen installieren:

Wir werden die detaillierte Konfiguration der Erweiterungen nicht betrachten, die Standardeinstellungen sind fĂŒr unsere Demo-Zwecke ausreichend.
Erstellung eines Abonnements und einer Website
Als nĂ€chstes mĂŒssen wir ein Abonnement fĂŒr unsere Website helloworld.ru erstellen und die Unterdomain dev.helloworld.ru hinzufĂŒgen.
- Wir erstellen ein Abonnement fĂŒr die Domain helloworld.ru und geben den Benutzernamen und das Passwort fĂŒr den Systembenutzer an:

Unten auf der Seite setzen wir ein HĂ€kchen Sichern Sie die Domain mit Letâs Encrypt, wenn wir HTTPS fĂŒr die Website einrichten möchten:
- Dann erstellen wir in diesem Abonnement die Unterdomain dev.helloworld.ru (fĂŒr die ebenfalls ein kostenloses TLS-Zertifikat ausgestellt werden kann):

Installation der Serverkomponenten
Wir haben einen Server mit OS Debian Stretch 9.12 und dem installierten Verwaltungspanel Plesk Obsidian 18.0.27.
Wir mĂŒssen fĂŒr unser Projekt installieren und konfigurieren:
- PostgreSQL (in unserem Fall wird es einen Server mit zwei Datenbanken fĂŒr die dev- und prod-Umgebung geben).
- RabbitMQ (das gleiche, eine Instanz mit verschiedenen vhosts fĂŒr die Umgebungen).
- Zwei Instanzen von Redis (fĂŒr die dev- und prod-Umgebung).
- Docker Registry (fĂŒr die lokale Speicherung der erstellten Docker-Images).
- UI-Schnittstelle fĂŒr die Docker-Registry.
PostgreSQL
Im Lieferumfang von Plesk ist bereits eine PostgreSQL-Datenbank enthalten, jedoch nicht die neueste Version (zum Zeitpunkt der Erstellung des Artikels unterstĂŒtzte Plesk Obsidian Detaillierte Anleitungen zur Installation von Postgres auf Debian finden sich zahlreich im Internet (
Beispiel), deshalb werde ich sie nicht im Detail beschreiben, sondern nur die Befehle anfĂŒhren:
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
Da die Standardkonfiguration in PostgreSQL ziemlich durchschnittlich ist, ist es erforderlich, die Konfiguration unbedingt anzupassen. Dabei hilft uns : Sie mĂŒssen die Parameter Ihres Servers eingeben und die Einstellungen in der Datei /etc/postgresql/12/main/postgresql.confdurch die vorgeschlagenen ersetzen. Hier muss ich anmerken, dass solche Rechner keine Wunderwaffe sind und die Datenbank gezielt an Ihre Hardware, Ihre Anwendung und die KomplexitĂ€t der Abfragen angepasst werden sollte. Aber fĂŒr den Anfang reicht das aus.
Neben den vom Rechner vorgeschlagenen Einstellungen Ă€ndern wir auch in postgresql.confden standardmĂ€Ăig eingetragenen Port 5432 auf einen anderen (in unserem Beispiel - 53983).
Nach der Ănderung der Konfigurationsdatei starten wir den postgresql-Server mit dem Befehl:
service postgresql restart
Wir haben PostgreSQL installiert und konfiguriert. Jetzt erstellen wir eine DB, Benutzer fĂŒr die Entwicklungs- und Produktionsumgebung und vergeben den Benutzern die Rechte zum Verwalten der DB:
$ 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
Kommen wir zur Installation von RabbitMQ - einem Nachricht broker fĂŒr Celery. Die Installation auf Debian ist recht einfach:
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
Nach der Installation mĂŒssen wir vhosts, Benutzer erstellen und die erforderlichen Berechtigungen festlegen:
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
Jetzt installieren und konfigurieren wir die letzte Komponente fĂŒr unsere Anwendung - Redis. Es wird als Backend fĂŒr die Speicherung von Ergebnissen der Celery-Aufgaben verwendet.
Wir werden zwei Docker-Container mit Redis fĂŒr Dev- und Prod-Umgebungen mithilfe des Erweiterung starten Docker fĂŒr Plesk.
- Gehe zu Plesk, gehe zum Abschnitt Erweiterungen, suche nach der Docker-Erweiterung und installiere sie (wir benötigen die kostenlose Version):

- Gehe zur installierten Erweiterung, finde das Abbild ĂŒber die Suche
redis bitnamiund installiere die neueste Version:
- Gehe in den heruntergeladenen Container und passe die Konfiguration an: gib den Port, die maximal zugewiesene RAM-GröĂe, das Passwort in den Umgebungsvariablen an und mounte das Volume:

- FĂŒhre die Schritte 2-3 fĂŒr den Prod-Container aus, Ă€ndere nur die Parameter in den Einstellungen: Port, Passwort, RAM-GröĂe und den Pfad zum Volume-Ordner auf dem Server:

Docker Registry
Neben den grundlegenden Diensten wĂ€re es sinnvoll, auf dem Server ein eigenes Repository fĂŒr Docker-Images einzurichten. GlĂŒcklicherweise sind die PlĂ€tze auf den Servern jetzt recht gĂŒnstig (sicherlich gĂŒnstiger als ein Abonnement bei DockerHub) und der Prozess zur Installation eines privaten Repositories ist sehr einfach.
Wir möchten folgendes installieren:
- ein durch ein Passwort geschĂŒtztes Docker-Repository, das ĂŒber eine Subdomain zugĂ€nglich ist ;
- eine BenutzeroberflÀche zur Anzeige von Images im Repository, zugÀnglich unter der Adresse .
DafĂŒr:
- Erstelle in Plesk zwei Subdomains in unserem Abonnement: docker.helloworld.ru und docker-ui.helloworld.ru, und richte fĂŒr sie Let's Encrypt-Zertifikate ein.
- FĂŒge in den Ordner der Subdomain docker.helloworld.ru die Datei hinzu
docker-compose.ymlmit folgendem Inhalt: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' - Wir generieren ĂŒber SSH die Datei .htpasswd fĂŒr die Basis-Authentifizierung im Docker-Repository:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Wir bauen und starten die Container:
docker-compose up -d - Und wir mĂŒssen Nginx auf unsere Container umleiten. Das kann ĂŒber Plesk erfolgen.
Die folgenden Schritte mĂŒssen fĂŒr die Subdomains docker.helloworld.ru und docker-ui.helloworld.ru durchgefĂŒhrt werden:
Im Abschnitt Dev-Tools unserer Website gehen zu Docker Proxy-Regeln:

Und wir fĂŒgen eine Regel zum Proxy des eingehenden Traffics in unseren Container hinzu:

- Wir ĂŒberprĂŒfen, dass wir uns von einem lokalen Rechner aus in unseren Container einloggen können:
$ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password WARNUNG! Die Verwendung von --password ĂŒber die CLI ist unsicher. Verwenden Sie --password-stdin. Anmeldung erfolgreich - Lassen Sie uns auch die FunktionalitĂ€t der Subdomain docker-ui.helloworld.ru ĂŒberprĂŒfen:

Wenn Sie auf Repositories durchsuchen klicken, zeigt der Browser ein Anmeldefenster an, in das Sie den Benutzernamen und das Passwort fĂŒr das Repository eingeben mĂŒssen. Danach werden wir auf die Seite mit der Liste der Repositories weitergeleitet (diese wird zunĂ€chst leer sein):
Ăffnen Sie die Ports in der Plesk-Firewall
Nach der Installation und Konfiguration der Komponenten mĂŒssen wir die Ports öffnen, damit die Komponenten von Docker-Containern und aus dem externen Netzwerk erreichbar sind.
Sehen wir uns an, wie man dies am Beispiel der zuvor installierten Firewall-Erweiterung fĂŒr Plesk macht.
- Gehen Sie zu Tools & Einstellungen > Einstellungen > Firewall:

- Gehen Sie zu Ăndern Sie die Plesk-Firewallregeln > Benutzerdefinierte Regel hinzufĂŒgen und öffnen Sie die folgenden TCP-Ports fĂŒr das Docker-Subnetz (172.0.0.0/8):
RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- Wir werden auch eine Regel hinzufĂŒgen, die die Ports fĂŒr PostgreSQL und das Management-Panel von RabbitMQ fĂŒr die externe Welt öffnet:

- Wenden Sie die Regeln mit der SchaltflĂ€che Ănderungen anwenden an:

CI/CD-Konfiguration in Github Actions
Kommen wir zum interessantesten Teil â der Konfiguration des Pipelines fĂŒr die kontinuierliche Integration und Bereitstellung unseres Projekts auf dem Server.
Diese Pipeline wird aus zwei Teilen bestehen:
- Bau des Abbilds und AusfĂŒhrung von Tests (fĂŒr das Backend) â auf der Seite von Github;
- AusfĂŒhrung der Migrationen (fĂŒr das Backend) und Bereitstellung der Container â auf dem Server.
Bereitstellung in Plesk
Lassen Sie uns zunÀchst den zweiten Punkt bearbeiten (da der erste davon abhÀngt).
Wir werden den Bereitstellungsprozess mit der Git-Erweiterung fĂŒr Plesk konfigurieren.
Sehen wir uns ein Beispiel mit der Prod-Umgebung fĂŒr das Backend-Repository an.
- Gehen Sie zu unserem Helloworld-Webseiten-Abonnement und navigieren Sie zum Git-Unterbereich:

- FĂŒgen Sie im Feld âRemote Git-Repositoryâ den Link zu unserem Github-Repository ein und Ă€ndern Sie den Standardordner
httpdocsin einen anderen (zum Beispiel,/httpdocs/hw_back):
- Kopieren Sie den SSH-Ăffentlichen SchlĂŒssel aus dem vorherigen Schritt und Klicken Sie im Punkt 2 auf OK, danach werden wir auf die Repository-Seite in Plesk weitergeleitet. Jetzt mĂŒssen wir die Aktualisierung des Repositories bei Commits in den Master-Zweig einrichten. Dazu gehen wir zu
- Repository-Einstellungen und speichern den Wert Webhook-URL
(dies wird spĂ€ter bei der Konfiguration der Github Actions benötigt):Geben Sie im Feld Aktionen auf dem vorherigen Bildschirm das Skript zum Starten der Bereitstellung ein:
- cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}
wo:{REPOSITORY_ABSOLUTE_PATH}
â der Pfad zum Prod-Ordner des Backend-Repositories auf dem Server;{ENV}
â die Umgebung (dev/prod), in unserem Fallâ Umgebung (dev/prod), in unserem Fallprod;
{DOCKER_REGISTRY_HOST}â der Host unseres Docker-Repositorys
{TG_BOT_TOKEN}â Token des Telegram-Bots;
{TG_CHAT_ID}â ID des Chats/Kanals fĂŒr den Versand von Benachrichtigungen.Beispiel-Skript:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - FĂŒgen Sie einen Benutzer aus unserem Abonnement zur Docker-Gruppe hinzu (damit er Container verwalten kann):
sudo usermod -aG docker helloworld_admin
Die Entwicklungsumgebung fĂŒr das Backend-Repository und das Frontend wird Ă€hnlich konfiguriert.
Deployment-Pipeline in Github Actions
Gehen wir zur Konfiguration des ersten Teils unserer CI/CD-Pipeline in Github Actions ĂŒber.
Backend
Die Pipeline wird in .
Aber bevor wir dazu kommen, fĂŒgen wir in Github die benötigten Secret-Variablen ein. Dazu gehen wir zu Einstellungen -> Secrets:
DOCKER_REGISTRYâ der Host unseres Docker-Repositorys (docker.helloworld.ru);DOCKER_LOGINâ Benutzername fĂŒr das Docker-Repository;DOCKER_PASSWORDâ Passwort dafĂŒr;DEPLOY_HOSTâ der Host, auf dem das Plesk-Admin-Panel verfĂŒgbar ist (Beispiel: :8443 oder :8443);DEPLOY_BACK_PROD_TOKENâ Token fĂŒr das Deployment im Prod-Repository auf dem Server (wir haben ihn in Punkt 4 der Bereitstellung in Plesk erhalten);DEPLOY_BACK_DEV_TOKENâ Token fĂŒr das Deployment im Dev-Repository auf dem Server.
Der Deployment-Prozess ist einfach und besteht aus drei Hauptschritten:
- Erstellen und Veröffentlichen des Images in unserem Repository;
- AusfĂŒhren von Tests im Container basierend auf dem frisch erstellten Image;
- Bereitstellung in die jeweilige Umgebung je nach Branche (dev/master).
Frontend
unterscheidet sich kaum vom Backend. Der Schritt zum AusfĂŒhren von Tests fehlt und die Namen der Token fĂŒr das Deployment Ă€ndern sich. Die Secrets fĂŒr das Front-Repository mĂŒssen ĂŒbrigens separat ausgefĂŒllt werden.
Website-Konfiguration
Traffic ĂŒber Nginx proxyen
Nun, wir sind am Ende angekommen. Es bleibt nur noch, den eingehenden und ausgehenden Traffic ĂŒber Nginx in unseren Container zu proxyen. Diesen Prozess haben wir bereits im Punkt 5 der Konfiguration des Docker Registry behandelt. Dasselbe muss fĂŒr den Backend- und Frontend-Bereich in den Dev- und Prod-Umgebungen wiederholt werden.
Ich werde Screenshots der Einstellungen bereitstellen.
Backend

Frontend

Wichtige Klarstellung. Im Frontend-Container werden alle URLs auĂer denjenigen, die mit /api/ beginnenâ diese werden in den Backend-Container proxyed (deshalb mĂŒssen im Backend-Container alle Handler mit /api/).
Ergebnisse
beginnen. Jetzt sollte unsere Website unter den Adressen helloworld.ru und dev.helloworld.ru (Prod- und Dev-Umgebungen entsprechend) verfĂŒgbar sein.
Insgesamt haben wir gelernt, wie man eine einfache Anwendung mit Flask und Angular erstellt und eine Pipeline in Github Actions fĂŒr deren Bereitstellung auf einem Server unter Plesk einrichtet.
Ich werde die Links zu den Repositories mit dem Code wiederholen: , .
Quelle: habr.com
















