
W tym artykule podzielę się moimi doświadczeniami z konfigurowania CI/CD za pomocą Plesk Control Panel i Github Actions. Dzisiaj nauczymy się, jak wdrożyć prosty projekt o nieskomplikowanej nazwie „Helloworld”. Jest napisany w frameworku Flask Python, z pracownikami Celery i nakładką Angular 8.
Linki do repozytoriów: , .
W pierwszej części artykułu przyjrzymy się naszemu projektowi i jego częściom. W drugim dowiemy się, jak skonfigurować Plesk i zainstalować niezbędne rozszerzenia i komponenty (DB, RabbitMQ, Redis, Docker itp.).
W trzeciej części w końcu dowiemy się, jak skonfigurować potok wdrażania naszego projektu na serwerze w środowisku dev i prod. Następnie uruchomimy stronę na serwerze.
I tak, zapomniałem się przedstawić. Nazywam się Oleg Borzov, jestem fullstack developerem w zespole CRM dla managerów kredytów hipotecznych w Domclick.
Przegląd projektu
Najpierw spójrzmy na dwa repozytoria projektu — backend i front — i przejrzyjmy kod.
Backend: Kolba + Seler
W tylnej części wziąłem kilka dość popularnych wśród programistów Pythona: framework Flask (dla API) i Seler (dla kolejki zadań). SQLAchemy jest używany jako ORM. Alembik służy do migracji. Do sprawdzania poprawności JSON w uchwytach - Marshmallow.
В znajduje się plik Readme.md ze szczegółowym opisem struktury i instrukcją uruchomienia projektu.
dość nieskomplikowany, składa się z 6 długopisów:
/ping- aby sprawdzić dostępność;- uchwyty do rejestracji, autoryzacji, cofnięcia autoryzacji i uzyskania uprawnionego użytkownika;
- uchwyt e-mail, który umieszcza zadanie w kolejce Selera.
nawet łatwiej, jest tylko jeden problem send_mail_task.
W folderze są dwa podfoldery:
dockerz dwoma plikami Docker (base.dockerfilezbudować rzadko zmieniający się obraz bazowy iDockerfiledla głównych zespołów);.env_files- z plikami ze zmiennymi środowiskowymi dla różnych środowisk.
W katalogu głównym projektu znajdują się cztery pliki do tworzenia dokerów:
docker-compose.local.db.ymlstworzyć lokalną bazę danych dla rozwoju;docker-compose.local.workers.ymldo lokalnego pozyskiwania pracownika, bazy danych, Redis i RabbitMQ;docker-compose.test.ymlprzeprowadzać testy podczas wdrażania;docker-compose.ymldo rozmieszczenia.
I ostatni folder, który nas interesuje - . Zawiera skrypty powłoki do wdrożenia:
deploy.sh— uruchomienie migracji i wdrożenia. Działa na serwerze po zbudowaniu i uruchomieniu testów w Github Actions;rollback.sh- wycofanie kontenerów do poprzedniej wersji montażu;curl_tg.sh- wysyłanie powiadomień o wdrożeniu do Telegrama.
Frontend na Angularze
o wiele prostszy niż Becka. Przód składa się z trzech stron:
- Strona główna z formularzem do wysyłania wiadomości e-mail i przyciskiem wyjścia.
- Strona logowania.
- Strona rejestracji.
Strona główna wygląda ascetycznie:

W katalogu głównym znajdują się dwa pliki Dockerfile и docker-compose.yml, a także znajomy folder .ci-cd z nieco mniejszą liczbą skryptów niż w repozytorium wstecznym (usunięto skrypty do uruchamiania testów).
Rozpoczęcie projektu w Plesku
Zacznijmy od skonfigurowania Plesk i utworzenia subskrypcji dla naszej witryny.
Instalowanie rozszerzeń
W Plesku potrzebujemy czterech rozszerzeń:
Dockerzarządzać i wizualnie wyświetlać stan kontenerów w panelu administracyjnym Plesk;Gitaby skonfigurować etap wdrażania na serwerze;Let's Encryptdo generowania (i automatycznego odnawiania) bezpłatnych certyfikatów TLS;Firewallskonfigurować filtrowanie ruchu przychodzącego.
Możesz je zainstalować za pośrednictwem panelu administracyjnego Plesk w sekcji Rozszerzenia:

