Help us understand the problem. What is going on with this article?

Mastodon 保守メモ

備忘録として残しておきます

Mastodon専用ユーザにて、Mastodonのインストールディレクトリにて操作することを前提にしています。
(非Dockerならliveディレクトリ)

参考資料

公式ドキュメント

Mastodon documentation

tootctl

v2.5.0より、tootctlというコマンドラインツールが追加された。
Rakeタスクでの引数指定方法等への不満から誕生したものである。

既存Rakeタスクは、初期セットアップに使う一部のものを除き、tootctlに置き換えられた。

tootctl周りについては、肥大化してしまったため勝手ながら別投稿に移動しました。

勝手 Mastodon tootctl リファレンス

なお、公式ドキュメントもあります。
Using the admin CLI - Mastodon documentation

Rakeタスク

https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/List-of-Rake-tasks.md

あるいは

# すべてのRakeタスクを表示
$ RAILS_ENV=production bundle exec rails -T

# Namespace "mastodon" のタスクのみ表示
$ RAILS_ENV=production bundle exec rails -T mastodon

で、定義されているタスクが一覧(+簡単な説明文)表示される。
v2.6.1で確認したところでは、殆どの管理タスクがtootctlに移行されている。

タスク一覧の出力例
mastodon_tasks(v2.6.1)
$ RAILS_ENV=production bundle exec rails -T mastodon
rails mastodon:setup                       # Configure the instance for production use
rails mastodon:stats                       # Report code statistics (KLOCs, etc)
rails mastodon:webpush:generate_vapid_key  # Generate VAPID key

Rakeタスクの実体

https://github.com/tootsuite/mastodon/tree/master/lib/tasks

tootctlやrakeタスクを介さずにいろいろやる(irb)

irb(Interactive Ruby Shell)を用いれば、Mastodonの環境でRubyのコードを直接実行できる。
いろいろできるということは、それなりに危険を伴うのでオススメはできない。

Mastodon用irbコードメモ

irbの起動のしかた

非Docker

$ pwd
/home/mastodon/live
$ RAILS_ENV=production bundle exec rails console
irb(main):001:0>

Docker

$ docker-compose run --rm web rails console
irb(main):001:0>

※Docker環境がないため未検証

インストール・アップデート・バックアップ・移行に関する情報

どれも古くなりつつある。

インストール

Installing from source - Mastodon documentation
公式ドキュメント。Ubuntuにインストールするならこの手順に従う。

Mastodon構築手順・非Docker版
非公式・手前味噌ドキュメント。RHEL系なら参考になるかも。

アップデート

Upgrading to a new release - Mastodon documentation
公式ドキュメント。非Docker。

Mastodonアップデート手順(基本)・非Docker版
非公式・手前味噌ドキュメント。内容としては重複している。

バックアップ

Backing up your server - Mastodon documentation
公式ドキュメント。

移行

Migrating to a new machine - Mastodon documentation
公式ドキュメント。非Docker。

Mastodonサーバ移行手順(非Docker)
非公式・手前味噌ドキュメント。内容としてはおおむね重複している。

サービス保守

不具合かな?と思ったときの切り分け例

まず落ち着いて!

  • Lv 1: 異常に重たいけど機能している
    何かしらのバックグラウンドタスクでリソースを圧迫している可能性がある。
    コンソール接続できる場合は、topコマンド等で何がリソースを消費しているか調べる。
    ※一般的に、アクセス集中やフォローリストインポート、アーカイブ生成などで一時的に重くなることがある。

  • Lv 2: 象バンバン(HTTP 503)が出た
    Mastodon関連サービスでエラーが発生している可能性が高い。
    コンソール接続できる場合は、Mastodon関連サービスが起動しているか、あるいは後述する「Mastodonサービスのログを見る」で何が原因か突き止める。

  • Lv 3: そもそもつながらない。ブラウザにエラーが出る。
    証明書関連のエラーが出た(信頼できないサーバです、など)場合は、証明書の有効期限をチェックする。
    接続タイムアウトの場合は、ネットワークは正常か・サーバが起動しているか・Nginxサービスが起動しているか・ファイアウォール設定は正しいか・DNS設定が正しいか、などを順番にチェックする。

  • 番外編: アップデート後に不具合が出た
    ログを確認するとともに、アップデート手順に抜けがないかチェックする。
    リリースによっては、追加の作業が必要な場合もあるため。リリースノートを再度チェックする。

