目的
前回は、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ステップをやって終わりです。 お疲れさまでした。