Webhooksを使ったReactアプリのデプロイとUbuntuでのSlackの統合

このチュートリアルでは、Ubuntuを使用したAlibaba Cloud Elastic Compute Service (ECS)インスタンス上で**Webhooks**を使用してSlackの通知をトリガーします。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-to-deploy-react-apps-using-webhooks-and-integrating-slack-on-ubuntu_594116)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

#前提条件
1、Alibaba Cloud Elastic Compute Service (ECS)を有効化し、有効な支払い方法を確認する必要があります。新規ユーザーの場合は、Alibaba Cloudアカウントで無料アカウントを取得することができます。ECSインスタンスのセットアップ方法がわからない場合は、このチュートリアルまたはクイックスタートガイドを参照してください。ECSインスタンスは、少なくとも2GB RAMと1コアプロセッサを搭載している必要があります。
2、Alibaba Cloudから登録されたドメイン名。すでにAlibaba Cloudまたは他のホストからドメインを登録している場合は、そのドメインネームサーバーレコードを更新することができます。
3、ドメイン名は、あなたのAlibaba Cloud ECSのIPアドレスを指している必要があります。
4、Alibaba CloudのVNCコンソールまたはPCにインストールされているSSHクライアントにアクセスします。
5、サーバーのホスト名を設定し、root権限を持つユーザーを作成します。

#Ubuntuのシステムを更新する
パッケージのインストールを進める前に、以下のコマンドを使用してUbuntuシステムをアップデートしてください。このコマンドを実行するには、root ではないユーザーから sudo 権限でログインすることを忘れないでください。このコマンドを実行すると、**Is this ok?** 'y'と入力して**Enter**キーを押します。

```
# sudo apt update && sudo apt upgrade
```

#Nginxサーバーのインストール
nginxサーバーをインストールするためには、以下の手順に従う必要があります。

**ステップ1**

インストールするには、以下のコマンドを実行します。

```
# sudo apt-get install nginx
```

**ステップ2**

以下のコマンドを実行してNginxサーバーを起動します。

```
# sudo systemctl start nginx
```

Nginxサーバーの状態を確認するには、以下のコマンドを実行します。

```
# sudo systemctl status nginx
```

インストールを確認するには、アリババクラウドECSのIPアドレスか、IPアドレスを指したドメイン名でアクセスします。私の場合はドメイン名経由でアクセスし、以下の画面が読み込まれました。

#Gitのインストール
ローカルマシンだけでなく、サーバーにもgitをインストールする必要があります。Gitをインストールして設定するには、以下の手順に従います。

**ステップ1**

Gitをインストールするには、コマンドを実行します。

```
# sudo apt-get install git
```

**ステップ 2 (オプション)**

以下のコマンドを実行して Git を設定します。名前と有効なメールアドレスを指定してコミットメッセージに正しい情報が含まれるようにします。

```
# git config --global user.name "Aareez"
# git config --global user.email "xyz@example.com"
```

#Node.js のインストール
Node.jsは、ブラウザの外でJSコードを実行するクロスプラットフォーム・オープンソースのJSランタイム環境です。Node.jsのバージョンはUbuntuのデフォルトリポジトリにあります。PPAを使用してNode.jsをインストールするには、以下の手順に従ってください。

以下のコマンドを実行して、お好みのバージョンのスクリプトを取得します。

```
# curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh
```

では、以下のコマンドでスクリプトを実行します。

```
# sudo bash nodesource_setup.sh
```

インストールするには、コマンドを実行します。

```
# sudo apt-get install -y nodejs
```

これで無事にNode.jsのインストールが完了しました。

#gccとg++をインストール
また、ネイティブアドオンを構築するための開発ツールも必要になるかもしれません。それらをインストールするには、コマンドを実行します。

```
# sudo apt-get install gcc g++
```

#Yarnのインストール
Yarn パッケージマネージャをインストールするには、以下のコマンドを実行します。

```
 # curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
 #  echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
# sudo apt-get update && sudo apt-get install yarn
```

