気軽に使えるScalaのsbt環境をDockerでスクリプト化したので、そのご紹介です。
背景
sbtのDockerイメージとして以下のものが多く利用されているように見えます。
hseeberger/scala-sbt - Docker Image | Docker Hub
しかし、sbtのバージョンが少し古くてメンテされていないように見えます。
また、このイメージを使って単純に docker run -it --rm hseeberger/scala-sbt:... sbt run
などとすると、キャッシュが引き継がれず毎回ダウンロードから始まってしまいます。以下のようなメッセージが毎回出てしまうのです。
copying runtime jar...
[info] [launcher] getting org.scala-sbt sbt 1.9.0 (this may take some time)...
[info] [launcher] getting Scala 2.12.18 (for sbt)...
そこで、Dockerイメージとそのラッパーとなるシェルスクリプトを書いて、キャッシュが引き継がれる、気軽に使えるsbt環境を作ってみました。
ソースコードは以下に置きました。
各ファイルの説明
docker-run.sh
ラッパースクリプト本体です。次のように使います。
$ bash PATH-TO-scala-docker/docker-run.sh sbt run
またはパラメータを省略するとsbtが実行され、インタラクティブモードになります。
$ bash PATH-TO-scala-docker/docker-run.sh
以下の部分は、Dockerイメージがまだビルドされていなかったらビルドする処理です。
if [ -z "$(docker images -q $docker_image_name)" ]; then
bash $(dirname $0)/docker-build.sh
fi
以下の部分は、ホスト環境でのユーザでsbtを実行するために、ホスト環境のユーザ情報をDockerの中に渡すための情報取得です。
user=$(whoami)
uid=$(id -u $user)
gid=$(id -g $user)
Dockerにはdocker run
の以下のオプションでユーザ情報を渡しています。そして、この変数はentrypoint.sh
で参照しています。
-e HOST_UID=$uid -e HOST_GID=$gid -e HOST_USER=$user
以下の部分は、sbtが使うさまざまなキャッシュを置くためのディレクトリを作成します。このスクリプトはプロジェクトのディレクトリで実行することを想定し、キャッシュディレクトリを実行時のカレントディレクトリに作成しています。このスクリプトをそのまま使うのであれば、各プロジェクトの .gitignore
に .sbt-docker-cache
を追加する必要があります。
mkdir -p .sbt-docker-cache/.sbt
mkdir -p .sbt-docker-cache/.cache
このディレクトリをsbtから使わせるためにdocker run
に以下のオプションを渡しています。
-v $(pwd)/.sbt-docker-cache/.sbt:$HOME/.sbt -v $(pwd)/.sbt-docker-cache/.cache:$HOME/.cache"
docker-build.sh
このスクリプトはDockerイメージをビルドします。手動で実行しても大丈夫ですが、初回のdocker-run.sh
実行時に自動で呼び出されます。
単にdocker build
しているだけです。
Dockerfile
この中でJava、Scala、sbtをインストールしています。sbtのほかにScala単独でもインストールしているため、以下のようにすればScalaインタプリタが動きます。
$ bash PATH-TO-scala-docker/docker-run.sh scala
entrypoint.sh
このファイルはdocker-run.sh
の中のdocker run
起動時のエントリポイントとして指定されています。コンテナの中で最初に実行されるスクリプトです。
以下の部分はホスト側と同じユーザをDockerの中で作成するためのコードです。
groupadd -g $HOST_GID -o $HOST_USER
useradd -u $HOST_UID -g $HOST_GID -o $HOST_USER
usermod -aG sudo $HOST_USER
export HOME=/home/$HOST_USER
chown $HOST_USER $HOME
そのあとで su
でrootからこのユーザにスイッチして、sbtコマンドを実行します。
以上。