Ubuntu + Docker環境で全文検索システム「FESS」を構築してみる

GitBucket上のファイルを検索するのに全文検索システム「FESS」を構築したのでメモ。

FESSとは

GitBucketと連携

今回FESSを構築したのは、GitBucket内の全文検索を行うためです。
GitBucketのデフォルトの検索機能はリポジトリ名しか検索できません。

GitBucketのリポジトリ内に調査メモ等を残しているので、あとから見返すときに全文検索できたらなぁ…ということでFESSを利用してみます。

GitBucketの構築記事はこちら

FESS構築

プロセスが使用可能なメモリマップ領域設定

システムパラメータのプロセスが使用可能なメモリマップ領域の最大数を変更します。
パラメータの名前は、「vm.max_map_count」です。

システムパラメータを変更するためには、「/etc.sysctl.d」ディレクトリ以下に.confファイルを作成します。
今回は「10-docker.conf」の名前でファイルを作成します。

vi /etc/sysctl.d/10-docker.conf

「10-docker.conf」ファイルに、以下設定を記述し、保存します。

vm.max_map_count=262144

「10-docker.conf」ファイルを適用するため、sysctlコマンドを実行します。

sudo sysctl -p /etc/sysctl.d/10-docker.conf
picture 2

以下コマンドで、設定が適用されているか確認します。

sudo sysctl -n vm.max_map_count
picture 3

サーバをシャットダウンしても、設定が永続的に適用されているか確認するため、再起動します。

sudo reboot

再起動後、もう一度以下コマンドで設定が適用されているか確認します。

sudo sysctl -n vm.max_map_count

GitBucketにFESS用プラグインを導入する

GitBucketのpluginsフォルダに移動し、FESS用プラグインをダウンロードします。
今回は1.7.0をダウンロードしました。
codelibs/gitbucket-fess-plugin

cd ~/gitbucket/data/plugins/
sudo curl -sLJO https://github.com/codelibs/gitbucket-fess-plugin/releases/download/gitbucket-fess-plugin-1.7.0/gitbucket-fess-plugin_2.13-1.7.0.jar
picture 17

ファイアウォール設定

今回はGitBucketで51000、FESSで51002を使用することとします。
※ファイアウォール設定は、環境に合わせて適切に設定してください。

sudo ufw allow 51000
sudo ufw allow 51002

docker-compose.yml

FESSをdockerで使用するためのdocker-composeファイルが用意されているので、こちらを参考にしてdocker-compose.ymlを作成します。
今回はGitBucketと同じコンテナで動作させることにしたので、GitBucket構築時に作成したdocker-compose.ymlを変更していきます。

FESS用のdocker-composeファイルはこちらにあります。
docker-composeファイルは、FESS本体と、検索エンジンとして使用するのOpenSearchの2つを使用します。

FESS用 compose.yaml
OpenSearch用 compose-opensearch2.yaml

以下、編集したdocker-compose.ymlです。

version: '3'
services:
  gitbucket:
    image: gitbucket/gitbucket:latest
    container_name: gitbucket
    networks:
      - gitbucket_network
    extra_hosts:
      - "aru-server:host-gateway"
    ports:
      - 51000:8081
    expose:
      - 8081
    volumes:
      - ./data:/gitbucket
    environment:
      - TZ=Asia/Tokyo
      - GITBUCKET_DB_URL=jdbc:postgresql://gitbucket_db:5432/gitbucket
      - GITBUCKET_DB_USER=gitbucket
      - GITBUCKET_DB_PASSWORD=gitbucket
      - GITBUCKET_PORT=8081
      - GITBUCKET_PREFIX=gitbucket
    restart: always
    depends_on:
      gitbucket_db:
        condition: service_healthy

  gitbucket_db:
    image: postgres:15.1-alpine
    container_name: gitbucket_db
    networks:
      - gitbucket_network
    ports:
      - 51001:5432
    environment:
      - POSTGRES_DB=gitbucket
      - POSTGRES_USER=gitbucket
      - POSTGRES_PASSWORD=gitbucket
      - TZ=Asia/Tokyo
      - LANG=ja_JP.UTF-8
    volumes:
      - ./db/data:/var/lib/postgresql/gitbucket_data
    restart: always
    healthcheck:
      test: pg_isready -d gitbucket
      interval: 1s

  fess01:
    image: ghcr.io/codelibs/fess:14.6.1
    container_name: fess01
    environment:
      - TZ=Asia/Tokyo
      - "FESS_CONTEXT_PATH=/fess/"
      - "SEARCH_ENGINE_HTTP_URL=http://es01:9200"
      - "FESS_DICTIONARY_PATH=${FESS_DICTIONARY_PATH:-/usr/share/opensearch/config/dictionary/}"
    ports:
      - "51002:8080"
    expose:
      - 8080
    networks:
      - gitbucket_network
    extra_hosts:
      - "aru-server:host-gateway"
    volumes:
      - fessdata01:/usr/share/fess
    depends_on:
      - es01
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"
    restart: always

  es01:
    image: ghcr.io/codelibs/fess-opensearch:2.4.1
    container_name: es01
    environment:
      - TZ=Asia/Tokyo
      - node.name=es01
      - discovery.seed_hosts=es01
      - cluster.initial_cluster_manager_nodes=es01
      - cluster.name=fess-es
      - bootstrap.memory_lock=true
      - plugins.security.disabled=true
      - "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
      - "FESS_DICTIONARY_PATH=/usr/share/opensearch/config/dictionary"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65535
        hard: 65535
    volumes:
      - esdata01:/usr/share/opensearch/data
      - esdictionary01:/usr/share/opensearch/config/dictionary
    ports:
      - 9200:9200
    networks:
      - gitbucket_network
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"
    restart: always

