プログラミングなんてわからないんですけど〜

元プログラマによるプライベートでのプログラミング日記。1/3のつもりだけどソフト関連はここがメイン

fediversesearchの構築手順をまとめてみる(その3:fediversesearch-crawler)

第3回目は、fediversesearch-crawlerです。これで、システムとしてまともに動くようになります。前回、前々回の記事はこちら。
www.kaias1jp.com
www.kaias1jp.com

今回対象とするOS

今回対象とするOSは、Ubuntu 20.04.2 LTSとします。

構築手順

前準備(fediversesearch-serverとサーバーを分ける場合)

fediversesearch-crawlerはrubyとbundler gem、パッケージマネージャーのyarnを必要とします。また、fediversesearchユーザーでの作業を前提とします。これらは、fediversesearch-serverを構築した場合はすでにありますがサーバーを分ける場合は改めて準備しなくてはなりません。

OSの最新化

まずは、OSを最新の状態にしておきます。

sudo apt update
sudo apt upgrade -y

tmux上で作業するのがお勧めです。
再起動が必要な場合は念のため再起動してください。

yarnをインストールする

node.jsのパッケージマネージャーであるyarnをインストールします。

curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
ユーザーの作成

「fediversesearch」というユーザーを作成します。

sudo -i
adduser fediversesearch --disabled-login -q --gecos ""
rubyのインストール

fediversesearchユーザーになって、rubyをインストールします。

apt install -y build-essential libssl-dev zlib1g-dev
su - fediversesearch
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="~/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
rbenv install 2.7.3
rbenv global 2.7.3
bundlerのインストール

bundlerをインストールします。

gem install bundler

fediversesearch-crawlerをインストールする

ruby2.7.3とbundler、yarnがfediversesearchユーザーで使える状態になったら、fediversesearch-crawlerをインストールします。

前準備

fediversesearch-crawlerではredisを使いますので、sudoコマンドが使えるユーザーでredisをインストールします。

sudo apt install redis

redisサービスを登録して起動しておきましょう。

sudo systemctl enable redis-server
sudo systemctl start redis-server

sqlite3のライブラリが必要ですので、それをインストールします。

sudo apt install libsqlite3-dev

以下の作業はfediversesearchユーザーにて、そのホームディレクトリ直下から始めます。

fediversesearch-crawlerのソースコードのダウンロード

githubリポジトリからfediversesearch-crawlerのソースコードをダウンロードします。展開先はcrawlerディレクトリとしています。

git clone https://github.com/kaias1jp/fediversesearch-crawler.git crawler
必要なgemのインストール

crawlerディレクトリに移動して、必要なgemをインストールします。

cd crawler
bundle install
master.keyを作成する

config/master.keyがないとrailsの各コマンドが実行できません。そのため、再作成します。

EDITOR=vim bin/rails credentials:edit
yarn installの実行

yarn installを実行します。

yarn install
認証用tokenを作成する

crawlerで集めてきたデータを投入するためには、投入する前にfediversesearch-serverに対してtokenを発行してもらう必要があります。現時点ではUIを作っていないので、curlコマンドで取りに行きます。

curl -X POST  -H 'Content-Type:application/json' -d '{ "name": "crawler", "pwd": "crawler" }' http://fediversesearch-serverサービスのIPアドレス:18000/users

-dオプションでjsonの形でユーザ名とパスワードを指定してユーザを作成します。作成できると、その戻り値としてtokenが通知されます。

.env.productionファイルを作成する

設定ファイルである「.env.production」ファイルを作成します。ファイルの中身はこんな感じです。

.env.production

SERVER_URL = "http://fediversesearch-serverサービスのIPアドレス:18000"
SERVER_TOKEN =  "認証用token"
アセットをプリコンパイルする

アセットをプリコンパイルします。

RAILS_ENV=production bundle exec rails assets:precompile
試しにfediversesearch-crawlerのsidekiqを立ち上げてみる

確認のため、fediversesearch-crawlerのsidekiqを立ち上げてみましょう。

RAILS_ENV=production bundle exec sidekiq &

