Docker+Mavenで、テスト時にDockerコンテナを起動してテストして…みたいなことを、そういえばやったことが
ないなぁと思いまして。
いつも、わりかしふつうにdocker runしてます。
で、MavenでDockerを使うプラグインの情報をなんか見たことがあったので、軽く調べて試してみました。
今回は、docker-maven-pluginを使います。
https://github.com/fabric8io/docker-maven-plugin
ドキュメントはこちら。
docker-maven-plugin/intro.md at master · fabric8io/docker-maven-plugin · GitHub
docker-maven-pluginを使用するには、Mavenが使えることというのはさることながら、Dockerが
インストールされている、もしくはDocker APIが使えるホストにアクセスできる必要があるという
感じのようです。
このプラグインでできそうなこととして、docker build、run、stop、removeなど、Dockerのコマンドを使った
相応のこと(あと、Docker Composeまで)いろいろできそうですが、ビルドとかはふつうにdocker buildで
いいかなぁと思っているので、今回はrunとstopにフォーカスしてみました。
Docker Compose)
Docker Compose
では、試してみましょう。
お題
今回は、RedisのDockerイメージを使って、Integration Test時にRedisを起動、終了時にコンテナを停止する
といった使い方をしてみます。
RedisのDockerイメージは、こちら。
あとは、テスト中にJedisを使ってRedisへアクセスしてみましょう、と。
準備
Integration Testで使うというのと、そもそもdocker-maven-pluginだという話なので、まずはMavenの
プラグイン設定から書いていきます。
<plugins> <plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.20.0</version> <configuration> <images> <image> <alias>redis-server</alias> <name>redis:3.2.8</name> <run> <!-- docker:start --> <namingStrategy>alias</namingStrategy> <ports>6379:6379</ports> </run> </image> </images> <!-- docker:stop --> <keepContainer>false</keepContainer> </configuration> <executions> <execution> <id>start</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> </goals> </execution> <execution> <id>stop</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.19.1</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> </plugins>
maven-failsafe-pluginはまあいいとして、docker-maven-pluginについては利用するDockerイメージの設定や
runコマンドで指定するオプションなどを書いていきます。こちらは、またあとで。
Maven Failsafe Plugin – Introduction
依存ライブラリとしては、Jedis、JUnit、AssertJを用意。
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.6.2</version> <scope>test</scope> </dependency>
テストコードの準備と確認
動作確認に使用したテストコードは、こちら。Integration Testなので、テストクラス名は「〜IT」
としています。
src/test/java/org/littlewings/docker/DockerMavenPluginIT.java
package org.littlewings.docker; import java.util.concurrent.TimeUnit; import org.junit.Test; import redis.clients.jedis.Jedis; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; public class DockerMavenPluginIT { @Test public void jedisGettingStarted() { Jedis jedis = new Jedis("localhost"); assertThat(jedis.get("key")) .isNull(); jedis.set("key", "value"); assertThat(jedis.get("key")) .isEqualTo("value"); } }
確認は、「mvn verify」で。
$ mvn verify
実行すると、pre-integration-testでRedisを起動し、post-integration-testでRedisを停止してくれます。
[INFO] --- docker-maven-plugin:0.20.0:start (start) @ docker-maven-plugin-example --- [INFO] DOCKER> [redis:3.2.8] "redis-server": Start container fec538d2c43e [INFO] [INFO] --- maven-failsafe-plugin:2.19.1:integration-test (default) @ docker-maven-plugin-example --- ------------------------------------------------------- T E S T S ------------------------------------------------------- Running org.littlewings.docker.DockerMavenPluginIT Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.162 sec - in org.littlewings.docker.DockerMavenPluginIT Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] --- docker-maven-plugin:0.20.0:stop (stop) @ docker-maven-plugin-example --- [INFO] DOCKER> [redis:3.2.8] "redis-server": Stop and removed container fec538d2c43e after 0 ms
この部分ですね。
[INFO] DOCKER> [redis:3.2.8] "redis-server": Start container fec538d2c43e [INFO] DOCKER> [redis:3.2.8] "redis-server": Stop and removed container fec538d2c43e after 0 ms
OKそうですね。
docker-maven-pluginについて
で、docker-maven-plugin自体については、さらっと流してしまいました。そのあたりを見ていきましょう。
今回利用したのは、docker:startとdocker:stopです。
設定としては、ごった煮で書いている感じもしますが、それぞれ見ていきましょう。今回書いた設定を再度書くと、こちらです。
<plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.20.0</version> <configuration> <images> <image> <alias>redis-server</alias> <name>redis:3.2.8</name> <run> <!-- docker:start --> <namingStrategy>alias</namingStrategy> <ports>6379:6379</ports> </run> </image> </images> <!-- docker:stop --> <keepContainer>false</keepContainer> </configuration> <executions> <execution> <id>start</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> </goals> </execution> <execution> <id>stop</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin>
共通的な話としては、イメージ自体の記述はこんな感じで書くみたいですよ。Dockerイメージを複数書いても
いいみたいです。
<configuration> <images> <image> <name>[利用するDockerイメージ]</name> <run> <!-- 設定 --> </run> <!-- 設定 --> </image> <image> ... </image> </images> </configuration>
どのような設定が可能かは、各種ゴールを見ていくことになります。
docker:start
docker:startゴールは、pre-integration-testフェーズで実行するように設定して、このタイミングでコンテナを
起動させています。
<execution> <id>start</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> </goals> </execution>
コンテナに対する設定自体は、こちらを見て書いていきます。
今回は、ports(-p相当)と、コンテナ名を設定しておきました。こちらと
<ports>6379:6379</ports>
aliasとnamingStrategyですね。
<alias>redis-server</alias> <name>redis:3.2.8</name> <run> <!-- docker:start --> <namingStrategy>alias</namingStrategy>
多くの設定は、runタグ内に書くことになります。詳細は、ドキュメントを…。
docker:stop
docker:stopは、あまり設定がありません。まずは、post-integration-test時にコンテナを停止するように設定。
<execution> <id>stop</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution>
設定は、今回keepContainer(stop時に、コンテナを削除するか)を指定して、stop時にコンテナを削除するように
しています…が、デフォルトがfalseなので、実は書かなくても意味は同じだったりします。
<!-- docker:stop --> <keepContainer>false</keepContainer>
まあ、configurationタグ配下に書いて設定する、ということで。
設定をどこに書くかにちょっと悩んだりするのですが、ひとつ場所がわかればあとはドキュメント上での同じ並びの
項目は同じような場所に書いていくことになるので、そう困らないと思います。