ありがちなところだと

 ・ データベースマイグレーション実行忘れ … システムが動作不良を起こす。mastodon-web のログに「column not found」などのエラーが出る。
 ・ アセットコンパイル忘れ … 画面の動きがおかしくなったり、画像がリンク切れになったりする。必要に応じてclobberをしてからprecompileを実施する。
 ・ 一時ディレクトリアクセス権の問題 … 画像のアップロードができなくなり、画面上に500エラーが出る。nginxのエラーログに「access denied」といったエラーが出る。エラーが出ているディレクトリの所有者を nginx.confで指定したユーザーにする。(グループは触らなくてよい)

Mastodonサービスのログを見たいとき

$ sudo journalctl -r -u mastodon-web
$ sudo journalctl -r -u mastodon-sidekiq
$ sudo journalctl -r -u mastodon-streaming

-r で新しいものを先に表示
-u で表示するモジュールを指定
-f も付ければ、継続監視が可能(tailみたいに)

Nginxのログを見たいとき

$ sudo tail /var/log/nginx/access.log
$ sudo tail /var/log/nginx/error.log

継続して監視したい時は、 tail -f が便利

よく使うやつのメモ:

連合からの投稿の受け口(inbox)を除外して継続監視
$ sudo tail -f /var/log/nginx/access.log | grep -v " /inbox "
Mastodonからのアクセスを除外して継続監視
$ sudo tail -f /var/log/nginx/access.log | grep -v " (Mastodon/"
特定のHTTPステータスコードを返しているものを探す
$ sudo cat /var/log/nginx/access.log | grep " 404 "

Ruby Gem を再インストールしたい時

稀に壊れたりすることがあるようです。。。

$ bundle pristine

thanks @theoria !

あるいは

$ bundle exec gem uninstall -aIx
$ bundle install

引数 -aIx で、「全てを確認無しでアンインストール」
その後、通常通りインストールする

bundler 経由で操作しないと、グローバル環境のGemに作用する?らしいので注意。

アセットをゼロから作り直したいとき

$ RAILS_ENV=production bundle exec rails assets:clobber
$ RAILS_ENV=production bundle exec rails assets:precompile

clobber で webpackの出力を全消しできる。
長いことclobberをしていないと、古いアセットが残りっぱなしになることがある(らしい)ので、たまにやった方がいいかもしれない。

tootctlやrakeタスクをcronで動かしたいとき

cronから直接実行すると、環境変数が読み込まれず動作しない模様

たとえば、毎日0時0分にmedia removeを実行する場合は下記のようにする

crontab
0 0 * * * /bin/bash -l -c 'cd ~/live && RAILS_ENV=production bundle exec bin/tootctl media remove >> ~/log/media_remove.log 2>&1'

crontabでの時間指定の仕方については、ここでは省かせて頂く(検索するとたくさん出てくる)

これによりtootctl等のコマンドを通常通り実行することができる。

※Docker環境での動かし方について情報求む

スパム対策

(他にやれそうなことがあったら教えてください)

公開していると、どうしてもスパムがやってきます。
それらの対策について、ケースごとに紹介します。
スパマー許すまじ

連合を組んだ他のサーバからスパム投稿が送られてくる場合

  • 特定のユーザからスパム投稿が行われている場合、そのユーザを「転送」を有効にして通報する。加えて、「モデレーション」画面から該当ユーザを探し、「サスペンド」「活動停止」を実行する。
  • 特定のサーバがスパムアカウントだらけになっており、まるごと封じたい場合は、管理者権限で「既知のサーバー」より「ドメインブロック」を行う。

