小規模Mastodonインスタンスを運用するコツ

補足:ドキュメント移行によりリンク変更と、tasksに関しての追記を行いました。

最近は、twitterクローンであり分散型のSNSであるMastodonが勢力を伸ばしてきているところであり、自分もハマりつつあります。

実際に運用してみてわかった、大規模Mastodonインスタンスを運用するコツとしてpixiv.netが運営しているサーバpawoo.netでは、現時点で6万人以上のユーザ数を誇るほどの規模です。

その一方で、サーバ自体はオープンソースのため、誰でも立てることができ、立てたサーバはインスタンスとして他のサーバとつながることが出来ます。

実際に私も2,3日程運用して、おひとりさまで運用しております。その時のコツというレベルでもないですが、
これから構築する人に向けてはまりそうな点などをまとめておきます。

https://mastodon.potproject.net/@potpro

では、大規模に対してここでいう小規模とは何か、というと
・主に使用ユーザは1~100人程度を想定
・気軽に構築するため、公式のDockerを使用して構築
・SSLは無料のもの(Let’s Encrypt)を使用する
・サーバはVPS、月1000円~2000円程度
そして、
・ちょっとくらいのダウンは問題なし、データは出来るだけふっ飛ばさないようにする

とします。

VPSとコストに関して

基本的に小規模で運用している方々を見るに、

さくらVPSの1GB(972円/月)やAmazon EC2(従量課金、無料枠あり)が多いと思います。

私はコスパ重視で、お名前.com VPS メモリ 2GBプラン(1,099円/月、年払い)を使用しています。

メモリ2GBと仮想3コアあれば一人でロードアベレージは通常時0.1以下です。1-10人程度であればメモリ1GB以上の好きなVPSを選べばいいと思います。

自宅で管理したいなら、自宅鯖を構築するのも手ですが、固定IPアドレスの問題や安定稼働(停電で使えなくなるとか)を考えなくてはならないため、

その点ではVPSの方が優れているでしょう。

