MattermostをGCPサーバにデプロイしてみました

# Overview
Mattermost（コミュニケーションアプリ）をGCEサーバにパッケージを使ってデプロイした手順を書いてみます。
使用するサービスはGCPのみで、パッケージを使って簡単に構築することができるため、初心者向けの内容になっています。

#### 前提として次の作業を終えていること ※以下の手順は省略します
- GCPプロジェクトを作成済み
- ドメインホストで独自のドメインを取得済み
# Process
1. MattermostパッケージでGCEインスタンスをデプロイする
1. 展開されたVMのIPアドレスを固定する
1. DNSを設定する
1. サーバのSSL化
# Let's try it !
今回は "Mattermost(Google Click to Deploy)" というパッケージを使用しています。
パッケージの主要となるアーキテクチャは以下のようになっています。
- OS: Debian 10.13
- VCS: Git 2.20.1
- APP: Mattermost 6.5.0
- DB: MySQL-Server 5.7.41
- Web Server: Nginx 1.14.2

### Marketplace
GCPマーケットプレイスでパッケージを検索し、サーバの構成を決めてデプロイする。
- 今回の構成
    - ゾーン：`us-central1-a`
    - マシンタイプ：`E2,e2-small（2vCPU、2GBメモリ）`
    - ディスク：`Standard 40GB`
    - 月間推定合計額：`JPY 2,041/月` ※2022/10/1時点

無料枠で作りたい場合は以下の構成にしてください。
- 無料の構成
    - ゾーン：`バージニア州北部を除く米国リージョン`
    - マシンタイプ：`e2-micro（2vCPU、1GBメモリ）`
    - ディスク：`Standard 30GB`
 
構成内容を確認し実行すると、VMインスタンスが展開されます。

### VPC network
VMインスタンスへ固定IPを割り当てる。
※これを設定しないとサーバを再起動する度にIPアドレスが変わってしまいます

- 静的IPアドレスを予約
    - 名前：`予約する静的IPのタイトル`
    - 接続先：`VMインスタンス名を選択`
    - 

### Cloud DNS
VMインスタンスのDNS設定をおこなう

- ゾーンを作成
    - ゾーン名：`ゾーンのタイトル`
    - DNS名：`独自ドメイン`

- ゾーンを編集
    - NSレコード：`ドメインホストの管理画面でここで発行されたNSレコードに変更する`
    - Aレコード：`VMに割り当てた静的IP`

今回の手順では、GoogleのDNSサービスであるCloud DNSを使ってネームサーバの管理元を変更しましたが、特に管理元を変える必要がないのであれば、ホストドメインのAレコードにVMインスタンスのIPアドレスを追加してください。

### VMインスタンスに接続
WebサーバをSSL化するために、VMインスタンス（サーバ内）へSSHで接続します。
今回はgcloudを使って接続しました。
因みに最も簡単であり安全な接続方法は、GCPプロジェクトのGCEサービス管理画面から接続したいVMインスタンスの「SSH」をクリックするだけで、ブラウザにCLIが提供されます。

※ [instance_name]を作成したVMインスタンス名に置き換えてください。
```zsh
gcloud compute ssh [instance_name]
```
参考：[Google Cloud](https://cloud.google.com/sdk/gcloud/reference/compute/ssh)

### WebサーバのSSL化（証明書発行）
今回はCertbotという証明書発行ツールをインストールして使用します。

**Certbotインストール**
```bash
sudo apt install certbot
```
**バージョン確認**
```bash
certbot --version
```
**Webサーバを停止**
```bash
sudo nginx -s stop
```
**SSL証明書を発行**
※ [example.com]をドメイン名に置き換えてください。
※ [e-mail address]をお持ちのメールアドレスに置き換えてください。
```bash
sudo certbot certonly --standalone -d [example.com] -m [e-mail address] --agree-tos
```
**Certbotからメールを送ってよいか聞かれる　※どちらでもよい（Yes or No）**
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
上記の要約は「Certbotを開発する組織から組織の活動に関するニュースを送っても良いか？」といった内容です。
```
(Y)es/(N)o: Y
```
### WebサーバのSSL化（設定ファイルの追加）
これで証明書の発行ができました。
そして、リクエストは443ポート（HTTPS）で受けて、80ポート（HTTP）へのリクエストは443へリダイレクトするように設定を追加します。

**追加設定用ディレクトリのパス**
```bash
cd /etc/nginx/conf.d
```
**設定ファイル（ssl.conf）を作成**
```bash
sudo vi ssl.conf
```
**設定ファイル（ssl.conf）の中身**
※ [example.com]をドメイン名に置き換えてください（4箇所）
```nginx
server {
  listen 80;
  server_name localhost;
  return 301 https://[example.com]$request_uri;
}

server {
  listen 443;
  server_name [example.com];

ssl on;
ssl_certificate /etc/letsencrypt/live/[example.com]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[example.com]/privkey.pem;

location ~ /api/v[0-9]+/(users/)?websocket$ {
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  client_max_body_size 50M;
  proxy_set_header Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Frame-Options SAMEORIGIN;
  proxy_buffers 256 16k;
  proxy_buffer_size 16k;
  client_body_timeout 60;
  send_timeout 300;
  lingering_timeout 5;
  proxy_connect_timeout 90;
  proxy_send_timeout 300;
  proxy_read_timeout 90s;
  proxy_pass http://backend;
  }

location / {
  client_max_body_size 50M;
  proxy_set_header Connection "";
  proxy_set_header Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Frame-Options SAMEORIGIN;
  proxy_buffers 256 16k;
  proxy_buffer_size 16k;
  proxy_read_timeout 600s;
  proxy_cache mattermost_cache;
  proxy_cache_revalidate on;
  proxy_cache_min_uses 2;
  proxy_cache_use_stale timeout;
  proxy_cache_lock on;
  proxy_http_version 1.1;
  proxy_pass http://backend;
  }
}
```
**設定ファイルの記述チェック**
```bash
nginx -t
```
**サーバ再起動**
```bash
sudo nginx -s reload
```
**リダイレクトチェック**
```bash
curl -I http://[ドメイン]
```
（301が返されたらクリア）

# Conclusion
以上、GCPでMattermostアプリケーションをデプロイする手順でした。
また、GCPマーケットプライスでパッケージを扱う注意点として、
今回使用したGoogleのパッケージ以外にも、SSL化がより便利になったBitnamiのパッケージも存在しますが、
Bitnami独自のシェルスクリプトや証明書ツールが組み込まれているため、本記事と同様のやり方では注意が必要です。