SpringBootで実装したアプリケーションのDockerイメージをビルドします。
今回はDockerコマンドを直接叩くのではなくgradleを経由させる感じ。
前提
product | version |
---|---|
spring-boot | 2.3.0 |
Gradle | 6.3 |
Docker Engine | 19.03.5 |
各種ファイルの配置はこんな感じ。
root
+- src
+- Dockerfile
+- build.gradle
...
Dockerfile
の作成
作成した Dockerfile
はこんな感じ。
FROM openjdk:8-jdk-alpine
ENV JAVA_OPTS = "-Dspring.profiles.active=dev"
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT [ "sh", "-c", "java ${JAVA_OPTS} -jar /app.jar" ]
今回はデプロイ環境によってDBの接続先等も変えれるようにしたいので
ENV JAVA_OPTS = "-Dspring.profiles.active=dev"
を追加。(詳細はここでは省略しますがspringではjavaの起動オプションで環境ごとの切り替えができます)
build.gradle
へ追記
続いて以下を追記。
今回使用するのはこちらのプラグイン。
https://github.com/palantir/gradle-docker
plugins {
...
id 'com.palantir.docker' version '0.25.0'
}
...
docker {
name "${name}:${version}"
files bootJar.archiveFile.get()
dockerfile file('./Dockerfile')
buildArgs(['JAR_FILE': "${jar.archiveFileName.get()}"])
}
キーポイントはこの1行。
files bootJar.archiveFile.get()
これがないとイメージビルド時に以下のように怒られます。
> Task :application:docker FAILED
COPY failed: stat /var/lib/docker/tmp/docker-builder605201568/app-0.0.1-SNAPSHOT.jar: no such file or directory
前述の Dockerfile
にて COPY
タスクを実行しようとしたときに、jarファイルが見つからないため怒られています。
なので、 files()
メソッドを使って build/docker
以下に生成したjarファイルをコピーしてあげます。
(build
以下に docker
ディレクトリを生成しそこをワーキングディレクトリとしているみたいなので、そのワーキングディレクトリへのjarファイルのコピー作業が必要)
また、
buildArgs(['JAR_FILE': "${jar.archiveFileName.get()}"])
では、Dockerfile
内の JAR_FILE
引数へ生成したjarファイル名を引き渡しています。
ちなみにですが、
dockerfile file('./Dockerfile')
は build.gradle
と同階層に Dockerfile
を配置している場合は特に指定不要です。(つまり今回の場合は書かなくてもよい)
別途ディレクトリを切ってそこに Dockerfile
を入れてる、などの場合はそのパスを指定しましょう。
いざビルド
イメージのビルドは簡単。以下を実行するだけ。
Docker起動しておくのを忘れずに。
// build jar.
$ ./gradlew build
// build docker image.
$ ./gradlew docker
これでイメージのビルドが完了します。
(このとき、build
ディレクトリ以下にdocker
ディレクトリが生成されており、その中に Dockerfile
と生成されたjarがコピーされていることがわかるかと思います)
docker images
コマンドでイメージが生成されていることも確認しましょう。
動かす
イメージのビルドが完了したら、runしてみましょう。
$ docker run --env JAVA_OPTS="-Dspring.profiles.active=dev" ${name}:${version}
無事起動できます。
序盤に書きましたが、環境ごとで接続先等を変えたい場合は、
--env JAVA_OPTS="-Dspring.profiles.active=dev"
をオプション指定して適宜prod
などを指定してあげればOKです。
Registryへプッシュ
作成したイメージを今回はDockerHubへpushします。これも簡単。
docker login を忘れずに。
$ ./gradlew dockerPush
おわり
こんな感じで、Gradleプラグイン経由で簡単にDockerイメージをビルドできました。
細かい部分については言及していませんが、最小パターンでやるにはこんな感じで充分かと思います。