volumes:
  fessdata01:
    driver: local
  esdata01:
    driver: local
  esdictionary01:
    driver: local

networks:
  gitbucket_network:
    driver: bridge

今回はGitBucketの設定も合わせて変更しています。

  • GitBucketの使用ポートを8080から8081に変更

GitBucketもFESSも、デフォルトの使用ポートが8080になっているため、設定で別のポートを使用するように変更します。
今回は、GitBucket側の使用ポートを8081に変更して対応しました。

~
    ports:
      - 51000:8081
    expose:
      - 8081
~
    environment:
~
      - GITBUCKET_PORT=8081
~
  • GitBucketのURLを変更

GitBucketにアクセスするときのURLは、「http://<ホスト名>:<ポート名>」でした。
今回、FESSと併用するときにポート名のみで区別するのも…ということでprefix設定を追加。

~
    environment:
~
      - GITBUCKET_PREFIX=gitbucket
~

上記設定をすることで、「http://<ホスト名>:<ポート名>/gitbucket」でアクセス可能になります。

http://aru-server:51000/gitbucket/

起動確認

GitBucketを起動している場合は、GitBucketのコンテナを終了しておきます。
「docker stop <コンテナ名>」で停止できます。

docker stop gitbucket
docker stop gitbucket_db

docker-compose.ymlが用意できたら、docker composeコマンドで起動します。

docker compose up -d

起動出来たら、ブラウザからFESSにアクセスしてみます。
上記docker-compose.ymlを使用した場合、URLは「http://<ホスト名>:<ポート名>/fess/」になります。

http://aru-server:51002/fess/

正常に起動できていれば、FESSのページが表示されます。

picture 6

GitBucketで使用してみる

GitBucketにはFESSを利用するためのプラグインがあり、以下のサイトで連携方法が紹介されています。

GitBucketで高速に横断検索するためのプラグイン

GitBucketにてアクセストークンを発行する

「Account setting」 > 「Applications」を選択し、Generate new tokenから新しいアクセストークンを発行します。

picture 7

FESSの設定

  • プラグインのインストール
    FESSにログインし、「システム」 > 「プラグイン」からGitBucket用のプラグインをインストールします。
    ※初期ユーザ名、パスワード名は両方「admin」。
picture 8
picture 9
  • クロール設定
    次に、データストアのクロール設定を行います。
    「クローラ」 > 「データストア」を選択し、データストアのクロール設定画面で名前、ハンドラー名、パラメーターを設定します。

名前は任意、ハンドラー名は「GitBucketDataStore」、パラメーターはurlとtokenの設定を行います。
urlはGitBucketにアクセスするためのURL、tokenはGitBucketにて発行したアクセストークンを設定します。

http://aru-server:51000/gitbucket
picture 10
picture 11
  • ジョブ設定

次に、ジョブスケジューラの設定を行います。
作成したクロール設定をクリックすると、クロール設定の詳細が表示されるので、画面下部の「新しいジョブの作成」をクリックします。

picture 12

ジョブの設定では、クロールを行うタイミングを設定します。※詳細はこちら
今回は、毎日0:00にクロールを行うように設定しています。

picture 13

次に、クロールを手動で実行します。
「システム」 > 「スケジューラ」から先ほど作成したジョブをクリックします。

picture 14

画面下部の「今すぐ開始」をクリックします。
※作成直後は開始できないので、エラーがでたらしばらく放置してから再度実行してみてください。

picture 15

一覧表を更新すると、ジョブの状態が「実行中」になるので、状態が「有効」になるまで待機します。

picture 16
  • 動作確認

実行後、左上の検索欄から検索を行うと、GitBucket内のページを検索してくれます。

picture 18

上記例では、リポジトリに登録されているREADME.mdの他に、登録したIssueまで検索できています。
なかなかよさそう。

リポジトリは、おそらくデフォルトのブランチのみ検索する?のかmasterブランチは検索対象でしたが、developブランチの内容は検索されないという動作。

書きかけのdevelopブランチの内容が検索結果にはいったりはしなさそう。

  • FESS側のトークンの発行

GitBucketからFESSの検索結果を取得できるよう、FESS側でアクセストークンを発行します。
「システム」 > 「アクセストークン」からアクセストークンを発行し、トークンを取得します。

picture 19

GitBucketの設定

  • FESS側で発行したアクセストークンを登録

GitBucket側に、FESS側で発行したアクセストークンを登録します。
GitBucketに管理者でログインし、「http://<ホスト名>:<ポート名>/gitbucket/fess/settings」にアクセスします。

Fess URLに「http://<FESSのコンテナ名>:<FESSのポート>/fess」、Access TokenにFESS側で発行したアクセストークンを登録します。

http://aru-server:51000/gitbucket/fess/settings
picture 20

設定後、「http://<ホスト名>:<ポート名>/gitbucket/fess」にアクセスすることで、検索機能を使用することができます。

GitBucket 4.36.2以降だと使用できない?

GitBucketは4.38.0を使用しているのですが、検索画面でエラーのような文字列が。。。
こちらのissueに同様の事象が報告されているのですが、バージョンの問題なのか、docker上なのが問題なのか、はたまた別の問題か。

とりあえずはFESSの方にアクセスすれば検索自体はできるので、現状は運用でカバーとしておく。

picture 21

参考URL

codelibs/docker-fess
Fessのセットアップ
GitBucketで高速に横断検索するためのプラグイン
codelibs/gitbucket-fess-plugin
Not compatible with gitbucket 4.36.2