DockerのElasticsearchにSudachiをみっちり入れる
目的
前回は、SudachiをElasticsearchに入れるシンプルなやり方を紹介しました。
しかし、ダウンロードURLが変わったらどうすんの?バージョン文字列ならまだしも、いつ変わるか分からない文字列を持ちたくないです!という人もいらっしゃるでしょうし、 pom.xmlがあるんだから自分でビルドするがな! という奇特な方もいると思います。
今回はそんな方向けの情報です。
やること
必要な資源は3つなのは変わりません。
- Elasticsearch
- Sudachiの辞書
- elasticsearch-sudachiのプラグイン
ですが、これをSudachiに関しては、すべてGithubからソースを落としてきてビルドしましょう。
マルチステージで並列ビルドさせます。
辞書を生成するのと、elasticseaerch-sudachiプラグインは互いに独立した処理にできます。 辞書には、sudachiのjarが必要なので、sudachiのjarを作るところから入ります。
結論
Dockerファイルをあげておきましょう。
原本は以下に置いてあります。
https://github.com/tsgkdt/elasticsearch-sudachi-docker/blob/master/Dockerfile
# syntax = docker/dockerfile:1.0-experimental ARG ELASTIC_VER=6.7.0 ARG ELASTIC_SUDACHI_VER=${ELASTIC_VER}-1.3.0 ARG SUDACHI_VER=0.2.1 ###################################################################### # Sudachi本体のビルド. 辞書ビルドで、このjarが必要になる ###################################################################### FROM maven:3-jdk-8 as sudachi RUN --mount=type=cache,target=/root/.m2 \ git clone https://github.com/WorksApplications/Sudachi.git && \ cd Sudachi && \ mvn package -Dfile.encoding=UTF-8 ###################################################################### # Sudachiの辞書をビルドする. ここは時間かかる ###################################################################### FROM maven:3-jdk-8 as sudachi-dic # Heapを多めにとっておかないと、辞書をビルドするときOutOfMemoryに遭遇する ENV MAVEN_OPTS=-Xmx4096m ARG SUDACHI_VER COPY --from=sudachi /Sudachi/target/sudachi-${SUDACHI_VER}-SNAPSHOT.jar /Sudachi/target/sudachi-${SUDACHI_VER}-SNAPSHOT.jar RUN --mount=type=cache,target=/root/.m2 \ curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && \ apt-get install git-lfs && \ git lfs install && \ : "sudachiのjarファイルをmavenに登録する" && \ mvn install:install-file \ -Dfile=/Sudachi/target/sudachi-${SUDACHI_VER}-SNAPSHOT.jar \ -DgroupId=com.worksap.nlp \ -DartifactId=sudachi \ -Dversion=${SUDACHI_VER}-SNAPSHOT \ -Dpackaging=jar \ -DgeneratePom=true && \ : "辞書をCloneしてビルドする" && \ git clone https://github.com/WorksApplications/SudachiDict.git && \ cd SudachiDict && git pull origin develop && \ sed -i -e "s/0.1.2-SNAPSHOT/${SUDACHI_VER}-SNAPSHOT/g" pom.xml && \ sed -i -e 's#</dependencies>#<dependency><groupId>com.worksap.nlp</groupId><artifactId>jdartsclone</artifactId><version>1.0.1</version></dependency></dependencies>#g' pom.xml && \ mvn package -Dmaven.test.skip=true -Dfile.encoding=UTF-8 && \ mkdir -p /sudachi-dic && \ mv ./target/*.dic /sudachi-dic/ ###################################################################### # elsaticsearch-sudachiをビルドする ###################################################################### FROM maven:3-jdk-8 as sudachi-plugin ARG ELASTIC_VER ARG ELASTIC_SUDACHI_VER ENV ELASTIC_SUDACHI_FILENAME=analysis-sudachi-elasticsearch${ELASTIC_SUDACHI_VER}-SNAPSHOT.zip ENV ELASTIC_SUDACHI_URL=https://github.com/WorksApplications/elasticsearch-sudachi/releases/download/v${ELASTIC_SUDACHI_VER}/${ELASTIC_SUDACHI_FILENAME} RUN --mount=type=cache,target=/root/.m2 \ git clone https://github.com/WorksApplications/elasticsearch-sudachi.git && \ cd elasticsearch-sudachi && \ git checkout -b worktag refs/tags/v${ELASTIC_SUDACHI_VER} && \ sed -i -e "s#<artifactId>analysis-sudachi-elasticsearch.*</artifactId>#<artifactId>analysis-sudachi-elasticsearch${ELASTIC_VER}</artifactId>#g" pom.xml && \ mvn package -Dmaven.test.skip=true && \ mv ./target/releases /sudachi-plugin/ ###################################################################### # Sudachiプラグインを入れたElasticsearchのイメージをビルドする ###################################################################### FROM docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VER} COPY --chown=elasticsearch:root --from=sudachi-dic /sudachi-dic/*.dic ./config/sudachi/ COPY --chown=elasticsearch:root --from=sudachi-plugin /sudachi-plugin/*.zip /tmp/elasticsearch/plugins/ ARG ELASTIC_SUDACHI_VER ARG ELASTIC_SUDACHI_FILENAME=analysis-sudachi-elasticsearch${ELASTIC_SUDACHI_VER}.zip RUN bin/elasticsearch-plugin install -v file:///tmp/elasticsearch/plugins/${ELASTIC_SUDACHI_FILENAME}
注意点
DOCKER_BUILDKITを使ってます。
export DOCKER_BUILDKIT=1
でビルドします。
Dockerfileのポイント
Sudachi本体のビルド
###################################################################### # Sudachi本体のビルド. 辞書ビルドで、このjarが必要になる ###################################################################### FROM maven:3-jdk-8 as sudachi RUN --mount=type=cache,target=/root/.m2 \ git clone https://github.com/WorksApplications/Sudachi.git && \ cd Sudachi && \ mvn package -Dfile.encoding=UTF-8
ここは何もないですね。git cloneしてmavenでビルドするだけです。
Sudachiの辞書のビルド
###################################################################### # Sudachiの辞書をビルドする. ここは時間かかる ###################################################################### FROM maven:3-jdk-8 as sudachi-dic # Heapを多めにとっておかないと、辞書をビルドするときOutOfMemoryに遭遇する ENV MAVEN_OPTS=-Xmx4096m ARG SUDACHI_VER COPY --from=sudachi /Sudachi/target/sudachi-${SUDACHI_VER}-SNAPSHOT.jar /Sudachi/target/sudachi-${SUDACHI_VER}-SNAPSHOT.jar RUN --mount=type=cache,target=/root/.m2 \ curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && \ apt-get install git-lfs && \ git lfs install && \ : "sudachiのjarファイルをmavenに登録する" && \ mvn install:install-file \ -Dfile=/Sudachi/target/sudachi-${SUDACHI_VER}-SNAPSHOT.jar \ -DgroupId=com.worksap.nlp \ -DartifactId=sudachi \ -Dversion=${SUDACHI_VER}-SNAPSHOT \ -Dpackaging=jar \ -DgeneratePom=true && \ : "辞書をCloneしてビルドする" && \ git clone https://github.com/WorksApplications/SudachiDict.git && \ cd SudachiDict && git pull origin develop && \ sed -i -e "s/0.1.2-SNAPSHOT/${SUDACHI_VER}-SNAPSHOT/g" pom.xml && \ sed -i -e 's#</dependencies>#<dependency><groupId>com.worksap.nlp</groupId><artifactId>jdartsclone</artifactId><version>1.0.1</version></dependency></dependencies>#g' pom.xml && \ mvn package -Dmaven.test.skip=true -Dfile.encoding=UTF-8 && \ mkdir -p /sudachi-dic && \ mv ./target/*.dic /sudachi-dic/
先ほどビルドしたsudachiのjarを使うことにしましょう。
Sudachiの辞書は、 https://github.com/WorksApplications/SudachiDict にありますが、今のところdevelopブランチしかないです。
sudachiのバージョン問題
2019/04/09時点では、このdevelopブランチのpomファイルでは、0.1.2-SNAPSHOTを使うとありますが、この時点でのSudachi本体の方は、0.2.1-SNAPSHOTまで上がっています。
仕方ないのでsedでpomを書き換えます。
sed -i -e "s/0.1.2-SNAPSHOT/${SUDACHI_VER}-SNAPSHOT/g" pom.xml
jar足りない問題
標準のpomのまま続けてビルドしようとすると、NoClassDefFoundErrorに見舞われます。
足りないのは、jdartscloneです。これをdependenciesに足してやりましょう。
またまた無理やりsedでpomをかきかえます。
sed -i -e 's#</dependencies>#<dependency><groupId>com.worksap.nlp</groupId><artifactId>jdartsclone</artifactId><version>1.0.1</version></dependency></dependencies>#g' pom.xml
メモリ足りない問題
何も考えずにmvn packageを実行すると長い間またされた後に、OutOfMemoryで落ちるという悲劇が待っています。
多めにメモリを割り当てておきましょう。
# Heapを多めにとっておかないと、辞書をビルドするときOutOfMemoryに遭遇する ENV MAVEN_OPTS=-Xmx4096m
elasticsearch-sudachiプラグインのビルド
###################################################################### # elsaticsearch-sudachiをビルドする ###################################################################### FROM maven:3-jdk-8 as sudachi-plugin ARG ELASTIC_VER ARG ELASTIC_SUDACHI_VER ENV ELASTIC_SUDACHI_FILENAME=analysis-sudachi-elasticsearch${ELASTIC_SUDACHI_VER}-SNAPSHOT.zip ENV ELASTIC_SUDACHI_URL=https://github.com/WorksApplications/elasticsearch-sudachi/releases/download/v${ELASTIC_SUDACHI_VER}/${ELASTIC_SUDACHI_FILENAME} RUN --mount=type=cache,target=/root/.m2 \ git clone https://github.com/WorksApplications/elasticsearch-sudachi.git && \ cd elasticsearch-sudachi && \ git checkout -b worktag refs/tags/v${ELASTIC_SUDACHI_VER} && \ sed -i -e "s#<artifactId>analysis-sudachi-elasticsearch.*</artifactId>#<artifactId>analysis-sudachi-elasticsearch${ELASTIC_VER}</artifactId>#g" pom.xml && \ mvn package -Dmaven.test.skip=true && \ mv ./target/releases /sudachi-plugin/
https://github.com/WorksApplications/elasticsearch-sudachi
こちらの方は辞書とは異なり、リリースごとにタグが打たれています。 なので、ElasticsearchとSudachiのバージョンの組み合わせの環境が取得しやすいですね。
こんな感じで、指定バージョンのソースを取得しましょう。
git checkout -b worktag refs/tags/v${ELASTIC_SUDACHI_VER}
6.7.0なのに6.7.1になっていた件
v6.7.0-1.3.0をビルドしようとしていたところ、出力されたartifactを見るとv6.7.1-1.3.0になっていて困りました。
https://github.com/WorksApplications/elasticsearch-sudachi/blob/v6.7.0-1.3.0/pom.xml
<artifactId>analysis-sudachi-elasticsearch6.7</artifactId>
6.7までしか指定していないと、そのときの最新版を取ってしまうようです。 なので6.7.0しか世の中に存在しないときは良いんですが、6.7.1が出たら6.7.0の環境のつもりなのに6.7.1になってしまいます。
そうならないようにするためには、6.7で止めるのではなく最後のバージョンまで指定してやればよいです。
そこで、sed
sed -i -e "s#<artifactId>analysis-sudachi-elasticsearch.*</artifactId>#<artifactId>analysis-sudachi-elasticsearch${ELASTIC_VER}</artifactId>#g" pom.xml
Elasticsearchへ
###################################################################### # Sudachiプラグインを入れたElasticsearchのイメージをビルドする ###################################################################### FROM docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VER} COPY --chown=elasticsearch:root --from=sudachi-dic /sudachi-dic/*.dic ./config/sudachi/ COPY --chown=elasticsearch:root --from=sudachi-plugin /sudachi-plugin/*.zip /tmp/elasticsearch/plugins/ ARG ELASTIC_SUDACHI_VER ARG ELASTIC_SUDACHI_FILENAME=analysis-sudachi-elasticsearch${ELASTIC_SUDACHI_VER}.zip RUN bin/elasticsearch-plugin install -v file:///tmp/elasticsearch/plugins/${ELASTIC_SUDACHI_FILENAME}
事前のステージでビルドした成果物をもってきて、辞書をコピー、プラグインのインストールの2ステップをやって終わりです。 お疲れさまでした。