sbt の Docker image を探したり作ったり
sbt の Docker image を探したり作ったり
概要
sbt が使える docker image を探し、
結果的に自前で Dcokerfile をつくって image を作成しました。
その時に得た知見なんかを共有できればいいなと思ったので記載しました。
作った Docker image, Dockerfile は以下にあります。
- Docker Hub
- Github
動機
特定の Scala プロジェクトの開発・動作確認時に自分の環境で実行させらず、
Docker image がほしいなと思ったためです。
Docker image が欲しくなった
私は開発環境として Windows を使うことが多いのですが、
Scala は JVM 上で動作する言語のため、環境依存についていままで気にしたこともありませんでした。
特定の Scala project、特に JavaScript を使っているプロジェクトで
sbt job を実行できない事象に遭遇しました。
具体的にいうと、 munit のドキュメントを修正して contribute しようとしたのですが、
修正してドキュメントの生成確認に docs/docusaurusCreateSite というジョブを実行するのに yarn
が動かなくて失敗になりました。
> sbt docs/docusaurusCreateSite
...
[error] (docs / docusaurusCreateSite) java.io.IOException: Cannot run program "yarn" (in directory "C:\Users\kofuj\work\scala\munit-mine\website"): CreateProcess error=2, 指定されたファイルが見つか
りません。
[error] Total time: 49 s, completed YYYY/MM/DD h:mm:ss
おそらく このあたり が原因で、
sbt から実行した時に私の Windows の実行パスが読み取れなくて失敗したのだと思います。
環境側の設定を見直すべきなのかもしれないですが、せっかくなら Docker 上で確認できれば
差分を気にしなくても良くなるのかなと思い、Docker image を探してみようと思いました。
Docker image を探してみて
欲しいイメージがありませんでした。
探した条件としては以下になります
- sbt 1.5 以上
- JDK 11
- yarn が使える
特に yarn が入ってるものが見つかりませんでした。
※ みつけられなかっただけかもしれませんが
ということで、せっかくなので自分で Dockerfile を作ってみることにしました。
現存する image に後から追加することもできますが、
何度も使うなら最初から入っているほうが嬉しいので。
Docker image を作る
参考にさせていただいたもの
sbt のメインメンテナーの一人である eed3si9n さんのが目を引きました。
Docker での sbt
注目した点は alpine ベースで馴染みがあったり、JDK8, JDK11 で選択できるところであったりが嬉しかったです。
image をそのまま使わなかった理由としては、
- 最後の更新が少し前(8ヶ月くらい)
- sbt のバージョンも 1.4 系だった
Dockerfile
用途別で使い分けられるように sbt のインストールと yarn のインストールを分けるようにしました。
JDK は LTS のもので切り替えられるとよさそうだと思ったので、8, 11, 17 のものにしました。
8, 11 は adopt の image ですが、17 は(まだ)adopt がないので openjdk のものを使うようにしました。
- sbt
FROM adoptopenjdk/openjdk11:jre-11.0.13_8-alpine
ARG SBT_VERSION=1.5.5
RUN set -x \
# install sbt
&& apk --update add --no-cache --virtual .build-deps curl \
&& SBT_VER=${SBT_VERSION} \
&& SBT_URL="https://github.com/sbt/sbt/releases/download/v${SBT_VER}/sbt-${SBT_VER}.zip" \
&& apk add shadow bash openssh rsync git \
&& curl -Ls ${SBT_URL} > /tmp/sbt-${SBT_VER}.zip \
&& mkdir /opt/sbt \
&& unzip /tmp/sbt-${SBT_VER}.zip -d /opt/sbt \
&& sed -i -r 's#run \"\$\@\"#unset JAVA_TOOL_OPTIONS\nrun \"\$\@\"#g' /opt/sbt/sbt/bin/sbt \
&& apk del --purge .build-deps \
&& rm -rf /tmp/sbt-${SBT_VER}.tgz /var/cache/apk/* \
# create workdir
&& mkdir /work
WORKDIR /work
ENV PATH="/opt/sbt/sbt/bin:$PATH" \
JAVA_OPTS="-XX:+UseContainerSupport -Dfile.encoding=UTF-8" \
SBT_OPTS="-Xmx2048M -Xss2M"
sbt のインストールは他のレポジトリをみても、大きく分けると以下の2つがありそうでした
- sdkman から入れる
- 圧縮ファイルを取得して展開する
圧縮ファイルから取得するようにしています。sdkman から取得するとどうしても容量が大きくなりそうだったので。。。
参考にさせてもらった Dockerfile では別の URL から sbt の圧縮ファイルを取得するようになっていたのですが、
いつからか取得できなくなっている らしく、
GitHub の圧縮ファイルを取得するようにしてます。
- yarn
FROM keyno63/sbt:1.5-jdk11-alpine
RUN set -x \
&& apk add bash curl nodejs \
&& touch ~/.bashrc \
&& curl -o- -L https://yarnpkg.com/install.sh | bash \
&& ln -s "$HOME/.yarn/bin/yarn" /usr/local/bin/yarn
ENV PATH="$HOME/.yarn/bin:$PATH"
上に書いた sbt の Docker image をベースに、yarn コマンドを入れるような Dockerfile にしています。
- Docker Hub へ
GitHub Action で自動で docker push もできました。
今の時代、自動化できるのでいい時代だなと実感しています。
github-actions の設定
- 動作確認
問題の munit
の docs/docusaurusCreateSite
を作った docker image で動作確認してみました。
正常に動作完了して、生成物の確認もできるようになりました。
> docker run -it --rm -v ${PWD}:/work -w /work keyno63/sbt-yarn:1.5-jdk11-alpine sbt docs/docusaurusCreateSite
[info] [launcher] getting org.scala-sbt sbt 1.5.5 (this may take some time)...
...
Site built successfully. Generated files in 'build' folder.
Done in 63.03s.
[success] Total time: 295 s (04:55), completed MM DD, YYYY, hh:mm:ss
捜しているときに見つかったよさそうな image
Docker image を捜している時によさそうなイメージが色々あることに気づいたので、以下で紹介させてもらいます。
その中でも更新が半年以内で sbt バージョンが 1.5 以上のものをあげさせていただいています。
-
hseeberger/scala-sbt
- Docker Hub
- GitHub
- debian や oracle ベースのイメージで、JDK も 8,11,17 から選べるレパートリーが多い.
更新やメンテも頻繁にされていそうです。ただ、alpine ベースのイメージはなさそうでした。
-
westwater/scala-sbt
- Docker Hub
- GitHub
- openjdk11 ベース。 気になる点としては更新が4か月前と少し前。
-
chatworks さん
-
xirc/sbt-scala
- Docker Hub
- GitHub
- イメージは debian ベース
sdkman を使って最新の jdk, scala, sbt が入るようなっていて、github actions で毎週更新されるようにされています。
気になった点は image size が大きいので pull してくる時が重かったです
振り返り
環境依存の少ない開発環境としての、必要な Docker image を得ることができたので大変満足しています。
.ivy2
のキャッシュもマウントの仕方次第で解決できそうなのでローカル環境と変わらない開発体験を実現できそうです。
最後に
JVM のおかげで環境依存の少ない言語でも Docker image があると便利だなと改めて感じました。
良い開発体験を。
Discussion