
この記事では、Plesk コントロール パネルと Github Actions を使用して CI/CD をセットアップした私の経験を共有します。 今日は、「Helloworld」という単純な名前を持つ単純なプロジェクトをデプロイする方法を学びます。 これは、Celery ワーカーと Angular 8 フロントエンドを備えた Flask Python フレームワークで書かれています。
リポジトリへのリンク: , .
記事の最初の部分では、プロジェクトとその部分について説明します。 XNUMX 番目では、Plesk をセットアップし、必要な拡張機能とコンポーネント (DB、RabbitMQ、Redis、Docker など) をインストールする方法を理解します。
XNUMX 番目のパートでは、最終的に、プロジェクトを開発環境および本番環境のサーバーにデプロイするためのパイプラインをセットアップする方法を理解します。 そしてサーバー上でサイトを立ち上げます。
そうそう、自己紹介を忘れていました。 私の名前は Oleg Borzov です。Domclick の住宅ローン管理者向け CRM チームのフルスタック開発者です。
プロジェクト概要
まず、XNUMX つのプロジェクト リポジトリ (バックエンドとフロント) を見て、コードを見てみましょう。
バックエンド: フラスコ+セロリ
後半部分では、Python 開発者の間で非常に人気のある、Flask フレームワーク (API 用) と Celery (タスク キュー用) を取り上げました。 ORMとしてSQLAchemyを使用します。 移行には Alembic が使用されます。 ハンドルの JSON 検証用 - Marshmallow。
В Readme.md ファイルには、プロジェクトの構造と実行手順の詳細な説明が記載されています。
非常に単純で、6 本のペンで構成されています。
/ping- 空き状況を確認するため。- 登録、認可、認可解除、認可されたユーザーの取得を処理します。
- タスクを Celery キューに入れる電子メール ハンドル。
さらに簡単ですが、問題は XNUMX つだけです send_mail_task.
フォルダー内 XNUMX つのサブフォルダーがあります。
dockerXNUMX つの Dockerfile (base.dockerfileめったに変更されないベースイメージを構築し、Dockerfileメインアセンブリの場合);.env_files- さまざまな環境の環境変数を含むファイル。
プロジェクトのルートには XNUMX つの docker-compose ファイルがあります。
docker-compose.local.db.yml開発用にローカル データベースを構築します。docker-compose.local.workers.ymlワーカー、データベース、Redis、RabbitMQ のローカル起動用。docker-compose.test.yml導入中にテストを実行するため。docker-compose.yml展開用に。
そして、私たちが興味がある最後のフォルダーは - 。 これには、デプロイメント用のシェル スクリプトが含まれています。
deploy.sh— 移行と展開の開始。 Github Actions でテストをビルドして実行した後、サーバー上で実行されます。rollback.sh- コンテナーを以前のバージョンのアセンブリにロールバックします。curl_tg.sh- デプロイメント通知を Telegram に送信します。
Angular のフロントエンド
ベックのものよりもはるかに簡単です。 表紙は次の XNUMX ページで構成されています。
- 電子メールを送信するためのフォームと終了ボタンを備えたメイン ページ。
- ログインページ。
- 登録ページ。
メインページは禁欲的に見えます:

ルートにXNUMXつのファイルがあります Dockerfile и docker-compose.yml、おなじみのフォルダーと同様に .ci-cd バック リポジトリよりもスクリプトがわずかに少なくなります (テストを実行するためのスクリプトが削除されました)。
Plesk でプロジェクトを開始する
まずは Plesk をセットアップし、サイトのサブスクリプションを作成しましょう。
拡張機能のインストール
Plesk では、次の XNUMX つの拡張機能が必要です。
DockerPlesk 管理パネルでコンテナのステータスを管理し、視覚的に表示します。Gitサーバー上で展開ステップを構成します。Let's Encrypt無料の TLS 証明書を生成 (および自動更新) するため。Firewall受信トラフィックのフィルタリングを設定します。
これらは、Plesk 管理パネルの「拡張機能」セクションからインストールできます。

拡張機能の詳細な設定は考慮しません。デモの目的ではデフォルト設定で十分です。
サブスクリプションとサイトを作成する
次に、helloworld.ru Web サイトのサブスクリプションを作成し、そこに dev.helloworld.ru サブドメインを追加する必要があります。
- helloworld.ru ドメインのサブスクリプションを作成し、システム ユーザーのログイン パスワードを指定します。

ページの下部にあるチェックボックスをオンにします Let's Encrypt でドメインを保護するサイトに HTTPS を設定する場合:
- 次に、このサブスクリプションで、サブドメイン dev.helloworld.ru を作成します (無料の TLS 証明書を発行することもできます)。

サーバーコンポーネントのインストール
私たちはサーバーを持っています OS Debian ストレッチ9.12 そして設置されたコントロールパネル Plesk 黒曜石 18.0.27.
プロジェクト用にインストールして構成する必要があります。
- PostgreSQL (この場合、開発環境と本番環境用に XNUMX つのデータベースを持つ XNUMX つのサーバーがあります)。
- RabbitMQ (環境ごとに異なる vhost を持つ同じ同じインスタンス)。
- XNUMX つの Redis インスタンス (開発環境と本番環境用)。
- Docker レジストリ (ビルドされた Docker イメージのローカル ストレージ用)。
- Docker レジストリの UI。
PostgreSQL
Plesk には既に PostgreSQL DBMS が付属していますが、最新バージョンではありません (Plesk Obsidian の作成時点では) Postgres バージョン 8.4 ~ 10.8)。 アプリケーションには最新バージョン (この記事の執筆時点では 12.3) が必要なので、手動でインストールします。
Postgresのインストールに関する詳細な手順 Debian インターネット上にはそれがたくさんあります() なので、詳細は説明しません。コマンドを指定するだけです。
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
PostgreSQL のデフォルト設定が平凡であることを考慮すると、構成を修正する必要があります。 これは私たちにとって役立ちます : サーバーのパラメータを入力し、ファイル内の設定を置き換える必要があります /etc/postgresql/12/main/postgresql.conf提供された人たちに。 ここで、このような計算ツールは特効薬ではなく、ハードウェア、アプリケーション、クエリの複雑さに基づいてベースをより正確に調整する必要があることに注意してください。 しかし、始めるにはこれで十分です。
計算機によって提案された設定に加えて、次の設定も変更します。 postgresql.confデフォルトのポート 5432 を別のポートに (この例では - 53983).
構成ファイルを変更した後、次のコマンドを使用して postgresql-server を再起動します。
service postgresql restart
PostgreSQL をインストールして構成しました。 次に、データベース、開発環境および本番環境用のユーザーを作成し、データベースを管理する権限をユーザーに与えましょう。
$ 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の
Celery のメッセージブローカーである RabbitMQ のインストールに移りましょう。 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
インストール後、作成する必要があります バーチャルホスト、ユーザーに必要な権限を付与します。
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の
次に、アプリケーションの最後のコンポーネントである Redis をインストールして構成しましょう。 Celery タスクの結果を保存するためのバックエンドとして使用されます。
拡張機能を使用して、開発環境と本番環境用に Redis を使用して XNUMX つの Docker コンテナーを生成します。 Docker プレスク用。
- Plesk に移動し、[拡張機能] セクションに移動し、Docker 拡張機能を探してインストールします (無料バージョンが必要です)。

- インストールされている拡張機能に移動し、検索で画像を見つけます
redis bitnami最新バージョンをインストールします。
- ダウンロードしたコンテナーに移動して構成を調整します。ポート、割り当てられた最大 RAM サイズ、環境変数のパスワードを指定し、ボリュームをマウントします。

- prod コンテナに対して手順 2 ~ 3 を実行します。設定では、ポート、パスワード、RAM サイズ、サーバー上のボリューム フォルダーへのパスのパラメーターのみを変更します。

Dockerレジストリ
基本的なサービスに加えて、独自の Docker イメージ リポジトリをサーバー上に置くとよいでしょう。 幸いなことに、サーバー スペースは現在非常に安価であり (DockerHub サブスクリプションよりも確実に安い)、プライベート リポジトリをセットアップするプロセスは非常に簡単です。
私たちが望んでいるのは:
- サブドメインでアクセス可能なパスワードで保護された Docker リポジトリ ;
- リポジトリ内のイメージを表示するための UI。次の場所から入手できます。 .
これを行うには:
- サブスクリプション内の Plesk に XNUMX つのサブドメイン docker.helloworld.ru と docker-ui.helloworld.ru を作成し、それらの Let's Encrypt 証明書を設定しましょう。
- ファイルを docker.helloworld.ru サブドメイン フォルダーに追加します。
docker-compose.yml次のような内容で: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' - SSH では、Docker リポジトリに Basic 認証用の .htpasswd ファイルを生成します。
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - コンテナを収集して持ち上げます。
docker-compose up -d - そして、Nginx をコンテナにリダイレクトする必要があります。 これは Plesk を通じて実行できます。
docker.helloworld.ru サブドメインと docker-ui.helloworld.ru サブドメインに対して次の手順を実行する必要があります。
セクション内の 開発ツール 私たちのサイトに行く Docker プロキシ ルール:

そして、受信トラフィックをコンテナにプロキシするルールを追加します。

- ローカル マシンからコンテナにログインできることを確認します。
$ 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 - docker-ui.helloworld.ru サブドメインの動作も確認してみましょう。

[リポジトリの参照] をクリックすると、ブラウザに認証ウィンドウが表示され、リポジトリのユーザー名とパスワードを入力する必要があります。 その後、リポジトリのリストが含まれるページに移動します (現時点では空になっています)。
Plesk ファイアウォールでポートを開く
コンポーネントをインストールして構成した後、Docker コンテナーや外部ネットワークからコンポーネントにアクセスできるようにポートを開く必要があります。
先ほどインストールした Plesk のファイアウォール拡張機能を使用してこれを行う方法を見てみましょう。
- に行く [ツールと設定] > [設定] > [ファイアウォール]:

- に行く Plesk ファイアウォール ルールの変更 > カスタム ルールの追加 そして、Docker サブネット用に次の TCP ポートを開きます (172.0.0.0 / 8):
RabbitMQ: 1883、4369、5671-5672、25672、61613-61614
レディス: 32785、32786
- また、PostgreSQL ポートと RabbitMQ 管理パネルを外部に開くルールも追加します。

- 「変更を適用」ボタンを使用してルールを適用します。

Github Actions での CI/CD のセットアップ
最も興味深い部分、継続的インテグレーション パイプラインのセットアップとプロジェクトのサーバーへの配信に取り掛かりましょう。
このパイプラインは XNUMX つの部分で構成されます。
- イメージの構築とテストの実行 (バックエンド用) - Github 側。
- (バックエンドの) 移行の実行と、サーバー上でのコンテナーのデプロイ。
Plesk へのデプロイ
まず XNUMX 番目の点に対処しましょう (最初の点はそれに依存しているため)。
Plesk の Git 拡張機能を使用して展開プロセスを設定します。
バックエンド リポジトリの本番環境の例を考えてみましょう。
- Helloworld Web サイトのサブスクリプションに移動し、Git サブセクションに移動します。

- Github リポジトリへのリンクを「リモート Git リポジトリ」フィールドに挿入し、デフォルトのフォルダを変更します。
httpdocs別のもの(例:/httpdocs/hw_back):
- 前の手順で作成した SSH 公開キーをコピーし、 それはGithubの設定にあります。
- ステップ 2 の画面で [OK] をクリックすると、Plesk のリポジトリ ページにリダイレクトされます。 ここで、master ブランチへのコミット時にリポジトリが更新されるように設定する必要があります。 これを行うには、次の場所に移動します リポジトリ設定 そして値を保存します
Webhook URL(後で Github Actions を設定するときに必要になります):
- 前の段落の画面の「アクション」フィールドに、デプロイメントを開始するスクリプトを入力します。
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}ここで:
{REPOSITORY_ABSOLUTE_PATH}- サーバー上のバックエンド リポジトリの prod フォルダーへのパス。
{ENV}- 環境 (開発/本番)、この場合prod;
{DOCKER_REGISTRY_HOST}- Docker リポジトリのホスト
{TG_BOT_TOKEN}— Telegram ボット トークン。
{TG_CHAT_ID}— 通知を送信するためのチャット/チャネルの ID。スクリプトの例:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - サブスクリプションから Docker グループにユーザーを追加します (コンテナーを管理できるようにします)。
sudo usermod -aG docker helloworld_admin
バックエンド リポジトリとフロントエンドの開発環境は同じ方法でセットアップされます。
Github Actions のデプロイメント パイプライン
Github Actions での CI/CD パイプラインの最初の部分の設定に進みましょう。
バックエンド
パイプラインについては、以下で説明されています。 .
ただし、解析する前に、Github で必要な Secret 変数を入力しましょう。 これを行うには、次の場所に移動します 設定 -> シークレット:
DOCKER_REGISTRY- Docker リポジトリ (docker.helloworld.ru) のホスト。DOCKER_LOGIN- Docker リポジトリにログインします。DOCKER_PASSWORD- そのパスワード。DEPLOY_HOST— Plesk 管理パネルが利用可能なホスト (例: :8443 または :8443);DEPLOY_BACK_PROD_TOKEN- サーバー上の prod リポジトリにデプロイするためのトークン (Plesk でのデプロイメント p. 4 で取得しました)。DEPLOY_BACK_DEV_TOKEN- サーバー上の開発リポジトリにデプロイするためのトークン。
導入プロセスはシンプルで、次の XNUMX つの主要な手順で構成されます。
- イメージを構築してリポジトリに公開します。
- 新しく構築されたイメージに基づいてコンテナ内でテストを実行します。
- ブランチ (dev/master) に応じて、目的の環境にデプロイします。
フロントエンド
ベックスとは少し違います。 テストを実行するステップが欠けており、デプロイメント用のトークンの名前が変更されます。 ちなみに、フロントリポジトリのシークレットは別途入力する必要があります。
サイトのセットアップ
Nginx を介したトラフィックのプロキシ
さて、終わりに来ました。 残っているのは、Nginx を介したコンテナへの送受信トラフィックのプロキシを構成することだけです。 このプロセスについては、Docker レジストリのセットアップのステップ 5 ですでに説明しました。 開発環境と本番環境の背面と前面の部分でも同じことを繰り返す必要があります。
設定のスクリーンショットを提供します。
バックエンド

フロントエンド

重要な説明。 で始まる URL を除き、すべての URL がフロントエンド コンテナにプロキシされます。 /api/ - それらは背面のコンテナーにプロキシされます (つまり、 バックコンテナでは、すべてのハンドラーは次で始まる必要があります。 /api/).
結果
これで、サイトが helloworld.ru と dev.helloworld.ru (それぞれ prod 環境と dev 環境) で利用できるようになります。
全体として、Flask と Angular で単純なアプリケーションを準備し、Github Actions でパイプラインを設定して、Plesk を実行しているサーバーにロールアウトする方法を学びました。
次のコードを使用してリポジトリへのリンクを複製します。 , .
出所: habr.com