npmを動作させるためには、build-essentialをインストールする必要があります。インストールするには以下のコマンドを実行してください。

```
# sudo apt-get install build-essential
```

#create-react-appを使ってReactアプリを作成する
まず、**create-react-app**でWebhookをテストするためのアプリケーションを構築します。この後、GitHubのリポジトリを作成し、そのリポジトリにプロジェクトのコードをプッシュする必要があります。

**create-react-app**のノードモジュールをグローバルリポジトリに追加するには、以下のコマンドを実行してシェルから利用できるようにする必要があります。

```
# sudo npm install -g create-react-app
```

**aareez-project**という名前のプロジェクトを作成するには、以下のコマンドを実行します。

```
# sudo create-react-app aareez-project
```

以下のコマンドで作成したプロジェクトディレクトリに移動します。

```
# cd aareez-project
```

aareez-projectディレクトリにあるgitでリポジトリを初期化します。そのためには、以下のコマンドを実行します。

```
# sudo git init
```

ここで、GitHub の URL と一緒にリモートオリジンを追加します。

```
# sudo git remote add origin https://github.com/itsaareez1/react-example
```

プロジェクトディレクトリにあるファイルをステージします。

```
# sudo git add 
```

それらをコミットし、以下のコマンドを実行してリポジトリにプッシュします。

```
# sudo git commit -m "initial commit"
# sudo git push -f origin master
```

#React用ディレクトリの設定とNginxサーバーの設定
ここでは、Githubのリポジトリからreactアプリのクローンを取得する必要があります。

ルートディレクトリに移動します。

```
# cd ~
```

これでGithubからファイルをクローンします。

```
# sudo git clone https://www.github.com/itsaareez1/react-example 
```

上記のgitリンクを使ってプロジェクトをクローンします。

コマンドでcloneディレクトリに移動します。

```
# cd react-example
```

Nginxが動作するようにindex.htmlやJSファイル、CSSファイルなどのページを格納したフォルダを作成するには、yarnのbuildコマンドを実行する必要があります。

```
# sudo yarn && sudo yarn build
```

ここで、Nginx経由でファイルにアクセスできるようにするために、シンボリックリンクを作成する必要があります。Nginxはアプリケーションを**/var/www**ディレクトリに配置します。 シンボリックリンクの作成は以下のコマンドを実行してください。

```
# sudo ln -s ~/react-example /var/www/react-example
```

Nginxがシンボリックリンクを正しく動作させるための権限を付与するには、以下のコマンドを実行します。

```
# sudo chmod -R 755 /var/www
```

ここで、利用可能なサイトディレクトリにnginxサーバーブロックを設定します。以下のコマンドを実行すると、ファイルが開きます。

```
# sudo nano /etc/nginx/sites-available/react
```

開いたファイルに以下のテキストをコピーし、**softpedia.xyz**をドメイン名またはECSのIPアドレスに変更して保存してください。

```
server {
        listen 80;

        root /var/www/react-example/build;
        index index.html index.htm index.nginx-debian.html;

        server_name softpedia.xyz;

        location / {
                try_files $uri /index.html;
        }
}
```

ここで、利用可能なサイトディレクトリにある react の設定用のシンボリックリンクを、有効になっているサイトディレクトリに作成します。

```
# sudo ln -s /etc/nginx/sites-available/react /etc/nginx/sites-enabled/react
```

nginxの構文が正しいかどうかを確認するには、以下のコマンドを実行します。

```
# sudo nginx -t
```

設定をロードするには、nginx サーバーを再起動します。

```
# sudo systemctl restart nginx
```

すべての設定が正しく行われているかどうかを確認するために、ブラウザでIPアドレスやドメインにアクセスすると、以下のような画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b6de04e1-4d4f-767c-c680-c6a771a13687.png)


#Webhooks のインストールと設定
設定可能なエンドポイントを持つ HTTP サーバをフックと呼びます。Webhook サーバは、いくつかの HTTP リクエストを受信したときに、設定可能なルールのセットに従ったカスタマイズ可能なコードを実行します。