Nie będziemy brać pod uwagę szczegółowych ustawień rozszerzeń, ustawienia domyślne wystarczą do naszych celów demonstracyjnych.
Utwórz subskrypcję i witrynę
Następnie musimy utworzyć subskrypcję dla naszej witryny helloworld.ru i dodać tam subdomenę dev.helloworld.ru.
- Utwórz subskrypcję domeny helloworld.ru i podaj hasło logowania dla użytkownika systemu:

Zaznacz pole u dołu strony Zabezpiecz domenę za pomocą Let's Encryptjeśli chcemy skonfigurować HTTPS dla witryny:
- Następnie w tej subskrypcji utwórz subdomenę dev.helloworld.ru (dla której możesz również wystawić bezpłatny certyfikat TLS):

Instalowanie składników serwera
Mamy serwer z OS Debian Rozciągnij 9.12 i zainstalowany panel sterowania Plesk Obsydian 18.0.27.
Musimy zainstalować i skonfigurować dla naszego projektu:
- PostgreSQL (w naszym przypadku będzie to jeden serwer z dwiema bazami danych dla środowisk dev i prod).
- RabbitMQ (ta sama, ta sama instancja z różnymi vhostami dla środowisk).
- Dwie instancje Redis (dla środowisk deweloperskich i produkcyjnych).
- Docker Registry (do lokalnego przechowywania zbudowanych obrazów Docker).
- Interfejs użytkownika dla rejestru Docker.
PostgreSQL
Plesk jest już dostarczany z PostgreSQL DBMS, ale nie najnowszą wersją (w momencie pisania Plesk Obsidian wersje Postgresa 8.4–10.8). Chcemy najnowszej wersji dla naszej aplikacji (12.3 w momencie pisania tego tekstu), więc zainstalujemy ją ręcznie.
Подробных инструкций по установке Postgres на Debian в сети полно (), więc nie będę ich szczegółowo opisywał, podam tylko komendy:
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
Biorąc pod uwagę, że PostgreSQL ma raczej przeciętne ustawienia domyślne, konieczne jest poprawienie konfiguracji. To nam pomoże : musisz wprowadzić parametry swojego serwera i zastąpić ustawienia w pliku /etc/postgresql/12/main/postgresql.confdo oferowanych. Należy tutaj zaznaczyć, że takie kalkulatory nie są magiczną kulą, a bazę należy dostroić bardziej precyzyjnie, w oparciu o sprzęt, aplikację i złożoność zapytań. Ale to wystarczy, aby zacząć.
Oprócz ustawień proponowanych przez kalkulator dokonujemy również przesiadek postgresql.confdomyślny port 5432 na inny (w naszym przykładzie - 53983).
Po zmianie pliku konfiguracyjnego zrestartuj serwer postgresql za pomocą polecenia:
service postgresql restart
Zainstalowaliśmy i skonfigurowaliśmy PostgreSQL. Teraz utwórzmy bazę danych użytkowników dla środowisk dev i prod oraz nadajmy użytkownikom uprawnienia do zarządzania bazą danych:
$ 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
Перейдем к установке RabbitMQ — брокера сообщений для Celery. Ставится он на Debian достаточно просто:
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
Po instalacji musimy utworzyć vhosts, użytkowników i przyznać niezbędne uprawnienia:
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
Teraz zainstalujmy i skonfigurujmy ostatni komponent dla naszej aplikacji - Redis. Będzie używany jako backend do przechowywania wyników zadań Celery.
Zbudujemy dwa kontenery Docker z Redis dla środowisk dev i prod korzystających z rozszerzenia Docker dla Pleska.
- Wchodzimy na Plesk, przechodzimy do sekcji Extensions, szukamy rozszerzenia Docker i instalujemy je (potrzebujemy darmowej wersji):

- Przejdź do zainstalowanego rozszerzenia, znajdź obraz za pomocą wyszukiwania
redis bitnamii zainstaluj najnowszą wersję:
- Wchodzimy do pobranego kontenera i dostosowujemy konfigurację: określamy port, maksymalny przydzielony rozmiar pamięci RAM, hasło w zmiennych środowiskowych i montujemy wolumin:

- Kroki 2-3 wykonujemy dla kontenera prod, w ustawieniach zmieniamy tylko parametry: port, hasło, rozmiar RAM i ścieżkę do folderu wolumenu na serwerze:

Rejestr Dockera
Oprócz podstawowych usług fajnie byłoby umieścić na serwerze własne repozytorium obrazów Dockera. Na szczęście miejsce na serwerze jest teraz dość tanie (z pewnością tańsze niż subskrypcja DockerHub), a proces zakładania prywatnego repozytorium jest bardzo prosty.
Chcemy mieć:
- chronione hasłem repozytorium Docker dostępne w subdomenie ;
- Interfejs użytkownika do przeglądania obrazów w repozytorium, dostępny pod adresem .
Aby to zrobić:
- Stwórzmy dwie subdomeny w Plesk w naszej subskrypcji: docker.helloworld.ru i docker-ui.helloworld.ru i skonfigurujmy dla nich certyfikaty Let's Encrypt.
- Dodaj plik do folderu poddomeny docker.helloworld.ru
docker-compose.ymlz taką zawartością: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' - Pod SSH wygenerujemy plik .htpasswd dla autoryzacji Basic w repozytorium Dockera:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - Zbieraj i podnoś pojemniki:
docker-compose up -d - I musimy przekierować Nginx do naszych kontenerów. Można to zrobić przez Plesk.
Następujące kroki należy wykonać dla subdomen docker.helloworld.ru i docker-ui.helloworld.ru:
W sekcji Narzędzia deweloperskie przejdź do naszej witryny Reguły serwera proxy Dockera:

I dodaj regułę do proxy ruchu przychodzącego do naszego kontenera:

- Sprawdzamy czy możemy zalogować się do naszego kontenera z lokalnej maszyny:
$ 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 - Sprawdźmy też działanie subdomeny docker-ui.helloworld.ru:

Po kliknięciu Przeglądaj repozytoria przeglądarka wyświetli okno autoryzacji, w którym należy wprowadzić nazwę użytkownika i hasło do repozytorium. Następnie zostaniemy przeniesieni na stronę z listą repozytoriów (na razie będzie ona dla Ciebie pusta):
Otwieranie portów w Plesk Firewall
Po zainstalowaniu i skonfigurowaniu komponentów musimy otworzyć porty, aby komponenty były dostępne z kontenerów Dockera i sieci zewnętrznej.
Zobaczmy, jak to zrobić za pomocą rozszerzenia Firewall dla Pleska, które zainstalowaliśmy wcześniej.
- Iść do Narzędzia i ustawienia > Ustawienia > Zapora sieciowa:

- Iść do Zmodyfikuj reguły zapory Plesk > Dodaj regułę niestandardową i otwórz następujące porty TCP dla podsieci Docker (172.0.0.0 / 8):
KrólikMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
Redis: 32785, 32786
- Dodamy również regułę, która otworzy porty PostgreSQL i panele zarządzające RabbitMQ na świat zewnętrzny:

- Zastosuj reguły za pomocą przycisku Zastosuj zmiany:

Konfigurowanie CI/CD w akcjach Github
Przejdźmy do najciekawszej części - ustawienia potoku ciągłej integracji i dostarczenia naszego projektu na serwer.
Rurociąg ten będzie składał się z dwóch części:
- zbudowanie obrazu i uruchomienie testów (dla backendu) - po stronie Github;
- uruchamianie migracji (dla backendu) i wdrażanie kontenerów - na serwerze.
Wysłać do Pleska
Zajmijmy się najpierw drugim punktem (bo od tego zależy pierwszy).
Skonfigurujemy proces wdrażania za pomocą rozszerzenia Git dla Plesk.
Rozważmy przykład ze środowiskiem Prod dla repozytorium zaplecza.
- Przechodzimy do subskrypcji naszej witryny Helloworld i przechodzimy do podsekcji Git:

- Wstaw link do naszego repozytorium Github w pole „Remote Git reposository” i zmień domyślny folder
httpdocsdo innego (np./httpdocs/hw_back):
- Skopiuj klucz publiczny SSH z poprzedniego kroku i jest w ustawieniach Github.
- Kliknij OK na ekranie w kroku 2, po czym zostaniemy przekierowani na stronę repozytorium w Plesk. Teraz musimy skonfigurować repozytorium, aby było aktualizowane o zatwierdzenia do gałęzi master. Aby to zrobić, przejdź do Ustawienia repozytorium i zapisz wartość
Webhook URL(będziemy go potrzebować później podczas konfigurowania Github Actions):
- W polu Działania na ekranie z poprzedniego akapitu wprowadź skrypt uruchamiający wdrożenie:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}gdzie:
{REPOSITORY_ABSOLUTE_PATH}- ścieżka do folderu prod repozytorium zaplecza na serwerze;
{ENV}- środowisko (dev/prod), w naszym przypadkuprod;
{DOCKER_REGISTRY_HOST}- host naszego repozytorium dokerów
{TG_BOT_TOKEN}— Token bota telegramu;
{TG_CHAT_ID}— Identyfikator czatu/kanału do wysyłania powiadomień.Przykład skryptu:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - Dodaj użytkownika z naszej subskrypcji do grupy Docker (aby mógł zarządzać kontenerami):
sudo usermod -aG docker helloworld_admin
Środowisko dev dla repozytorium zaplecza i frontendu jest konfigurowane w ten sam sposób.
Potok wdrażania w akcjach Github
Przejdźmy do konfigurowania pierwszej części naszego potoku CI/CD w Github Actions.
Backend
Rurociąg jest opisany w .
Ale zanim to przeanalizujemy, wypełnijmy tajne zmienne, których potrzebujemy w Github. Aby to zrobić, przejdź do Ustawienia -> Sekrety:
DOCKER_REGISTRY- host naszego repozytorium Dockera (docker.helloworld.ru);DOCKER_LOGIN- zaloguj się do repozytorium Dockera;DOCKER_PASSWORD- hasło do niego;DEPLOY_HOST— host, na którym dostępny jest panel administracyjny Plesk (przykład: :8443 lub :8443);DEPLOY_BACK_PROD_TOKEN- token do wdrożenia do prod-repository na serwerze (dostaliśmy go w Deployment in Plesk p. 4);DEPLOY_BACK_DEV_TOKEN- token do wdrożenia do repozytorium dev na serwerze.
Proces wdrażania jest prosty i składa się z trzech głównych kroków:
- zbudowanie i opublikowanie obrazu w naszym repozytorium;
- uruchamianie testów w kontenerze na podstawie świeżo zbudowanego obrazu;
- wdrożenie do żądanego środowiska w zależności od branży (dev/master).
frontend
niewiele różni się od Becka. Brakuje kroku z uruchomieniem testów i zmianą nazw tokenów do wdrożenia. Nawiasem mówiąc, tajemnice dla przedniego repozytorium należy wypełnić osobno.
Konfiguracja witryny
Ruch proxy przez Nginx
Cóż, doszliśmy do końca. Pozostaje tylko skonfigurować proxy ruchu przychodzącego i wychodzącego do naszego kontenera przez Nginx. Omówiliśmy już ten proces w kroku 5 konfiguracji Docker Registry. To samo należy powtórzyć dla części tylnej i przedniej w środowiskach deweloperskich i produkcyjnych.
Dam screeny z ustawień.
Backend

frontend

Ważne wyjaśnienie. Wszystkie adresy URL zostaną przekazane do kontenera frontendu, z wyjątkiem adresów zaczynających się od /api/ - zostaną przesłane do tylnego kontenera (tzw w tylnym kontenerze, od którego muszą zaczynać wszyscy opiekunowie /api/).
Wyniki
Teraz nasza strona powinna być dostępna pod adresami helloworld.ru i dev.helloworld.ru (odpowiednio prod- i dev-environments).
W sumie nauczyliśmy się, jak przygotować prostą aplikację we Flask i Angular oraz skonfigurować potok w Github Actions, aby ją wdrożyć na serwerze z Plesk.
Powielę linki do repozytoriów z kodem: , .
Źródło: www.habr.com
















