Mattermostとは
オープンソースのSlack風チャットツールです。社内のゴニョゴニョでslackを使えないエンジニアにとってローカルサーバで動作させることのできる救いのチャットシステム。たぶん。
環境
- EC2:CentOS Linux release 7.6.1810 (Core)/3.10.0-957.1.3.el7.x86_64
- RDS: MySQL5.7.22
- Mattermost:5.13.2
- 独自ドメイン:ムームードメイン管理
参考情報
- 公式のインストールマニュアル(RHEL7/CentOS7兼用)
インストール
EC2インスタンス起動
無料枠で遊びたい設定したいためt2.microを選択。メモリ、DISKも初期選択のままです。AMIはマーケットでcentos7があったのでそれをそのまま使いました。ちなみにSSHでログインするときのユーザ名は「centos」です。(いつもの「ec2-user」ではない)
最初やっとけ的なアレ
[centos@ip-172-31-46-159 ~]$ sudo yum update
[centos@ip-172-31-46-159 ~]$ sudo yum upgrade
MySQLサーバのインストール
公式はサーバにインストールする手順ですが、せっかくAWSを使うのでRDSを使おうと思います。サーバーレスがスマートでオシャンティですしお寿司。Auroraを使おうと思ったら無料枠の対象外だったでござる。あぶねえ!
- MySQL5.7.22
- インスタンス識別子:mattermost-db
- マスターユーザ名:admin
- パスワード:adminadmin
- バースト可能クラス (t クラスを含む) /db.t2.micro
- storage: 20GiB
- ストレージの自動スケーリング :OFF
- VPCはデフォルト
EC2からRDSへ接続
EC2にmysqlクライアントをインストールしておく
[centos@ip-172-31-46-159 ~]$ sudo yum install mysql
先ほど作成したDBインスタンスのセキュリティグループにmysqlのポート(3306)を穴あけしておきましょう。ソースはEC2が所属するサブネットか、EC2のIPを直接叩いてもOK(/32)。この記事はセキュリティは基本的に考慮しないので本番環境で構築する際は注意してください。
EC2から以下のコマンドでRDSにアクセスできるか試してみます。うん、成功しました。エンドポイントはマネジメントコンソールから確認できるYO!
mysql -h [DBインスタンスのエンドポイント名] -P 3306 -u [マスターユーザ名] -p
[centos@ip-172-31-46-159 ~]$ mysql -h mattermost-db.XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com -P 3306 -u admin -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.22-log Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
MySQL [(none)]>
MySQL [(none)]>
MySQL [(none)]>
MySQL [(none)]>
MySQL [(none)]> exit
Bye
RDSを利用するのでマシン起動時のmysqldの自動起動設定などはとりあえず不要です。
mattermost用のユーザーを作成、続けてDBを作成します。権限付与も忘れずに
MySQL [(none)]> create user 'mmuser'@'%' identified by 'adminadmin';
Query OK, 0 rows affected (0.02 sec)
MySQL [(none)]> create database mattermost;
Query OK, 1 row affected (0.02 sec)
ySQL [(none)]> grant all privileges on mattermost.* to 'mmuser'@'%';
Query OK, 0 rows affected (0.00 sec)
Mattermostのインストール
EC2に戻ってmattermostのインストール作業を行っていきます。たぶんwgetがないので最初に入れてくださいw んで、mattermostの最新版は2019/8/8時点で5.13.2です。
[centos@ip-172-31-46-159 ~]$ yum -y install wget
[centos@ip-172-31-46-159 ~]$ wget https://releases.mattermost.com/5.13.2/mattermost-5.13.2-linux-amd64.tar.gz
解凍して/optへ移動、/dataディレクトリを作成します。ここにチャットのログ等が入るようです。
[centos@ip-172-31-46-159 ~]$ tar -xvzf mattermost-5.13.2-linux-amd64.tar.gz
[centos@ip-172-31-46-159 ~]$ sudo mv mattermost /opt
[centos@ip-172-31-46-159 ~]$
[centos@ip-172-31-46-159 ~]$
[centos@ip-172-31-46-159 ~]$ sudo mkdir /opt/mattermost/data
mattermostのユーザを追加しーのDirのオーナー変えーのパーミッション変えーの。
[centos@ip-172-31-46-159 ~]$ sudo useradd --system --user-group mattermost
[centos@ip-172-31-46-159 ~]$
[centos@ip-172-31-46-159 ~]$ sudo chown -R mattermost:mattermost /opt/mattermost
[centos@ip-172-31-46-159 ~]$
[centos@ip-172-31-46-159 ~]$ sudo chmod -R g+w /opt/mattermost
mattermostの設定ファイルを変更します。132行目にある「DataSource」を先ほど設定してきたDBの情報に変更しましょう。
[centos@ip-172-31-46-159 ~]$ sudo vi /opt/mattermost/config/config.json
##変更前
132 "DataSource": "mmuser:mostest@tcp(dockerhost:3306)/mattermost_test?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s",
##書式
"mmuser:<mmuser-password>@tcp(<host-name-or-IP>:3306)/<database-name>?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s"
#変更後
132 "DataSource": "mmuser:adminadmin@tcp(mattermost-db.XXXXXXXXXX.ap-northeast-1.rds.amazonaws.com:3306)/mattermost?charset=utf8mb4,utf8\u0026readTimeout=30s\u0026writeTimeout=30s",
mattermostが動くかどうかテストしてみます
[centos@ip-172-31-46-159 ~]$ cd /opt/mattermost
[centos@ip-172-31-46-159 ~]$ sudo -u mattermost ./bin/mattermost
起動させるとログが表示されるのですが、とりあえずerror表示がなければおk。ログ張っておきます。errorあるような気がしますが気にしない。
{"level":"info","ts":1565222771.5601966,"caller":"utils/i18n.go:83","msg":"Loaded system translations for 'en' from '/opt/mattermost/i18n/en.json'"}
{"level":"info","ts":1565222771.5603452,"caller":"app/server_app_adapters.go:58","msg":"Server is initializing..."}
{"level":"info","ts":1565222771.5658677,"caller":"sqlstore/supplier.go:224","msg":"Pinging SQL master database"}
{"level":"info","ts":1565222772.380953,"caller":"sqlstore/upgrade.go:105","msg":"The database schema has been set to version 5.13.0"}
{"level":"error","ts":1565222774.741623,"caller":"app/server_app_adapters.go:125","msg":"SiteURL must be set. Some features will operate incorrectly if the SiteURL is not set. See documentation for details: http://about.mattermost.com/default-site-url"}
{"level":"info","ts":1565222774.741879,"caller":"filesstore/localstore.go:33","msg":"Able to write files to local storage."}
{"level":"info","ts":1565222774.7504945,"caller":"app/license.go:41","msg":"License key from https://mattermost.com required to unlock enterprise features."}
{"level":"info","ts":1565222774.7559462,"caller":"app/migrations.go:26","msg":"Migrating roles to database."}
{"level":"info","ts":1565222774.9661043,"caller":"sqlstore/post_store.go:1279","msg":"Post.Message supports at most 16383 characters (65535 bytes)"}
{"level":"info","ts":1565222774.9856367,"caller":"app/migrations.go:102","msg":"Migrating emojis config to database."}
{"level":"info","ts":1565222776.184451,"caller":"mlog/log.go:164","msg":"Starting up plugins"}
{"level":"info","ts":1565222778.6988173,"caller":"mlog/sugar.go:19","msg":"Ensuring Surveybot exists","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1565222778.7479758,"caller":"mlog/sugar.go:19","msg":"Surveybot created","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1565222778.7875261,"caller":"mlog/sugar.go:19","msg":"Upgrade detected. Checking if a survey should be scheduled.","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1565222778.7885778,"caller":"app/server.go:213","msg":"Current version is 5.13.0 (5.13.2/Wed Jul 24 17:25:26 UTC 2019/9a8b0906fdbf2c2a309db2400f4bcc5902800e2c/1ab74b3ea1137c385e03a9982dce917a4128f903)"}
{"level":"info","ts":1565222778.7886064,"caller":"app/server.go:214","msg":"Enterprise Enabled: true"}
{"level":"info","ts":1565222778.788629,"caller":"app/server.go:216","msg":"Current working directory is /opt/mattermost"}
{"level":"info","ts":1565222778.7886417,"caller":"app/server.go:217","msg":"Loaded config","source":"file:///opt/mattermost/config/config.json"}
{"level":"info","ts":1565222778.8262846,"caller":"mlog/sugar.go:19","msg":"Scheduling next survey for Aug 29, 2019","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1565222778.8947675,"caller":"jobs/workers.go:68","msg":"Starting workers"}
{"level":"info","ts":1565222778.8948622,"caller":"app/server.go:413","msg":"Starting Server..."}
{"level":"info","ts":1565222778.895643,"caller":"app/server.go:479","msg":"Server is listening on [::]:8065"}
{"level":"info","ts":1565222778.904744,"caller":"app/web_hub.go:75","msg":"Starting 2 websocket hubs"}
{"level":"info","ts":1565222778.9057112,"caller":"jobs/schedulers.go:72","msg":"Starting schedulers."}
{"level":"error","ts":1565222778.9439611,"caller":"plugin/hclog_adapter.go:60","msg":"reading plugin stderr","plugin_id":"com.mattermost.nps","wrapped_extras":"errorread |0: file already closed"}
{"level":"error","ts":1565222808.7904632,"caller":"plugin/health_check.go:95","msg":"Health check failed for plugin com.mattermost.nps, error: Plugin process not found, or not responding"}
{"level":"warn","ts":1565222808.7905388,"caller":"plugin/hclog_adapter.go:51","msg":"error closing client during Kill","plugin_id":"com.mattermost.nps","wrapped_extras":"errconnection is shut down"}
{"level":"warn","ts":1565222808.790574,"caller":"plugin/hclog_adapter.go:53","msg":"plugin failed to exit gracefully","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1565222808.806801,"caller":"mlog/sugar.go:19","msg":"Ensuring Surveybot exists","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1565222844.0351005,"caller":"migrations/worker.go:109","msg":"Worker: Job is complete","worker":"Migrations","job_id":"pc6859js17fwjr1fa3hqm9rk4r"}
^C{"level":"info","ts":1565222993.6133847,"caller":"app/server.go:324","msg":"Stopping Server..."}
{"level":"info","ts":1565222993.613451,"caller":"app/web_hub.go:120","msg":"stopping websocket hub connections"}
{"level":"info","ts":1565222993.6137729,"caller":"app/plugin.go:193","msg":"Shutting down plugins"}
{"level":"error","ts":1565222993.6156826,"caller":"plugin/hclog_adapter.go:60","msg":"reading plugin stderr","plugin_id":"com.mattermost.nps","wrapped_extras":"errorread |0: file already closed"}
{"level":"info","ts":1565222993.6159368,"caller":"sqlstore/supplier.go:917","msg":"Closing SqlStore"}
{"level":"info","ts":1565222993.616295,"caller":"jobs/workers.go:184","msg":"Stopped workers"}
{"level":"info","ts":1565222993.6163175,"caller":"jobs/schedulers.go:140","msg":"Stopping schedulers."}
{"level":"info","ts":1565222993.6163528,"caller":"jobs/schedulers.go:75","msg":"Schedulers stopped."}
{"level":"info","ts":1565222993.616367,"caller":"app/server.go:357","msg":"Server stopped"}
[centos@ip-172-31-46-159 mattermost]$
mattermostをdaemon化。
[centos@ip-172-31-46-159 mattermost]$ sudo touch /etc/systemd/system/mattermost.service
[centos@ip-172-31-46-159 mattermost]$ sudo vi /etc/systemd/system/mattermost.service
[Unit]
Description=Mattermost
After=syslog.target network.target mysqld.service ##ここの表記を「postgresql-9.4.service」→「mysqld.service」へ変更する
[Service]
Type=notify
WorkingDirectory=/opt/mattermost
User=mattermost
ExecStart=/opt/mattermost/bin/mattermost
PIDFile=/var/spool/mattermost/pid/master.pid
TimeoutStartSec=3600
LimitNOFILE=49152
[Install]
WantedBy=multi-user.target
[centos@ip-172-31-46-159 mattermost]$ sudo chmod 664 /etc/systemd/system/matter most.service
[centos@ip-172-31-46-159 mattermost]$
[centos@ip-172-31-46-159 mattermost]$ sudo systemctl daemon-reload
[centos@ip-172-31-46-159 mattermost]$
[centos@ip-172-31-46-159 mattermost]$ sudo systemctl enable mattermost
Created symlink from /etc/systemd/system/multi-user.target.wants/mattermost.service to /etc/systemd/system/mattermost.service.
[centos@ip-172-31-46-159 mattermost]$
[centos@ip-172-31-46-159 mattermost]$ sudo systemctl start mattermost
ブラウザーで下記URLを開いてみて表示されたら成功です。curlでもいいですが。AWSのEC2のSGで8065のポートを開けてあげるのをお忘れなく!
http://xxx.xxx.xxx.xxx:8065/
mattermostの初期設定
システムを管理するユーザを作成していきます。管理者のメールアドレスとユーザ名、PWDを設定しましょう。
「Go to System Console」をクリック
サイトのURLを設定しましょう。とりあえず今はHTTPS化していないので「http://xxx.xxx.xxx.xxx:8065/」を入力しておきます。
通知設定をいじります。
- Set Enable Email Notifications → 「True」
- Set Notification Display Name → 「No-Reply」
- Set Notification From Address → 管理者のメールアドレス
SMTPサーバの設定は・・・・とりあえず今は放置します。てへ☆
ファイルと画像のストレージ設定
ユーザが添付するファイルや画像はDBに保管されるのではなく、サーバのローカル、またはAWSのS3に設定できます。なるべく十分なスペースを確保しろとのことなのでS3に設定してみます。
AWS側の設定
- S3バケットの作成
- IAMにてS3FullAccessのユーザを作成 (credentialsのCSVを忘れずに)
Mattermost側の設定
File Storage System: | Amazon S3 | プルダウン選択 |
Local Storage Directory: | ./data/ | デフォルト |
Maximum File Size: | 50 | デフォルト |
Amazon S3 Bucket: | [S3のバケット名] | AWSで確認 |
Amazon S3 Region: | ap-northeast-1 | AWSで確認 |
Amazon S3 Access Key ID: | [***********] | IAMユーザ作成時のCSV(credentials)参照 |
Amazon S3 Endpoint: | s3.amazonaws.com | デフォルト |
Amazon S3 Secret Access Key: | [***********] | IAMユーザ作成時のCSV (credentials) 参照 |
Enable Secure Amazon S3 Connections: | true | デフォルト |
Enable Amazon S3 Debugging: | false | デフォルト |
上記設定を入力したら、「Save」をクリックしてから「Test Connection」をクリックします。すると「Connection was successful 」と出るはず。
Mattermostでチャットしてみる
ここまで設定できたら一通りチャットが可能です。Teamを作成したらすぐに遊べます。ファイルも添付可能です(S3にてファイルが保存されていることを確認)
日本語化
account settingsから行けます。素晴らしい。
番外編
こういう構成でつくりたい
TLS(SSL)サーバ設定
公式によると、ユーザからのアクセスをHTTPS化するには2種類方法がある模様。
- さきほど作成したmattermostサーバをTLS化
- proxyサーバ(nginx)を別に建ててTLS化する
200名以上のユーザを予定するならproxy推奨とのことなので、せっかくだから、そのままAWSでproxy(ELB)たててみる。
AWSでELB(proxy)を作成する
上記のとおり、proxyサーバをEC2でもう一台作成するのはスマートでは無いので、ELBを使って負荷分散する仕組みにします。「サーバーレスが昨今の流行りじゃよぉ~」とばっちゃが言ってたし。こんな感じになります。
client ---- ELB(ALB) ---- server(mattermost)
ついでにELBでサーバ証明書を入れてSSLターミネーションします。セキュア&極力serverに負荷をかけないことが目的です。システム間のポート番号は以下のようになります。
client --(:443)-- ELB(ALB) --(:80)-- server(mattermost)
ELB作成のポイント
- リスナーはHTTPS:443
- SSL証明書はACMを利用(AWSで無料で作成できるのでおすすめ!)
- 転送先はHTTPでinstanceをターゲット
- ヘルスチェックはdefault値のまま
memo
ALBのヘルスチェックはmattermost(EC2)のport:80に設定(下記参照)。んでずっとstatusが「unhealthy」でなんでやろ?と思ってたらEC2のSGで80番を許可するのを忘れていたというオチ・・・。おなじくELBの443も許可してあげてねッ
mattermostのポート変更
環境>ウェブサーバー>接続待ちアドレス
ウェルノウンポート(80)をmattermostが使うために以下のコマンドを実行して再起動
[centos@ip-172-31-46-159 mattermost]$ sudo setcap cap_net_bind_service=+ep ./bin/mattermost
[centos@ip-172-31-46-159 mattermost]$ sudo service mattermost restart
Redirecting to /bin/systemctl restart mattermost.service
Route 53でホストゾーン作成
現在運用中の個人的なブログはさくらのRSでそのまま利用し、mattermostはサブドメインでAWSで遊べる構成にしたい!
もともとドメイン(ここではhogehoge.com)を持っていたのですが、今利用しているサービスだとDNSのゾーン編集ができない(サブドメインのAレコード設定ができない)ため、下記のように変更しました。
そもそもドメイン名でELBにアクセスするにはRoute53の利用が必須のようです。
変更前
- hogehoge.comはムームードメインで管理している
- ネームサーバはさくらインターネットのNSを指定
- www.hogehoge.comはさくらのRSを使用中
- mm.hogehoge.comでAWS(EC2)で作ったmattermostサーバにアクセスさせたい
変更後
- hogehoge.comはムームードメインで管理している
- ネームサーバはAWSのRoute 53を使用する
- www.hogehoge.comはさくらのRSを使用中
- mm.hogehoge.comでAWS(EC2)で作ったmattermostサーバにアクセス
Route53作成のポイント
Route53のレコードセットは以下のように設定しました。
名前 | タイプ | 値 | 備考 |
hogehoge.com | A | [さくらのRSのIP] | 追加 |
hogehoge .com | NS | ns-XXX.awsdns-XX.net. ns-XXXX.awsdns-XX.org. ns-XXXX.awsdns-XX.co.uk. ns-XXX.awsdns-XX.com. | デフォルト値 |
hogehoge.com | SOA | ns-XXXX.awsdns-XX.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400 | デフォルト値 |
mm.hogehoge.com | A | [ELBのDNS名] | 追加 |
追加が必要なのは運用中のブログをホストしているさくらのRSのAレコードと、MattermostをホストしているAWS(ELB)のAレコードです。後者はRoute53でホストゾーン作成でレコードセットを登録する際、エイリアスでELBのDNS名を選択できます。TTLはそのまんまです。
ムームードメイン側の設定
上記の通り、NSはAWSを使用するのでその旨の設定をムームードメイン側に設定する必要があります。
ドメイン管理>ドメイン操作>ネームサーバ設定変更> GMOペパボ以外 のネームサーバを使用する
ここに上記route53のレコードセットで出てきたデフォルトのNS(4つ)を入力して設定を保存します。
確認してみる
ブログにはhttp://hogehoge.comで、Mattermostにはサブドメインのhttps://mm.hogehoge.comでアクセスできることを確認できたら完了です。アクセスできない場合、DNSの設定が浸透するには時間がかかるので、半日くらいは放置しておきましょう。
まとめ
- 使い心地はslackと比べて悪くない
- アプリはiOS、android、windows、Linuxと幅広く対応しており便利
- AWSに組み込んでも多分うまく動く(少なくとも上記の構成では)
- dockerでも動かせるらしいのでAWS(Fargate,ECS)で構成もできそう(あまり詳しくないw)
- EC2は1台構成なので、複数台&AutoScaleで動くか試してみたい。いづれ・・・