ホームに移動する

```
# cd ~
```

webhookをダウンロードします。

```
# sudo wget https://github.com/adnanh/webhook/releases/download/2.6.6/webhook-linux-amd64.tar.gz
```

ダウンロードしたフォルダを展開します。

```
# sudo tar -xvf webhook-linux-amd64.tar.gz
```

バイナリを**/usr/local/bin**に移動して、自分の環境で利用できるようにします。

```
# sudo mv webhook-linux-amd64/webhook /usr/local/bin
```

ダウンロードしたフォルダを削除します。

```
# sudo rm -rf webhook-linux-amd64*
```

ここで、主にサードパーティ製のアプリケーションを配置するoptフォルダ内に、スクリプトとフックのためのディレクトリを作成します。

```
# sudo mkdir /opt/scripts

# sudo mkdir /opt/hooks
```

これらのディレクトリの権限をユーザ名に割り当てます。

```
# sudo chown -R aareez:aareez /opt/scripts
# sudo chown -R aareez:aareez /opt/hooks
```

GitHubがHTTPリクエストを送信すると、JSON配列ファイルで定義されたルールに基づいてwebhookが起動されます。ここで、webhook用の設定ファイルを作成する必要があります。そのためには、以下のコマンドを実行します。

```
# sudo nano /opt/hooks/hooks.json
```

開いたファイルに以下のテキストをコピーします。

```
[
  {
    "id": "redeploy-app",
    "execute-command": "/opt/scripts/redeploy.sh",
    "command-working-directory": "/opt/scripts",
    "pass-arguments-to-command":
    [
      {
        "source": "payload",  
        "name": "head_commit.message"
      },
      {
        "source": "payload",
        "name": "pusher.name"
      },
      {
        "source": "payload",
        "name": "head_commit.id"
      }
    ],
    "trigger-rule":
    {
      "and":
      [
        {
          "match":
          {
            "type": "payload-hash-sha1",
            "secret": "654321Ab", 
            "parameter":
            {
              "source": "header",
              "name": "X-Hub-Signature"
            }
          }
        },
        {
          "match":
          {
            "type": "value",
            "value": "refs/heads/master",
            "parameter":
            {
              "source": "payload",
              "name": "ref"
            }
          }
        }
      ]
    }
  }
]
```

#GitHub の通知を設定する
GitHub リポジトリで、master へのコミットが発生した際に HTTP リクエストが発生するように設定するには、以下の手順に従う必要があります。

1、GitHub リポジトリを開き、以下のように**設定**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/e6d17fc4-e019-f270-4d38-c3e680ad9af4.png)

2、この後、Webhooksセクションに移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/6c65e017-3685-6d07-c759-0dbc9bb077b6.png)

3、Webhookの追加ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/6771e595-a427-77a2-2de6-ee347162ec76.png)


4、**Payload URL** には http://your_server_ip:9000/hooks/redeploy-app と入力してください。softpedia.xyzをECSのIPアドレスまたはドメインに置き換えることを忘れないでください。**Content type**には、option **application/json**を選択します。hooks.jsonファイルでは、秘密鍵**654321Ab**を使用していますが、任意のものを使用することができます。秘密鍵には654321Abを使用します。その後、**Just the push event**オプションを選択します。**アクティブ**チェックボックスにチェックを入れて、**Add webhook**ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/d7c5acf6-90aa-1290-ae5d-135bb78864ac.png)

これで、あなたや誰かが GitHub リポジトリにコミットするたびに、GitHub はコミットイベントに関する情報を含む Payload を含む POST リクエストを送信するようになりました。

#リデプロイスクリプトを書く
redeploy.shスクリプトにWebhookを指定しているので、スクリプトを作成する必要があります。以下のコマンドを実行して、スクリプトを書くためのファイルを開きます。

```
# sudo nano /opt/scripts/redeploy.sh
```