自分のサーバにスパムアカウントが作られた場合

  • そのユーザを通報するか、「設定」→「モデレーション」画面から該当ユーザを探し、「サスペンド」「活動停止」を実行する。
  • 断続的に作られてしまって収拾がつかなくなってしまった場合は、いったん「サイト設定」内の「新規登録」を「誰も許可しない」に設定し、順次該当アカウントの「サスペンド」「活動停止」を実行する。

ただし、今あるスパムアカウントの対処し終わったからとって、何も対策せず再解放すると、再び嵐のようなスパム登録が行われる可能性が高いので、後述するメールブラックリストの設定や、Nginxでのアクセス制限を設定してから解放する。

新規登録を「承認制」もしくは「招待制」とすれば、ある程度抑制はできると思われるが、スパマーでない新規登録者も参加しづらくなる問題がある。

メールブラックリストの設定

メールアドレスのドメイン部を調べる

まず、スパムアカウントのメールアドレスのドメイン部を調べる。
たとえば、 alice@evil.example.com というメールアドレスが使われていた場合
ドメイン部は evil.example.com である。
まずこれを控えておく。

ドメインのMXレコードを調べる

MXレコード = 電子メールの配送先を示すDNSのレコード。

メールのドメイン部をころころ変えて登録してくるパターンでも、実はMXレコードは同じところを指し示して使い回しているケースがあり、その場合、それを抑えれば一網打尽にできる可能性がある。

MXレコードの調べ方

たとえば evil.example.com のMXレコードを調べたい時

nslookup を使う例。
Windows 10 / Linux(Fedora)にて動作確認。

$ nslookup -type=mx evil.example.com
Server:         192.168.xxx.xxx
Address:        192.168.xxx.xxx#53

Non-authoritative answer:
evil.example.com   mail exchanger = 0 mail.evil.example.com.

Authoritative answers can be found from:

dig を使う例。
Linux(CentOS)にて動作確認。

$ dig mx evil.example.com

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> mx evil.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34355
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;evil.example.com.                  IN      MX

;; AUTHORITY SECTION:
evil.example.com.           299     IN      SOA     mail.evil.example.com. 1 3600 300 2419200 300

;; Query time: 351 msec
;; SERVER: xxx.xxx.xxx.xxx#53(xxx.xxx.xxx.xxx)
;; WHEN: Wed Jul 25 14:28:50 JST 2018
;; MSG SIZE  rcvd: 127

この結果から、メールの配送先は mail.evil.example.com であることが分かる。
これも控えておく。

メールブラックリストの追加を行う

  • Mastodonに管理者権限でログインし、「設定」→「モデレーション」→「メールブラックリスト」の画面へ行く。
  • 上記手順にて調べた「メールアドレスのドメイン部」「MXレコード」を新規追加する。

Nginxでのアクセス制限の設定

どうしてものときの最終手段。
ちょっと複雑です。

スパマーのIPレンジを調べる

  • 「設定」→「モデレーション」画面から該当ユーザを探し、「直近のIP」を控える。(例:192.168.0.5)
  • IPの範囲を検索し、CIDR表記にする。(例:192.168.0.0/24)

CMAN ドメイン/IPアドレス サーチ などを使うと調べられるかも?

ブラックリストを作る

  • ブラックリスト用ファイルを作成し、CIDR表記を書き込む。(ファイルの場所は任意)
$ sudo vim /etc/nginx/conf.d/blacklist.conf
/etc/nginx/conf.d/blacklist.conf
deny 192.168.0.0/24;

ブラックリストを読み込ませる

  • Nginxの設定ファイルにブラックリスト用ファイルを読み込ませる一文を追加する
/etc/nginx/conf.d/mastodon.conf
(前略)

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;

(中略)

  include /etc/nginx/conf.d/blacklist.conf;

(後略)
}

上記例では、Mastodon全体にアクセス制限をかけているが、includeを書く場所を工夫することによって特定のURIのみ制限をかけることも可能。