このレベルでどのくらい運用できるのかはまあやっぱり実際に試してみないとわかりませんが、100ユーザくらいなら多分大丈夫(と思いたい。

この部分に関しては公式ドキュメントのResources-needed.mdが参考になります。まだ3つしか参考がありませんが、多分増えていくと思います。
https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Resources-needed.md

この記事はあくまで小規模が目的のため、ユーザ1000くらいを目指すなら、
脱Docker、PostgreSQLやRedisの別サーバー管理、Sidekiq threadsの増加、nginxのチューニング、ロードバランスなどが必要になってきますので、
その部分は他の誰かが解説してくれることでしょう。

Dockerコンテナの作成と構築

基本的に、公式DocumentのDocker Guideを読んで作成してください。
更新が激しいので、ここでは構築方法は解説しません。
何故なら構築方法が変更され、この記事の情報が古くなる可能性が高いからです。

自分がハマった点は、必ず公開用に立てるのであれば、タグ付きのリリース版を使用してください。
https://github.com/tootsuite/mastodon/releases
単純にgit cloneをしてクローンした最新のmasterブランチはうまく動作しない可能性が高いです。
タグ付きのreleaseブランチは、このようなコマンドでチェックアウトできます。

git clone https://github.com/tootsuite/mastodon.git
cd mastodon
git checkout $(git tag | tail -n 1)

アップデート

アップデートも余計なことはせず、公式ドキュメントのDocker Guide – updatingを見て行ってください。
公式DocumentにあるThings to look out for when upgrading Mastodon(Mastodonをアップデートするときの注意点)に記載されていることも重要なので参考にしましょう。
ミスったらデータ消えたり上手く動かなくなるのでここは慎重に。
https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md#things-to-look-out-for-when-upgrading-mastodon

このアップデート手順通りに行えば、すぐに新しくコンテナが立ち上がることでダウンタイムも数秒で済みますし、
まず失敗することはないと思われます。

しかし、万が一の時を含め、バックアップとデータ永続化は行っておきましょう。

データ永続化

一部のデータをホストOS側にマウントすることで、コンテナを誤って削除してもデータが保持される状態にします。
docker-compose.ymlの最初のコメントアウト部分を外すことで、ホストOS側のディレクトリに保存されます。
左側がホストOSのパスとなっているので、変更すれば好きな部分におけます。

version: '2'
services:

  db:
    restart: always
    image: postgres:alpine
### Uncomment to enable DB persistance
    volumes:
      - ./postgres:/var/lib/postgresql/data

  redis:
    restart: always
    image: redis:alpine
### Uncomment to enable REDIS persistance
    volumes:
      - ./redis:/data
(略)

この作業を忘れたまま本番稼働させてしまった場合は、次で紹介するdocker cpコマンドでバックアップを取り、
バックアップをマウントするディレクトリと同じ場所に置き、アップデートを行ってください。

バックアップ

小規模といえど、データのバックアップは行いたいです。

#データベース
PostgreSQLコンテナ : /var/lib/postgresql/data
#キャッシュデータ
Redisコンテナ : /data
#取得した画像等のデータ
Mastodon-webコンテナ :  /mastodon/public/system
#sidekiqデータ
sidekiqコンテナ :  /mastodon/public/system

この4つが基本的なバックアップ対象のデータです。
一番重要なのはデータベースですが、
現バージョンでは、取得した画像等のデータも一度紛失すると再取得を行ってくれず、
タイムラインに取得済みのアバター画像が何も表示されない悲しい状態に陥ってしまいます。

Dockerの場合、Docker cpコマンドを使用することでDockerコンテナからホストOSにコピーが出来ます。
例として、

docker cp mastodon_db_1:/var/lib/postgresql/data /mastodon_data/postgresql

という形です。
mastodon_dataディレクトリにpostgresqlデータが入っていることが確認できると思います。

その他、構築時に使用した.env.productionファイルも無くした場合は再構築が簡単ではなくなるため、バックアップしておいてください。
無くしてしまった場合は、稼働しているMastodon-webサーバから
docker exec -it mastodon_web_1 env
から取得することは一応可能です。

SSL対応

Mastodonサーバでは、SSLの対応はほぼ必須です。

一応httpでも動作しますが、httpとhttpsは共存できないため、httpsのサーバからリモートフォローすることが出来ない、などの弊害があるようです。

今ではLet’s encryptなどを使用してSSL対応は簡単にできるので、個人でも敷居はかなり下がっていると思います。

公式のProduction Guideでは、nginxをリバースプロキシにして、動作することが推奨されています。
公式のProduction Guideをメインに、SSLの設定は自分の過去の記事あたりにその辺は結構書いているので、よければ参考にしてください。

Centos+nginxでLet’s encrypt(certbot)導入と自動更新まで

証明書は期限が切れると使えなくなり、アクセスしてもエラーが出て正常に使えないため、Let’s Encryptを使う場合は自動更新の設定を行うこともおすすめします。

また、公式ではssl_protocols TLSv1.2;になっているため、ちょっと古いブラウザなどで使用できない可能性もあります。
使うべきではないとされているSSLv3を除いて、広く対応を行いたければ、ssl_protocols TLSv1 TLSv1.1 TLSv1.2;に変更することをお勧めします。

Cronjobs

運用するにつれ、他のインスタンスからデータを持ってきて表示するため、放置しているとデータはどんどん溜まっていきます。
それを解消するため、公式で要らないデータ等を削除できるRakeタスクが用意されています。
※特にmastodon:dailyタスクにはPuSHの購読更新処理が含まれるため、外部インスタンスから自分のトゥートが見えなくなる可能性があります。
自分も更新しなくても大丈夫だと思っていたのですが、mastodon:dailyに関しては必ず1日に1回は動かしてください(多くてもOK)。

https://github.com/tootsuite/mastodon/blob/master/lib/tasks/mastodon.rake

#いらないやつもろもろを消してくれるタスク(日一で動作)
0 3 * * * cd /var/www/mastodon && docker-compose run --rm web rake mastodon:daily
#1週間以上前の画像動画キャッシュを削除(週一で動作)
0 3 * * 1 cd /var/www/mastodon && docker-compose run --rm web rake mastodon:media:remove_remote

自分はこのようにしてcrontabで動作させています。

swapの設定

Mastodonに限らないことですがメモリが少なくなっても賄えるようにswapを設定しましょう。
swapがあれば仮想メモリとして退避することができ、遅くはなりますが少ないメモリでもリソースが確保できます。
Mastodonは1ユーザでもそこそこメモリを食います。最低でも1GB、よくて2GBはほしいところです。

特に上に書いているmastodon:dailyタスクは、動作するだけでかなりのメモリを食います。自分もメモリ不足ギリギリ回避な感じでした。

メモリ1GBの場合は3GB、2GBの場合はswapは2GB確保と合計4GBは確保しておけばととりあえず大丈夫と思います。
(Linuxディストリビューションでコマンドが違ったりします。これはcentos7の参考例です。)

//2GB確保、当然ストレージに2GB空きが無いと作れません
if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

まとめ

Mastodonを個人で運用するメリットとして、
・データを勝手に改ざんされたり削除される心配はない
・逆に自分の好きなようにデータを弄れる
・おひとり様サーバならサーバ負担に悩まされることもない(htmlのレスポンスは100ms以下!)
・SNSを運用してるって、なんかカッコいいじゃん。自分だけの空間にするもよし、鯖管で皆を導くのもよし。

という点があり、自分もかなり満足して使っています。

私は個人的にMastodonで個人鯖を立てる人を応援しております。もっとたくさん増えて、個人鯖連合を作ろう。

MySQL WorkBenchでデータベースのモデルを作る

potproject.net Advent Calendar 201615日目の記事です。

今回はかなり珍しいけれど、データベースの話です。


うまいことE-R図が書ける書けるソフトウェアを探していて、
普段MySQLサーバーを操作するときに使用していたMySQL Workbenchに、
モデル作成機能があるとわかり、使ってみたらかなり使いやすく便利だったのでブログでの紹介です。

MySQL Workbenchは、MySQLに関する統合管理ソフトウェアです。Windows/Mac/Linuxのマルチプラットフォームかつ、無償です。
MySQLの開発元であるOracleが開発しています。

大体はデータベースを管理していろいろ情報を見たり、挿入したり削除したりがGUIで出来るのでそれだけでかなり便利なんですが、
モデル作成機能もついてるようです。
バージョンは6.3.8です。

ダイアグラムを立ち上げる

File -> New Model で、新しいモデルを作ります。
その後、 Add Diagram をクリックするともうE-R図の作成画面が出てきます。

基本的に、書くだけだったらそんなに難しくないです。左側のタブの真ん中あたりにあるのがテーブル追加ボタン。これでテーブルを追加。
左側にあるのはテンプレートです。ここをクリックすることで用意されたテンプレートを使用できます。
今回は一から作らず、このテンプレートを使って簡単にいきます。
userテーブル、categoryテーブルが出来ました。

テーブルを編集する

テーブルはダブルクリックすることで編集が出来ます。
テンプレートはカラムのデータ型が設定されてないようなので、編集して設定します。
主キーやデータ型などを付け加えるとこんな感じです。

関係(リレーション)を設定

E-R図なので、外部キーなどの関係を設定します。
編集状態で、 Foreign keys を選び、外部キーの名前、参照するテーブル、参照するカラムなどを設定。
今回はuser.usernameを参照するようにcategory.nameに外部キー制約を設定します。

このような感じになります。また、自動的に指定された表記法で関係が表されます。
初期状態だとIE (Information Engineering)記法となっています。自分は一番なじみのあるUML記法で表示するため、
Model -> Relationship Notation で、UMLを指定。記法が変えられるというのもかなり嬉しいポイントじゃないでしょうか。

SQLで出力

モデル機能も優秀ですが、MySQL Workbenchは作ったモデルをSQLで出力することが出来る機能があり、これが本当に使えます。
E-R図を見ながらSQLを組み立てていく時間が削減されるので、すごく便利。

File -> Export -> Forward Engineer SQL CREATE Script を選択。
途中何を出力するか聞かれるので、 Export MySQL Table Objects にチェック。
他にもViewやroleまで出力できるようです。すげー。

CREATE TABLE IF NOT EXISTS `mydb`.`user` (
  `username` VARCHAR(20) NOT NULL,
  `email` VARCHAR(255) NULL,
  `password` CHAR(64) NOT NULL,
  `create_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`username`));

CREATE TABLE IF NOT EXISTS `mydb`.`category` (
  `category_id` INT NOT NULL,
  `name` VARCHAR(20) NOT NULL,
  PRIMARY KEY (`category_id`),
  INDEX `name_idx` (`name` ASC),
  CONSTRAINT `name`
    FOREIGN KEY (`name`)
    REFERENCES `mydb`.`user` (`username`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);

組みあがったSQL文がこれ。SQL文全く分からなくてもいけるわけですよ。
自分はこれくらいならSQLを書けないことはないですが、外部キーやインデックスなどまで含めて書くとなると、ちょっときつい。というかめんどくさい。
後はこれをSQLにインポートで完了ですよ。

データベースメインのひとでもかなり使えるのでは?自分は多すぎて全容把握できてないです。
欠点は、MySQL Workbenchがすぐクラッシュするくらいですね。本当に多いのよね。自動保存機能はあるらしいけれど。
まあ、なんでもそうですが、こういったソフトウェアは定期的に保存っすなあ。