mastodonの調査(特徴・起動・APIアクセスなど)メモ

  • 12
    Like
  • 0
    Comment

参考にしたURL

参考の自分用まとめ

特徴

  • GNUソーシャルのオープンソース
  • Ruby on Rails・Node.js・sidekiq・PostgreSQL・Redis・Nginx
  • WebSocketによるリアルタイム更新UIが作れる
  • OAuth2.0認証でREST APIが利用できる
  • Docker composeでデプロイできる

Docker composeでデプロイできる

docker-compose.ymlの中身

  • db
  • redis
  • web
  • streaming
  • sidekiq

db

  • postgreSQLの設定(データボリュームとして残す場合はコメントアウトが必要)
  • ダッシュボードは管理用Webインターフェースから使える
  • 接続先をAWS RDSにすれば外だしできる

redis

  • redisの設定(データボリュームとして残す場合はコメントアウトが必要)
  • 接続先をAWS ElasticCacheにすれば外だしできる

web

  • railsの設定など
  • データボリュームとして、アセットとシステムを利用する

streaming

sidekiq

デプロイ手順(環境: centos7)

  • docker composeインストール
  • mastodonダウンロード
  • ビルド&構築
  • 起動

docker composeインストール

# dockerインストール
$ curl -sSL https://get.docker.com/ | sh
$ docker --version
Docker version 17.04.0-ce, build 4845c56
$ sudo usermod -aG docker ${user}
# 一度ログアウトする
#exit

# docker composeインストール
# https://github.com/docker/compose/releases/
$ curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose

mastodonダウンロード

$ git clone https://github.com/tootsuite/mastodon && cd mastodon

ビルド&構築

$ docker-compose build

# secretを3つ生成しておく
$ docker-compose run --rm web rake secret
secret1
$ docker-compose run --rm web rake secret
secret2
$ docker-compose run --rm web rake secret
secret3

# `.env.production` の設定
$ cp .env.production.sample .env.production
$ vi .env.production
  # とりま消す
  #LOCAL_HTTPS=true
  LOCAL_HTTPS=false

  # 生成したsecretを張り付ける
  PAPERCLIP_SECRET=${secret1}
  SECRET_KEY_BASE=${secret2}
  OTP_SECRET=${secret3}

  DEFAULT_LOCALE=ja

# DB初期化
$ docker-compose run --rm web rails db:migrate

# Rake アセットのプリコンパイル
$ docker-compose run --rm web rails assets:precompile

起動

$ docker-compose up
# もしくはデーモン化
# docker-compose up -d

アクセス

  • http://localhost:3000/
  • とりあえずアクセスしたいだけなので、サインアップ後、以下コマンドで強制メール認証(SMTPサーバーの設定をしてれば不要)
  • $ docker-compose run --rm web rails mastodon:confirm_email USER_EMAIL=${サインアップにつかったメールアドレス}

APIをたたく

  • トークンを取り出すの面倒なので、jqを使う
  • アプリケーション作成
  • 書き込み

トークンを取り出すの面倒なので、jqを使う

$ sudo curl -o /usr/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && sudo chmod +x /usr/local/bin/jq

アプリケーション作成

# サインアップしたアカウント情報
$ YOUR_EMAIL=${サインアップにつかったメールアドレス}
$ YOUR_PASSWORD=${サインアップにつかったパスワード}

$ APPS=`curl -X POST 'http://localhost:3000/api/v1/apps' --data 'client_name=MyApp&redirect_uris=urn:ietf:wg:oauth:2.0:oob&scopes=write'`
$ echo $APPS | jq .
{
  "id": 11,
  "redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
  "client_id": "fcd3b1b292331a4d0d1f2dd60bf4d0b7e3ea0e54ec46d6485ebcc85471c62c08",
  "client_secret": "7173722c306f29a73731c868687698f1b855bc9482c2a6f01f5a1da7c55043d0"
}

$ CLIENT_ID=`echo $APPS | jq -r .client_id`
$ CLIENT_SECRET=`echo $APPS | jq -r .client_secret`

$ TOKEN=`curl -X POST -d "scope=write&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&grant_type=password&username=$YOUR_EMAIL&password=$YOUR_PASSWORD" http://localhost:3000/oauth/token`
$ echo $TOKEN | jq .
{
  "access_token":"f2fd59be80f63448129831dc62db75a0d6d2cdd7300ad76ad32d90e61d582f90",
  "token_type":"bearer",
  "scope":"write",
  "created_at":1492277130
}
ACCESS_TOKEN=`echo $TOKEN | jq -r .access_token`

書き込み

$ curl -X POST --header "Authorization: Bearer $ACCESS_TOKEN" 'http://localhost:3000/api/v1/statuses' --data 'status=いえーい'
{
  "id":30,
  "created_at":"2017-04-15T17:37:31.795Z",
  "in_reply_to_id":null,
  "in_reply_to_account_id":null,
  "sensitive":null,
  "spoiler_text":"",
  "visibility":"public",
  "application":{
    "name":"MyApp",
    "website":null
  },
  "account":{
    "id":1,
    "username":"jtodo",
    "acct":"jtodo",
    "display_name":"",
    "locked":false,
    "created_at":"2017-04-15T15:52:09.556Z",
    "followers_count":0,
    "following_count":0,
    "statuses_count":30,
    "note":"",
    "url":"http://example.com/@jtodo",
    "avatar":"http://localhost:3000/avatars/original/missing.png",
    "avatar_static":"http://localhost:3000/avatars/original/missing.png",
    "header":"http://localhost:3000/headers/original/missing.png",
    "header_static":"http://localhost:3000/headers/original/missing.png"
  },
  "media_attachments":[],
  "mentions":[],
  "tags":[],
  "uri":"tag:example.com,2017-04-15:objectId=30:objectType=Status",
  "content":"<p>いえーい</p>",
  "url":"http://example.com/@jtodo/30",
  "reblogs_count":0,
  "favourites_count":0,
  "reblog":null,
  "favourited":false,
  "reblogged":false
}

siegeでたたきまくってみる

  • 結果
  • やったこと

結果

やったこと

$ cd /tmp
$ echo "http://localhost:3000/api/v1/statuses POST status=いっぱい!!" > request.txt
$ siege --header="Authorization: Bearer $ACCESS_TOKEN" -c 10 -r 10000 -f request.txt
    HTTP/1.1 200     0.19 secs:     468 bytes ==> POST http://localhost:3000/api/v1/statuses
    ...
    HTTP/1.1 429     0.01 secs:      21 bytes ==> POST http://localhost:3000/api/v1/statuses

$ curl -X POST --header "Authorization: Bearer $ACCESS_TOKEN" 'http://localhost:3000/api/v1/statuses' --data 'status=いえーい'
{"error":"Throttled"}

その他

タスク

定期(cronジョブ推奨の模様?)

  • rake mastodon:feeds:clear 最近サインインしてないユーザーのタイムラインを削除する。次回ユーザーが、homeやmentionsのタイムラインを取得する際に再構築される
  • rake mastodon:media:clear 使われていない(?)アップロードの削除
  • rake mastodon:push:refresh Push通知のリフレッシュ。期限切れユーザー対策?リモートユーザーのハブに応じた間隔で実行すべき?なぞ

トラブルシューティング用

  • rake mastodon:feeds:clear_all すべてのタイムラインを削除
  • rake mastodon:push:clear フォロワーを持たないリモートユーザーのPush通知登録を解除

運営ガイド