起動できれば「INFO: Booting Sidekiq 6.2.1 with redis options {:url=>"redis://localhost:6379", :namespace=>"fediversesearch_production"}」みたいなメッセージが表示されるはずです。リターンキーを押してプロンプトで入力できる状態に戻ってください。
次にsidekiqのweb画面を立ち上げてみましょう。

RAILS_ENV=production PORT=4000 rails s -b 0.0.0.0 &

起動できれば「* Listening on http://0.0.0.0:4000」と表示されます。この状態で、Webブラウザから「http://fediversesearch-crawlerIPアドレス:4000/sidekiq」にアクセスすると、以下のような画面が表示されるはずです。

f:id:kaias1jp:20210924164820p:plain

画像ではキューが積まれていますが、workerを呼び出さないとまだ積まれていないはずです。なので実際にworkerを呼び出してみます。リターンキーを押してプロンプトで入力できる状態に戻ってから、以下を順番に実行してみてください。

~/.rbenv/shims/rails runner -e production "AddSiteWorker.perform_async('popon.pptdn.jp')"
~/.rbenv/shims/rails runner -e production "PeerAllWorker.perform_async()"
~/.rbenv/shims/rails runner -e production "CrawlNewsiteWorker.perform_async()"

最初の「AddSiteWorker.perform_async('popon.pptdn.jp')」は、「popon.pptdn.jpというサイトをDBに追加する」というものです。「popon.pptdn.jp」は私が管理しているmastodonサーバーです。
次の「PeerAllWorker.perform_async()」は、「登録されている全てのサイトのpeers情報を取得して、未登録のサイトがあったらDBに追加する」というものです。
最後の「CrawlNewsiteWorker.perform_async()」は、「新しく追加されたサイトの情報を取得しに行く」というものです。
popon.pptdn.jpにはすでに2000件くらいの他のサーバーと連合を組んでいますので、peers情報にこれらのサイトが列挙されています。crawlerは、追加されたサイト1つを1つのキューとして積み、そのキューでそのサーバーの情報をクロールします。つまり、上記のコマンドを実行することで2000件以上のクロールを非同期に実行するわけです。もちろん、1つのサーバーに対しては1度しかクロールしません。クロールが終わると、WebUIでこのようになるはずです。

f:id:kaias1jp:20210924170826p:plain

これで動くことが確認出来たら念のため起動した2つのプロセスを終了させておきます。

ps -ef | grep sidekiq | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep puma | grep -v grep | awk '{print $2}' | xargs kill -9
fediversesearch-crawlerをサービスとして登録する

動作確認が終わったら、fediversesearch-crawlerをサービスとして登録しましょう。rootユーザーに戻ってserviceファイルを作成します。作成するファイルは「fediversesearch-crawler-sidekiq.service」と「fediversesearch-crawler-web.service」とします。「/etc/systemd/system/」の下に作成してください。

fediversesearch-crawler-sidekiq.service

[Unit]
Description=fediversesearch-crawler-sidekiq
After=network.target

[Service]
Type=simple
User=fediversesearch
WorkingDirectory=/home/fediversesearch/crawler
Environment="RAILS_ENV=production"
Environment="DB_POOL=25"
Environment="MALLOC_ARENA_MAX=2"
ExecStart=/home/fediversesearch/.rbenv/shims/bundle exec sidekiq -c 25 -q default
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target


fediversesearch-crawler-web.service

[Unit]
Description=fediversesearch-crawler-web
After=network.target

[Service]
Type=simple
User=fediversesearch
WorkingDirectory=/home/fediversesearch/crawler
Environment="RAILS_ENV=production"
Environment="PORT=14000"
ExecStart=/home/fediversesearch/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -SIGUSR1 $MAINPID
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target

ファイルの作成が終わったら、サービスとして登録してから起動します。

systemctl daemon-reload
systemctl enable fediversesearch-crawler-sidekiq
systemctl start fediversesearch-crawler-sidekiq
systemctl enable fediversesearch-crawler-web
systemctl start fediversesearch-crawler-web

ひとまずこんなところです。