以下のコードをコピーして、開いたファイルに貼り付けてください。

```
#!/bin/bash -e

function cleanup {
      echo "Error occoured"
      # !!Placeholder for Slack notification
}
trap cleanup ERR

commit_message=$1 # head_commit.message
pusher_name=$2 # pusher.name
commit_id=$3 # head_commit.id

# !!Placeholder for Slack notification

cd ~/react-example/
sudo git pull origin master
sudo yarn && yarn build

            # !!Placeholder for Slack notification 
```

以下のコマンドでスクリプトを実行可能な状態にします。

```
# sudo chmod +x /opt/scripts/redeploy.sh
```

Nginxは/var/wwwフォルダに**react-example**を置くように設定されているため、上記のスクリプトを実行するとビルドディレクトリが更新され、新しいファイルがサーバに送られてきます。

```
## run webhook server to test configuration. Execute the command below for it.
# webhook -hooks /opt/hooks/hooks.json -verbose
```

すべてが正常に動作すると、以下のような画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b11a7f3c-42a9-a31f-31b3-4bc18d7829fe.png)


テストのためには、Webhookを起動したまま、複製セッションを開き、以下のコマンドを実行してください。

```
# sudo git commit --allow-empty -m "Trigger notification"
# sudo git push origin master
```

以下のような画面が表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b251a9ed-64ab-5991-e046-9575f7702d73.png)


#Slackの通知を統合する
Slackの通知を追加するには、**redeploy.sh**を修正してSlackからの通知を送受信するようにします。Slackの設定は以下の手順で行います。

1、左上のドロップダウンメニューをクリックし、「**Slackのカスタマイズ**」を選択します。
2、次に、**アプリの設定**に移動します。
3、**管理**パネルで、「**統合を選択**」を選択します。
4、Incoming Hooks integrationを検索します。
5、**Add Configuration**をクリックします。
6、チャンネルを選択または作成します。
7、**Add Incoming Webhooks integration**をクリックします。
Slackのウェブフック設定が表示されます。WebhookのURLをメモしておきます。コマンドを使ってredeploy.shスクリプトを開きます。

```
# sudo nano /opt/scripts/redeploy.sh
```

前のコードを削除し、以下のコードを追加します。**slack_webhook_url**を**WebhookのURL**に置き換えることを忘れないでください。

```
#!/bin/bash -e

function cleanup {
      echo "Error occoured"
      curl -X POST -H 'Content-type: application/json' --data "{
              \"text\": \"Error occoured while building app with changes from ${pusher_name} (${commit_id} -> ${commit_message})\",
              \"username\": \"buildbot\",
              \"icon_url\": \"https://i.imgur.com/JTq5At3.png\"
      }" your_slack_webhook_url
}
trap cleanup ERR

commit_message=$1 # head_commit.message
pusher_name=$2 # pusher.name
commit_id=$3 # head_commit.id

curl -X POST -H 'Content-type: application/json' --data "{
        \"text\": \"Started building app with changes from ${pusher_name} (${commit_id} -> ${commit_message})\",
        \"username\": \"buildbot\",
        \"icon_url\": \"https://i.imgur.com/JTq5At3.png\"
}" your_slack_webhook_url

cd ~/react-example/
sudo git pull origin master
sudo yarn && sudo yarn build

curl -X POST -H 'Content-type: application/json' --data "{
        \"text\": \"Build and deploy finished with changes from ${pusher_name} (${commit_id} -> ${commit_message})\",
        \"username\": \"buildbot\",
        \"icon_url\": \"https://i.imgur.com/JTq5At3.png\"
}" your_slack_webhook_url
```

テストは、Webhookを起動した状態で、セッションを複製して以下のコマンドを実行してください。

```
# sudo git commit --allow-empty -m "Trigger notification"
# sudo git push origin master
```

これで完了です! Slackチャンネルでは、開始・終了したアプリケーションのビルドに関する通知やメッセージを受け取ることができます。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*