自前サーバでRocket Chatを構築するメモ
世はクラウド全盛時代。サーバーレスで基本企業やユーザは、利用させてもらうだけのお手軽な時代。とはいえ、様々な事情やセキュリティの観点から使わせないという企業も未だに多いのは事実。そんな時の助けになるのが、様々なオープンソース製品。
そんなものの1つにチャットシステムがあります。LINE駄目、Slack駄目と言ってもそれだけじゃ、ただシャドーITを推進しているようなもの。企業はシャドーIT撲滅したいなら、代わりになるものを提供しなければなりません。そこで使いたいのがRocket Chat。クラウドサービスもあり、またAndroidやiOS用のアプリも用意されていて、非常にオススメです。
図:病院やセキュアな環境で使える最高のシステムかも
今回使用するもの
今回は仮想環境上にLinuxを入れて、其の中にRocket Chat Serverを作るというベタなやり方です。Docker上に構築するという今どきな手法もありますよ。
また、RocketchatのメッセージログであるBSONファイルをJSONに変換したものから、Excelで読み取ってシートデータにするプログラムを作成しました。
いざ構築をしましょう
いろいろ注意点
httpd.confが見つからない
Rocket ChatはWebアプリケーションなので、SnapでインストールするとApache2もインストールされる。今回Ubuntuにインストールしてるのですが、肝心のhttpd.confが見つからない。色々なサイトでApacheを弄る場合これを編集するみたいなことが一般論みたいに書かれていますが、Ubuntuの場合にはhttpd.confがありません。
代わりに/etc/apache2の中にapache2.confというhttpd.confの役目を果たすものがあるので、編集する場合にはこちらを利用すると良いでしょう。
図:apache2.confが設定ファイルになります
ARM64の場合の注意点
M1 Mac環境やRaspberry PiのようなARM64環境の場合、Rocket Chat Server自体はインストールできるのですが、MongoDBの5.xからCPUにAVX命令が無いとインストールできないといった事象に巻き込まれてインストールが出来ません。
2023年頃から報告はありますが、解決法がどこにも掲示されておらず。
5.x以上のARM64対応のMongoDBはこちらのサイトにあるのですが、手動でdebをインストールしても解決できず。
図:MongoDBが原因でインストール出来ない
サーバーのインストール
Ubuntu Linuxのインストールについてはここでは省略します。今は昔と違って、Linuxのインストールはとてつもなく簡単になってるので、ここで躓く人は殆どいないでしょう。
ここでは、Rocket Chat Serverのインストールを中心に紹介します。Ubuntu Linux 16.04より採用されたsnapというパッケージ管理システムのおかげで、データベースとして利用するMongoDBやら設定ファイルを書かずに済むのでお手軽です。
- ターミナルを起動する
- まずは、OSを最新にアップデートしましょう。sudo apt-get updateを実行
- さらに、パッケージのアップデートの為に、sudo apt-get dist-upgrade -yを実行
- しばらくアップデート作業が完了するまで待機します。
- 完了したら、sudo snap install rocketchat-serverで、Rocket Chat本体をインストール(sudo snap remove rocketchat-server でアンインストール)
- インストールが完了すると、Rocket Chat ServerおよびMongoDBのインストールが完了しています。サービスはOS起動時に自動で立ち上がるようになっています。(手動で起動する時はsystemctl start snap.rocketchat-server.rocketchat-server.serviceを実行する)
- Rocket Chat Serverの稼働状況は、systemctl status snap.rocketchat-server.rocketchat-server.serviceで確認可能です。
- これですでにもうRocket Chatは使えるようになっています。
ログインして環境設定
まずは、http://localhost:3000にアクセスします。Rocket Chatのメイン画面が表示されます。初回起動時にだけ管理者のアカウントとして、ユーザ名(ニックネーム)、メアド、パスワードの設定を求められます。作成完了したら、早速ログインしましょう。
- http://localhost:3000/admin/infoの管理画面に入る
- 非常に沢山の設定項目があるが、主に使うのは、検索窓より上の設定項目。
- 「権限」では、ユーザに与えられたロールに応じて何が可能かを設定するエリアです。管理者だけしかルーム作れないように設定などをしたい場合には、変更を加えます。
- 「ユーザ」では新規にユーザを追加したり、権限変更したり、削除したりするエリアです
- 「インポート」では他のチャットサービスで使っていたデータを取り込む事が可能です。HipchatとSlackに対応しているみたいです。
- 「Assets」では、サービスに表示されるロゴなどを変更する画面です。
- 「E2E Encryption」は通信を暗号化する為のオプションです。
- 「OAuth」では、他のクラウドサービスと連携する為のオプションです。
- 「Slack Bridge」は、Slackに橋渡しをするための設定関係があります。
- 「アカウント」では各ユーザが実行可能な細かいカスタマイズの変更許可について設定があります。
- 「プッシュ通知」ではプッシュ通知をするためのゲートウェイ設定項目があります。
- 「メッセージ」では投稿するメッセージに対する規制やフォーマットなどの設定項目があります。
- 「メール」では、招待メールなどの通知に使用するSMTPサーバ設定やヘッダー、フッター、テンプレ設定があります。
- 「レイアウト」では、RocketChatの見た目のカスタマイズを行うための設定項目があります。
- 「全般」では、REST APIの設定や翻訳などその他の設定項目があります。
Rocket Chatの主な機能
Rocket ChatはSlack風のチャットサービスです。Slackで実装されてるような主要なサービスは持ち合わせております。また、誰が今オンラインなのか?確認することも可能です。管理者設定からこれ以外にも多種多様な機能を追加可能です。
絵文字も簡単に送れる
非常に沢山の絵文字が用意されていますし、IMEで絵文字を送るのも手軽
メンバーリストやメンバー追加もお手軽
ユーザ招待はメールで送られるので、SMTPなどを事前に設定しておく必要があります。
写真や動画を送信可能
初期設定では最大100MBまで送ることが可能。ファイル自体を送れるので、画像や動画以外もアップロード可能。
いいね的なボタン機能
レスの右上にあるちっちゃなボタンから「いいね」的なリアクションを送れます。
プライベートルーム作成
左上のルーム作成ボタンから、作れます。プライベートルームは招待した人以外は参加が出来ない閉じたチャットルームです。
アプリを利用する
Rocket Chatの優れている点はブラウザ上で動くだけでなく、主要な環境用にクライアントアプリが用意されている点です。Android, iOS, デスクトップPC用(Electronで作られてる)やWindows10 UWPアプリと用意されているので、ローカルサーバに接続して使うことが可能です。ここでは、Android版での接続をしてみます。
- Rocket Chatアプリをインストールする
- 起動するとWelcome to Rocket.Chatの画面が出るので、Connect with a Serverをクリック。
- サーバー接続画面が出るので、http:を選び(SSL有効にしてるならばhttps://)、相手のサーバのIPアドレスとポート番号を入れる(例:http://192.168.1.3:3000)
- 次にログイン画面が出るので、登録したメアドとパスワードを入力してログイン。
- ログインが完了すると、チャンネルを作ったり、プロフィール設定、チャットを行う事がすぐに可能です。
図:サーバアドレスを入力する画面
図:Slack風で多機能なチャットが出来ます
図:macOS X クライアントで接続してみた
メンテナンス
不具合対策
最新版のRocket Chatに於いて、ファイルのアップロードが出来ない現象が出ています。理由はGridFSの設定の場合、/tmp/ufsのフォルダを経由してファイルを取り込んでいるのですが、これが存在しません・・・また、/tmpディレクトリというのは、OS起動時にクリーンする場所と決められているので、通常は一時ファイル以外は置いていけない場所です。Ubuntu 18.04で発生を確認しています。
ということで、シェルスクリプトなどに以下のコマンドを追加して、起動時に読み込ませるか?gnome-session-properties。これは、Ubuntuが起動後に自動的に起動するアプリケーションを登録しておく為のもので、systemdのような仕組みというより、Windowsのスタートアップフォルダみたいなものです。ここで以下のように登録しておきます。
1 2 3 |
#!/bin/sh mkdir /tmp/ufs chmod 777 /tmp/ufs |
日本語ルーム作成可能にする
デフォルトの設定では英語のルームしか作れません。そこで以下の変更を施して、日本語のルームを作成できるようにします。
- 管理に入る
- 左サイドバー一番下の「全般」をクリック
- UTF8をクリック
- UTF8形式名の検証パターンには[ぁ-んァ-ヶーa-zA-Za-zA-Z0-9一-龠-0-9-、。_.]+を入れる
- 変更を保存をクリックして完了。
図:面倒な設定ですね・・・
デフォルトアバターの設定をオフにする
デフォルトの設定だとアバターとしてGravatorを取りに行こうとしますが、社内運用等では全く必要ないので、オフにしておきます。
- 管理設定に入ります。
- アカウントに入ります。
- アバターの項目にある「デフォルトのアバターを設定」を「いいえ」に設定
- 変更を保存ボタンをクリック。
図:アバター設定はオフにしておく
アップロードした画像がぼやける
localhostでテストしていて忘れがちなのですが、その状態のまま本番で固定IPをセットして運用するとファイルがアップロードできなかったり、できても画像がぼやけた状態のまま、またアップロードしたファイルがダウンロードができないなどの現象が起きます。必ず本番環境でリリースする時には、以下の設定を見直しましょう。
- rocketchatの管理設定に入ります。
- 左サイドバーの一番下の「全般」の設定に入ります。
- 一番上の「サイトURL」が、localhostのままになっているので、本来のURLを入れてあげる(固定IPとポート番号など)
- 変更を保存ボタンをクリックする
図:地味に忘れがちな項目です
ファイアウォール関係の設定
- snapでのインストールはサーバ環境自体がメジャーリリース時に自動アップデートされる仕組みです。
- 自動でServerが起動しない場合には、sudo systemctl start snap.rocketchat-server.rocketchat-server.serviceで手動で起動します。
- ファイアウォール設定時には、以下のコマンドでPort3000番を開けるようにする
1 2 3 |
firewall-cmd --add-port=3000/tcp --zone=public --permanent firewall-cmd --reload firewall-cmd --list-all |
- 自動起動設定ファイルは、/usr/lib/systemd/system/rocketchat.serviceに記述されています。
- サービスで自動起動設定をする場合は、systemctl enable rocketchat.serviceで行う
- Rocket Chat自体は、Githubで公開されています。
デフォルトポートを変更する
snapでインストールしたRocketChatのデフォルトポートを変更するには、公式ドキュメントによると以下の手順を踏みます。
- /var/snap/rocketchat-server/current/に、Caddyfileという設定ファイルを作成する
- 以下の設定を書き込む。
- sudo systemctl restart snap.rocketchat-server.rocketchat-caddyにて再起動
- sudo systemctl status snap.rocketchat-server.rocketchat-caddyにて再起動を確認し、ポート指定でアクセスする
- ポートの稼働状況をnetstat -plnatu | grep :80で確認
1 2 3 4 5 |
http://:8080 proxy / localhost:3000 { websocket transparent } |
上記の設定で、localhostの3000ポートを8080ポートに変更しています。
バックアップ
Rocket Chatのバックアップについてですが、コマンドラインから可能なので、cronと合わせて定期的に外部HDDなどに退避させておくと良いでしょう。
- バックアップをする時は、sudo snap run rocketchat-server.backupdbを実行
- リストアする時は、sudo snap run rocketchat-server.restoredb --noIndexRestoreを実行
- アップロードしてるファイルは、データベースに格納された形で/var/snap/rocketchat-server/common/に保存されていますので、tar cf /tmp/backup/rocket.tarなどをcronに登録しておくと良いでしょう。
- JSON形式だけでなく、BSON形式になってるものもあるので、mongoDB付属のbsondumpを使ってBSON形式からJSON形式に変換すると二次利用が可能になります。
図:アップロードされたファイルの在り処
社内で使うと接続が途切れる場合
小さな企業内の場合、せいぜいルーターが1個ある程度の環境なので、普通にサーバを立てれば普通に運用が可能だと思いますが、ある程度の組織の場合、途中に存在するルータ、スイッチその他いろいろなものが入っています。ネットワークの設計上早めにTCPのコネクションを解除するような設定が入っていると、立てたRocketChat Serverに他の方が接続できなくなったり、しにくくなったりすることがあります。
そこで、OS側に定期的に生存している旨のパケットを送る設定がありますが、これを少し変更しておくと接続を維持できるようになります。もちろん、OS自体が勝手にスリープしてしまったり、サスペンドしないように設定しておくようにしましょう。今回はUbuntu Linuxをベースに記述します。これらの作業はターミナルとテキストエディタで行います。
logind.confでサスペンドをオフ
1 2 |
//geditでlogind.confを編集 sudo gedit /etc/systemd/logind.conf |
geditが起動したら、以下の項目を新規に追記
1 |
HandleLidSwitch=ignore |
追記したら再起動すればサスペンドしないようになります。
InterfacesにDNS設定
1 2 |
//geditでlogind.confを編集 sudo gedit /etc/network/interfaces |
geditが起動したら以下の項目を新規に追記。すでにあるdns-nameserversはコメントアウト。DNSは社内にあるならそれを指定。
1 |
dns-nameservers 8.8.8.8 |
追記したら再起動するだけです。
nsswitch.confでhostsの設定
1 2 |
//geditでnsswitch.confを編集 sudo gedit /etc/nsswitch.conf |
geditが起動したら以下の項目に編集しなおす。
1 |
hosts: files dns |
追記したら再起動するだけです。
resolv.conf関係にDNSを設定
1 2 |
//geditで編集 sudo gedit /etc/resolvconf/resolv.conf.d/base |
geditが起動したら、以下の項目を追記する
1 |
nameserver 8.8.8.8 |
さらに以下のコマンドで編集を行う
1 2 |
sudo resolvconf -u sudo gedit /etc/resolv.conf |
起動したら既存のdns-nameserversをコメントアウトして、以下の項目を追記
1 |
nameserver 8.8.8.8 |
追記したら再起動するだけです。
sysctl.confでkeepaliveの設定
最後に一番重要な設定。キープアライブの設定とIPv6の設定を行います。UbuntuはIPv6の設定をオフにしておきます。
1 2 |
//geditでsysctl.confを編集する sudo gedit /etc/sysctl.conf |
geditが起動したら以下の項目を追記する
1 2 3 4 5 6 7 8 |
#IPv6の設定を無効にする net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 #キープアライブの設定 net.ipv4.tcp_keepalive_time = 10 net.ipv4.tcp_keepalive_probes = 2 net.ipv4.tcp_keepalive_intvl = 3 |
追記したら以下のコマンドで設定を反映する。sysctl -a | grep keepalive_timeは保存した設定を確認するコマンドです。
1 2 |
sudo sysctl -p sysctl -a | grep keepalive_time |
これで即時にキープアライブとIPv6の設定が反映されます。
仮想環境で構築した場合
発言内容を取得する
REST APIを使用する
Rocket Chatにも様々なREST APIが装備されています。また、β版且つ未公開となってるRealtime APIを用いると、発言内容などを取得出来るようです。メッセージを送ったり、ルームを作ったり様々なAPIが用意されているので、これらを元に自前のアプリケーションに組み込む事が可能です。メッセージ部分に関する取り込みはこちらを参照。
OAuth2.0認証周りはこちらにドキュメントがあります。いずれGoogle Apps Scriptで接続するための仕組みを作ってみたいと思います。
Excelで取り出す
Rocket ChatはMongoDBというNoSQLなデータベースを採用しています。そのままではJSONオブジェクトなので、JavaScriptとは相性が良さそうです。しかし、VBAから扱うには、VBA-JSONなどのライブラリを使って、JSONをパースする仕組みが必要になります。
前項でバックアップを実行して取得したバックアップデータからメッセージをExcelで取り出したいケースもあるかと思います。以下の手順で取り出すことが可能です。まずは、BSONをJSONに変換します。この変換プログラムであるbsondumpですが、64bitでないと動きません・・・
- バックアップファイルであるtar.gzファイルを解凍する
- mongodbよりzip形式のファイル群をダウンロードして解凍する(lastest.zipという名のファイル)
- 解凍したファイル内にbsondumpという実行ファイルがあるのでみつける。
- bsondumpと同じフォルダに1.で解凍した中身にある「rocketchat_message.bson」をコピーする
- 以下のコマンドラインでBSONをJSONに変換する
1 2 |
//BSONをJSONに変換する bsondump.exe rocketchat_message.bson > message.json |
そして、変換したJSONはVBA-JSONなどでプログラムから解析して取得するのも良いのですが、以下の手法でExcelに取り込むことが可能です。
- Excel2016ではPowerQueryが標準装備になりましたが、ソレ以前のExcelではPowerQueryを別途インストールが必要です。
- Excel2013の場合、PowerQueryタブ内の「Webから」をクリック
- パスはmessage.jsonのある場所のフルパスを入れてとりあえず、OKを実行
- 取り込みに失敗するので、編集をクリック。
- 詳細をクリックして、元のファイルの文字コードはUTF-8を指定する。もし、BOMなしのUTF8ファイルならば、予めBOM有りのUTF8じゃないと取り込めないです。
- OKを押すと開始
- テーブルに変換をクリックする
- 変換されたのちに、Nameの列のフィルタっぽいのをクリックする
- msgを選ぶとメッセージの部分がvalue列で取り出せます。
- 閉じて読み込むをクリックするとExcelのシートにテーブルとして取り込めます。
- ただし、時々、余計な文字があるといわれ取り込めないケースがあります。その時は素直に、VBAでプログラムを組みましょう。
図:PowerQueryを使って読み込む
図:Query編集画面
JSONファイルを分解するExcelプログラム
今回とある機会で、前項のBSON=>JSONへ変換したデータの塊を、Excelのシートに綺麗に変換する為のプログラムを作成しました。JSONファイルをこのVBAプログラムで開くと、メッセージID、部屋ID、メッセージ、添付ファイル名を取り出して一覧にしてくれます。
コード自体は非常にシンプルです。メンションなどいろいろ考慮すべき要素はありますが、今回は純粋にユーザのメッセージを塊から取り出すだけです。リボンにボタンが1個あるだけなので、簡単仕様です。
図:ボタン1個だけのシンプル設計です
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
'Rocket ChatのJSONファイルを変換するメインルーチン Public Function rocketjson() '変数の宣言 Dim dlg As Object, boolResult As Boolean Dim jsonfile As String 'オブジェクト変数にFileDialogオブジェクトを代入 Set dlg = Application.FileDialog(msoFileDialogOpen) 'JSONをパースする用の変数 Dim doc Dim JsonObject As Object Dim kinoko As Variant Dim dlength As Variant Dim i As Variant Dim fileflg As Boolean fileflg = False 'レコード要素用変数 Dim rid As Variant Dim mid As Variant Dim msgstr As Variant Dim attachman As Variant Dim atdata 'FileDialogオブジェクトの各種プロパティを設定 With dlg .AllowMultiSelect = False .Filters.Clear .Filters.Add "解析対象のJSONファイル", "*.json" .FilterIndex = 3 .Title = "変換されたRocketChatデータ" .ButtonName = "変換する" End With 'ファイルを開くダイアログを開く boolResult = dlg.Show If boolResult Then 'インポートルーチンに渡す jsonfile = dlg.SelectedItems(1) Else '[キャンセル]ボタンが押された場合の処理 MsgBox "シートデータの取り込みはキャンセルされました。" Exit Function End If 'ワークシートのデータをクリアする Dim lastrow As Variant lastrow = Worksheets("rocket").UsedRange.Rows.Count If lastrow = 1 Then 'タイトル行だけなので何もしない Else '2行目移行を削除する Worksheets("rocket").Range("A2:D" & lastrow).Clear End If 'バッファにJSONファイルを読み込む Dim buf As String With CreateObject("ADODB.Stream") .Charset = "UTF-8" .Open .LoadFromFile jsonfile buf = .ReadText .Close End With '連想配列にし、LF改行コードをカンマに変換して、CRLF改行コードを追加 buf = "{'kinoko':[" & buf & "]}" buf = Replace(buf, vbLf, vbCrLf) buf = Replace(buf, vbCrLf, "," & vbCrLf) 'JSON受信用 'HTMLDocumentを取得 Set doc = CreateObject("HtmlFile") 'scriptタグを追加 doc.Write "<script>document.JsonParse=function (s) {return eval('(' + s + ')');}</script>" 'JSONをパースする Set JsonObject = doc.JsonParse(buf) 'kinoko部分の連想配列を取得する Set o = CallByName(JsonObject, "kinoko", VbGet) 'データの件数を調べる dlength = CallByName(o, "length", VbGet) 'ループで値を取り出す For i = 0 To dlength - 1 'fileflg初期化 fileflg = False '個別レコードを取得する Set o2 = CallByName(o, i, VbGet) 'file要素があるかどうかチェック fileflg = keycheck("file", buf, i + 1) 'レコード要素を取得する rid = CallByName(o2, "rid", VbGet) mid = CallByName(o2, "_id", VbGet) msgstr = CallByName(o2, "msg", VbGet) 'msgの改行コードを変換 msgstr = Replace(msgstr, "\n", vbVCrLf) 'fileflgがtrueならば添付ファイル名を取得する If fileflg = True Then Set atdata = CallByName(o2, "file", VbGet) attachman = CallByName(atdata, "name", VbGet) Debug.Print attachman Else attachman = "" End If 'シートに書き込む With Worksheets("rocket") .Cells(i + 2, 1).Value = mid .Cells(i + 2, 2).Value = rid .Cells(i + 2, 3).Value = msgstr .Cells(i + 2, 4).Value = attachman End With Next i '終了処理 MsgBox "データの変換が完了しました。" End Function '指定のキーが要素の中にあるかどうかをチェック Public Function keycheck(keyname As String, json As Variant, keynum As Variant) As Boolean Dim Parse As Object Dim Key As Variant Dim keyflg As Boolean keyflg = False Set Parse = JsonConverter.ParseJson(json) '指定のレコードの要素数を調べる 'Debug.Print Parse("kinoko")(keynum).Count For Each Key In Parse("kinoko")(keynum) If Key = keyname Then keyflg = True Exit For End If Next keycheck = keyflg End Function |
関連リンク
- Rocket.Chat構築でちょっと詰まったところまとめ
- RocketChat(mongodb)のバックアップ・リストア [Linux]
- ラズパイwebサーバをhttpsに対応させた
- firefoxで PR_END_OF_FILE_ERROR エラーが発生した話
- Apacheでオレオレ証明書を発行して自分で自分を証明したい(備忘録)
- macのApacheにSSLを導入した
- ubuntu の apache2 には httpd.conf は無い
- Can not install Rocket.Chat #30045
- DockerでMongoDB 6.x実行時「requires a CPU with AVX support」と出た際の対処
- AWSにRocketChatをインストールする手順
- 独自のSlack風チャット環境を構築できる「Rocket.Chat」や「Mattermost」
- Slack の代替オンプレ型チャット Rocket.Chat を業務利用している時に知っておくと捗ること
- MongoDBのImport・Exportコマンドを試す
- MongoDBのドキュメント指向NoSQLデータをCData JDBC Driver経由でYellowfinを使い可視化してみる
- MongoDBのImport・Exportコマンドを試す
- MongoDBコマンド一覧(自分用メモ)
- 覚えておきたいカーネルパラメータの変更方法
- Linuxカーネルのチューニング
- 【図解】TCP Keep-Alive/http Keep-Aliveの仕組みと違い ~Client/Serverの挙動とメリット,設定~
- JSONファイルをExcelに変換
- BSON形式のファイルをJSONに変換しよう!
- Request - Simplified HTTP client