gradle-dockerプラグインでDockerfileをビルド時に生成する
前回の続き。要改善点を退治していきます。
mao-instantlife.hatenablog.com
【おさらい】要改善なところ
- プラグインのGlobal configurationに
registry
を指定するための項目があるが、リポジトリ名生成で反映されている感じがしないので確認してみる - Dockerfileにバージョン入ってるのではまりそう。プラグインからDockerfile生成できるはずなのでもうちょっと頑張る
- buildタスクはテストが走るので、今の
circle.yml
だとテストが2回走る。build時はテストトラップしたい
ビルド時にテストをスキップするところは、 circle.yml
の buildDocker
タスク実行時に -x test
つければ良いだけの話だったので、gradleもっと勉強しろ、で終了な話でした。
registry
項目でハマる
前回、
最初のやつは試しかけてたんですが、buildDockerタスクが突然無言になったのでちょっと後日に回します。
と書いていましたが、なんで無言になったんでしょうねえ。。。どうもローカルのdockerホストにはイメージが作られているみたいなので確認してみます。
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE tutum.co/tutum-private-sample 1.3-SNAPSHOT 597ce97c7755 2 minutes ago 668.6 MB shinsukeabe/tutum-private-sample 1.3-SNAPSHOT e9804acf2a95 17 hours ago 668.6 MB tutum.co/shinsukeabe/tutum-private-sample 1.0-SNAPSHOT ea5233a18ba7 19 hours ago 668.6 MB tutum.co/shinsukeabe/tutum-private-sample 1.1-SNAPSHOT ea5233a18ba7 19 hours ago 668.6 MB java 8 de4a13c84f53 6 days ago 641.9 MB java latest de4a13c84f53 6 days ago 641.9 MB
registry
にtutum.co
と指定したときに無言になった後のイメージです。明らかに怪しい奴がいますね。。。 tutum.co/tutum-private-sample
とか。期待していたのは registry/group
の状態で生成されることだったのですが、 registry
を指定するとリポジトリの生成時に group
が無視されてしまうようです。つまりアプローチとしては以下のどちらか。
group
をサーバ名/ユーザ名
にするかregistry
をサーバ名/ユーザ名
にするか
各設定の役割から考えたら明らかに後者ですね。とりあえず今のイメージ消してやってみると無言になることもなくうまくpushできました。どうやらリポジトリのユーザを指定できていない状態でpushしようとしていたからTutumに弾かれていたようです。というか1時間だんまりとかやめて、エラーで落として。
というわけで最終的なbuild.gradleは以下のような感じに。
group "shinsukeabe" version '1.3-SNAPSHOT' buildscript { ext { springBootVersion = "1.3.0.RELEASE" } repositories { mavenCentral() jcenter() } dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" classpath 'se.transmode.gradle:gradle-docker:1.2' } } apply plugin: 'java' apply plugin: 'idea' apply plugin: 'spring-boot' apply plugin: 'docker' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: "${springBootVersion}" testCompile group: 'junit', name: 'junit', version: '4.11' } task buildDocker(type: Docker, dependsOn: build) { push = true applicationName = jar.baseName registry = “${System.getenv()[’TUTUM_URL’]/shinsukeabe" baseImage 'java:8' volume "/tmp" addFile "${applicationName}-${version}.jar", "app.jar" runCommand "bash -c 'touch /app.jar'" entryPoint(["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]) doFirst { copy { from jar into stageDir } } }
gradle-docker
プラグインを使ってDockerfileを生成する
先ほどの build.gradle
は、 gradle-docker
プラグインを使ったDockerfileの生成にも対応しています。Dockerfileの各設定項目に対応するメソッドは用意されているので、ドキュメントを見ながら先に作ったDockerfileの項目とマッピングしただけです。
アプリケーションのjarファイルを addFile
している箇所について相対パスも指定していないので少し補足。 gradle-docker
プラグインでdockerコマンドを実行する際のワーキングディレクトリが build/docker
で、そこにDockerfileが出力されます。 doFirst
で実行しているコピーでビルドしたjarファイルがワーキングディレクトリである build/docker
にコピーされるので、 addFile
の指定はファイル名のみで構いません。
アプリケーションのjarファイル名は applicationName
と定義済みのバージョンでbuild.gradeに定義した内容が生成されるようにしてます。なんかバージョンまで含めたjarファイル名が取得できそうな気がするけど、どれがそうなのかよくわかりませんでした。。。
なお、 entryPoint
はリストが引数となるメソッドなのですが、カッコを省略すると読み込み専用フィールドへのアクセスと解釈されてビルド時にエラーになったためカッコをつけています。
よしよし、これでDockerfileは不要となりました。
まとめ
早くTutumの料金プランが発表にならないかなあ。Github -> CircleCI -> Tutumという流れが楽すぎる。
リポジトリです。ご査収ください。