たとえば、以下のようにする。

  # サイト全体に効かせたい場合
  location / {
    include /etc/nginx/blacklist_all.txt;
    try_files $uri @proxy;
  }

  # 登録を抑止したい場合(副作用としてログインもできなくなる)
  location /auth {
    include /etc/nginx/blacklist_auth.txt;
    try_files $uri @proxy;
  }

のようにする。

スパム登録を抑止したいだけの場合は、/authに対してのみ適用するといいかもしれない。

設定を反映する

  • Nginxの書式チェックを行い、問題なければリロードして有効化する
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

syntax ok および、test is successful と表示されれば、Nginx設定ファイルの書式は正しい。

$ sudo systemctl reload nginx

サービス再起動(restart)でもよいが、一瞬ダウンタイムが発生してしまう。

パフォーマンスチューニング

(他にやれそうなことがあったら教えてください)

PostgreSQL

サーバスペックに応じたパラメータを設定する

たとえば、pgTune( http://pgtune.leopard.in.ua/ )を参考に、サーバのスペックに合ったパラメータを設定する。

定期的にvacuumを行う

標準機能のautovacuumを有効にしたり、cron等で定期的にvacuumdbコマンドを実行する。
(環境によってはautovacuumが無効になっているので要確認。postgresql.confに設定項目がある。)

それにより、データベースファイルの肥大化を防いだり、多少の速度アップが望めるかもしれない。

cronでvacuumdbを行う場合のcrontabの例
0 4 * * * /usr/bin/vacuumdb -z -U dbuser -d dbname >> ~/log/vacuum.log 2>&1

上記例では、毎日4時に権限のある全テーブルに対し、バキュームおよびオプティマイザ用統計情報の計算を行う。
テーブルロックがかからないとはいえ、それなりに負荷がかかることが想定されるので、アクティブな時間を外すとよい。

接続にSocketを使う

Unix Socketを使うことで、localhost接続よりも高速化が見込めるかもしれない。

/var/lib/pgsql/data/postgresql.conf
listen_addresses = '' # TCP/IPでの待ち受けが必要ない場合は空白とする

unix_socket_directories = '/var/run/postgresql' # ソケットファイルの場所を指定する

デフォルトでは /tmp をソケットディレクトリとして使用する。必要に応じて場所を変更する。
設定を変更したら、有効にするためPostgreSQLサービスを再起動する。

続いて、Mastodon側の設定も変更する。

/home/mastodon/live/.env.production
DB_HOST=/var/run/postgresql

設定を変更したら、Mastodonサービス3点セットを再起動する。

pgBouncer を使う

PgBouncer とは

PgBouncer は、軽量なコネクションプーラーです。
通常、クライアントからデータベースに対して大量の接続が発生すると、接続を確立する為の時間のコストや、接続を管理する為のコンピュータリソースが多く必要となります。
このようなケースにおいて PgBouncer を使用すると、これらのコストを劇的に減少させる事ができます。
http://postgres.sios.com/modules/newbb/viewtopic.php?forum=1&topic_id=149&post_id=150

コネクションの開閉にはそこそこパワーを使うので、プールしておいて有効に使おうよ、という仕組み。

Mastodon公式ドキュメントにも、pgBouncerに関する記事がある。

tootsuite/documentation - PgBouncer Guide

Redis

Socketを使う

PostgreSQLと同様、Unix Socketを使うことで、localhost接続よりも高速化が見込めるかもしれない。

/etc/redis.conf
port 0 # TCP/IPでの待ち受けが必要ない場合はゼロとする

unixsocket /var/run/redis/redis.sock
unixsocketperm 777

デフォルトではソケットを使用しない設定になっているので、既存の設定値を消すかコメントアウトした上、ソケットの設定を追加する。
ソケットはREDIS_HOSTでなくREDIS_URLに対して設定する点に注意!

設定を変更したら、Redisサービスを再起動する。

続いて、Mastodon側の設定も変更する。

/home/mastodon/live/.env.production
REDIS_URL=unix:///var/run/redis/redis.sock
#REDIS_HOST=127.0.0.1
#REDIS_PORT=6379
#REDIS_PASSWORD=

設定を変更したら、Mastodonサービス3点セットを再起動する。

Mastodon

Tuning Mastodon

jemalloc を使ってメモリ最適化

jemallocとは?

jemalloc は、標準ライブラリで定義されているmalloc, free 等のメモリアロケーション APIの実装である。
http://zonomasa.hatenablog.com/entry/jemalloc_about

詳しい機能については引用元のWebページを参考にして頂きたいが、わたしのざっくりとした理解では:

  • メモリのフラグメンテーションを防止し、有効に使われるようにする
  • マルチコア・スレッド環境においてパフォーマンス向上
  • メモリ周りの不具合(リーク、オーバーフロー等)の検査ツール付

また、このパッケージについて公式ドキュメントでも紹介されている。
Tuning Mastodon - Using jemalloc

Debian系(Ubuntu等)においては、上記公式ドキュメント通りに設定すればよいが、Fedoraにおいてはパッケージ名等が違うので注意が必要。

  • パッケージ名: jemalloc (jemalloc-5.0.1-5.fc28.x86_64 等)
  • インストールパス: /usr/lib64/libjemalloc.so.2

jemallocの導入

yum-install
$ sudo yum install jemalloc jemalloc-devel
$ ls /usr/lib64/libjemalloc.so.2 
/usr/lib64/libjemalloc.so.2

Mastodonに対して設定する前に、Rubyをjemallocに対応させておく必要がある。
jemalloc対応版かどうかを確認し、対応していない場合はRubyの再インストールが必要となる。

確認・アンインストール・インストール手順についての参考資料: rbenvでインストールしたRubyのバージョンを上げる

Mastodonサービス側の設定:jemallocの有効化

mastodon-web.service および mastodon-sidekiq.service に対し、
jemallocを読み込ませるため Environment="LD_PRELOAD=/usr/lib64/libjemalloc.so.2" を追記する。
(下記はwebの例だが、sidekiqも同じように追記する。)

mastodon-web.service
[Unit]
Description=mastodon-web
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="PORT=3000"
Environment="LD_PRELOAD=/usr/lib64/libjemalloc.so.2"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -SIGUSR1 $MAINPID
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target

編集後、更新されたファイルを再読み込みし、webとsidekiqを再起動する。

$ sudo systemctl daemon-reload
$ sudo systemctl restart mastodon-{web,sidekiq}

その他小ネタなど

  • ホスティングサービス等を使用せず、独自にサーバを立て、自分以外の第三者にも使用できる状態にした場合、各地域の総合通信局に「電気通信事業届出」をしておくとよい。
  • 「サイト設定」内に連絡先を記載。メールアドレス、管理者欄を埋める。他のサーバのアカウントなどがあれば併記しておく。サーバに何かあったときに、誰かが知らせてくれるかも。

「お知らせ」の時差(JST to UTC)

タイムラインの上に出る「お知らせ」を作成する際、日付時刻の範囲や掲載開始日時を設定できるが
これはJST(日本標準時)でなくUTC(協定世界時)で設定しなければならない。

UTC・JST間の時差は -9 時間である。

つまり、日本標準時で昼の12時を指定したい場合は、協定世界時の早朝3時にセットする必要がある。

時差を計算するサイトも多数あるので、それらを使うと楽。

keisan by CASIO

時差計算

アーカイブファイルの読み方

Mastodonの「 設定 > インポート・エクスポート > アーカイブのリクエスト 」を用いると、自分が投稿した文章や画像をまとめてダウンロードできるようになります。
しかし、内容はActivityPub形式の大きなJSONファイルのため、そのまま読める形にはなっていません。

手前味噌ですが、ActivityPub形式のoutbox.jsonを読める簡易リーダーを試作しました。
https://gist.github.com/Neustrashimy/51442fe6932c86d2555e18bada0d6c93

使い方は下記投稿を参考にしてください。
https://md.objektiv2.net/@kumasun/103099863276308470

全文検索に対応していないサーバでも、この方法であればブラウザのテキスト検索機能を使用して検索することができます。

謎のファイルが /tmp を食いつぶす問題

/tmp/magick-* (ImageMagickの一時ファイル)

Mastodon側で画像の縮小・メタ情報削除を行う処理を行うようになっているため、そのような一時ファイルが生成されます。
また、何らかの原因により、一時ファイルが削除されず残ってしまうことがあるようです。

/tmp は様々なアプリケーションが一時ファイル置き場として使うので、使い切ってしまうとサーバごと機能不全に陥る可能性があります。

応急処置としては、手動で一時ファイルを削除することで解消できます。

$ rm /tmp/magick-*

再発する場合は、ImageMagickが使用するディスク領域を制限することで解消を図ります。

ImageMagickのリソース制限値表示(Before)
$ identify -list resource
Resource limits:
  Width: 214.7MP
  Height: 214.7MP
  List length: unlimited
  Area: 2.0403GP
  Memory: 972.867MiB
  Map: 1.90013GiB
  Disk: unlimited
  File: 768
  Thread: 2
  Throttle: 0
  Time: unlimited

Disk: unlimited になっているため、限界まで使用しようとします。これを制限します。

$ sudo vim /etc/ImageMagick-6/policy.xml
policy.xml
<policymap>
  <policy domain="resource" name="disk" value="256MB"/>
</policymap>

<policymap> 以下にコメントアウトされている設定値が羅列してありますので、該当部分をコメントアウトして設定し、保存します

ImageMagickのリソース制限値表示(After)
$ identify -list resource
Resource limits:
  Width: 214.7MP
  Height: 214.7MP
  List length: unlimited
  Area: 2.0403GP
  Memory: 972.867MiB
  Map: 1.90013GiB
  Disk: 256000000B
  File: 768
  Thread: 2
  Throttle: 0
  Time: unlimited

Disk値が制限されました。

とりあえず、これで様子を見てみます。

Paperclipの一時ファイル(v3.1.4)

$ ll /tmp
total 138992
-rw------- 1 mastodon mastodon   388526 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-100pphy
-rw------- 1 mastodon mastodon   201603 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-102g7ck
-rw------- 1 mastodon mastodon   106475 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-1052yfm
-rw------- 1 mastodon mastodon    41792 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-10g2myt
-rw------- 1 mastodon mastodon    54901 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-10indac
-rw------- 1 mastodon mastodon    26021 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-10rv5ny
-rw------- 1 mastodon mastodon   416685 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-10ytz90
-rw------- 1 mastodon mastodon    23994 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-116kyt4
-rw------- 1 mastodon mastodon     9726 May 21 13:21 8d777f385d3dfec8815d20f7496026dc20200521-41299-11d09gv
  • 先頭の文字列(8d777f385d3dfec8815d20f7496026dc20200521)はSidekiqのJID
  • 数字(41299)は、mastodon-sidekiqのプロセスID
  • 末尾の文字列(11d09gv等)はSidekiqのTID

であり、Paperclip(ファイル等を操作するライブラリ)によって生成された一時ファイルだろうと思われる。

Sidekiqの管理画面上で該当するジョブが走っていなければ、おそらく消し忘れなので、手動で消しても差し支えないように思う。

あとがき

  • 自分用にメモした内容です。必要に応じて読み替えてください。
  • 使用は自己責任でお願いします。何か不具合が起こっても責任取れません。
  • こうしたほうがいいよ的なアドバイス、誤記や記載漏れ、動作の違い等の指摘を頂けると大変助かります。項目が多くなってきており、すべて検証することが難しくなってきています
  • 連絡先: Mastodon1, Mastodon2

以上

kumasun
くまさん学習帳 PHP, PgSQL, MySQL, Arduino, RasPi など
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした