> For the complete documentation index, see [llms.txt](https://np-complete.gitbook.io/mastodon/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://np-complete.gitbook.io/mastodon/running-mastodon.md).

# マストドンを運用する

マストドンは主に3つの機能から成り立っています。

* Webアプリケーションサーバ (Rails)
* WebSocketストリームサーバ (Node.js)
* 非同期処理ワーカー (Sidekiq)

マストドンを実行するには、これらのプロセスを動かさなければなりません。

また、ミドルウェアとして

* PostgreSQL
* Redis

を利用します。

## 手っ取り早くdockerで

簡単に実行するならdockerが一番よいでしょう。 また、**docker-compose.yml**を読めば個別に起動するときの参考にもなります。

```
$ cp .env.production.sample .env.production
```

いくつかある `*SECRET*` という名前の環境変数に、 `rake secret` で作った文字列を入れておきます。 データベースを永続化するには `db: volumes` のコメントアウトを外しておきましょう。

```
$ docker-compose run --rm web rake db:migrate
$ docker-compose run --rm web rake assets:compile
```

で準備をしたら、

```
$ docker-compose up
```

で起動します。 PostgreSQLやRedisも同時に起動されます。

これで <http://localhost:3000> でマストドンにアクセスできます。 あとはフロントにNginxなどを立ててリバースプロキシをやらせればいいでしょう。 一般的なRailsアプリの実行方法と一緒です。

ただし、dockerでは本番運用にはほとんど通用しません。

## スケールする構成

大規模で運用する場合はdockerを諦めたほうがいいでしょう。 まず、PostgreSQLとRedisは一般的なスケールできる仕組みを使います。 RDSやElastiCacheを利用したり、自前でクラスタリングします。 ここで気をつけるのは、**Railsの世界にリードレプリカの概念はない**ということです。 何も考えずにRDSを使うことを推奨します。

マストドンはSPAなので、Railsの負荷はほぼ**APIリクエスト数**に依存します。 ひとつひとつの処理はシンプルなのであまり負荷は高くなく、レスポンスタイムも高速です。 一般的なRailsをスケールさせる方法がそのまま使えます。

StreamはWebSocketなのでクライアントは接続を維持します。 タイムラインの種類ごとに接続するので、**ユーザ数 \* 4〜5本**くらいのクライアントが繋ぎっぱなしになります。 そういうのはnode.jsがめちゃくちゃ得意なので特に気にしなくていいでしょう。

問題はSidekiqです。 マストドンの重要な処理はほとんどワーカーで行われており、負荷もほとんどワーカーに集中します。 さらに、ワーカーの負荷はユーザの状況によって変化し、予想しづらいという難点があります。 例えば、あるユーザがトゥートすると、フォロワーのホームタイムラインにそのトゥートを送信します。 その場合、フォロワーの数だけ「トゥートを送信する」というジョブが登録されます。 ジョブはその性質から、またデータベースから `find` しなければならないので、結構重い処理です。 人気のあるユーザがトゥートすると、数千回 `Status.find(id)` が走るということになります。 これは結構大変なコストです。 ただ、データベースさえ詰まらなければプロセス数を増やしたぶんだけ綺麗にスケールしてくれます。 今のところ、**CPUのコア数**と同じ数のプロセスを立ち上げ、それぞれのプロセスでは `concurrency` の設定を **40スレッド** にしておくと、最良なパフォーマンスが得られるとされています。

とにかくSidekiqをどれだけ用意するか、そしてデータベースはそのコネクション数に耐えられるか、が肝になります。 RailsやNodeは1台あたり数コネクションしか消費しませんが、Sidekiqは大量のコネクションを消費します。 例えば8コアCPUのマシンをSidekiqに使うと、1台あたり320コネクションも使うことになります。 実際に運用してみると、おそらく **ジョブの消化が間に合わない** という問題に当たります。 **ジョブの消化に十分なワーカー数** を確保し、そこから **必要なデータベースインスタンスの性能** を導くことになると思います。
