How to create docker image in Spring Boot project - spring

I have tried using spotify/docker-maven-plugin without any success .
Below is part of my pom.xml file
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${dockerfile-maven-version}</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>myrepo/maven-docker-spotify</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}-jar-with-dependencies.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>

The spotify/docker-maven-plugin you are using is currently inactive. It's recommended using spotify/dockerfile-maven-plugin instead.
So change the plugin section of your pom.xml file to resemble below
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-maven-version}</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>spotify/foobar</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
Note: You can also try using JIB maven plugin that doesnt require you to have docker installed and works with minimal configuration. With JIB, Running below command in is enough to do the jo
mvn compile com.google.cloud.tools:jib-maven-plugin:0.9.2:dockerBuild

Related

Quarkus: maven deploy the runner jar

I need to deploy the quarkus runner jar from maven, however with a basic mvn deploy it only deploys the usual .jar and the .pom.
I tried the following plugin:
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<executions>
<execution>
<id>deploy-executable</id>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<file>quarkus/target/quarkus-1.0-SNAPSHOT-runner.jar</file>
</configuration>
</execution>
</executions>
</plugin>
But it seems that it cannot work this way (file name should be provided in the command line, which is not what I need).
Is there an easy way to deploy the runner jar? Also for a native image?
You can use the builder-helper-maven-plugin like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}-runner.jar</file>
<classifier>runner</classifier>
<type>jar</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>

Tagging created image with dockerfile-maven-plugin

I am using dockerfile-maven-plugin with the following configuration:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.6</version>
<executions>
<execution>
<id>build-image</id>
<goals>
<goal>build</goal>
</goals>
<configuration>
<tag>latest</tag>
<repository>root/${project.artifactId}</repository>
<buildArgs>
<APP_NAME>${project.artifactId}</APP_NAME>
</buildArgs>
</configuration>
</execution>
<execution>
<id>push-image</id>
<goals>
<goal>push</goal>
</goals>
<configuration>
<repository>${docker.registry.url}/root/${project.artifactId}</repository>
</configuration>
</execution>
</executions>
</plugin>
Project deployment fails due to:
[INFO] The push refers to a repository [my-repository:9090/root/image-name]
[ERROR] An image does not exist locally with the tag: my-repository:9090/root/image-name
[WARNING] An attempt failed, will retry 1 more times
org.apache.maven.plugin.MojoExecutionException: Could not push image
.
.
.
Prefixing the repository under the build goal (in similar way to push goal) solves the issue. But then the locally created image prefixed with the repository tag.
Didn't find any documentation reference on how to perform the tag before push task.
In other words, I want that my local docker images will contain 2 images after plugin execution:
REPOSITORY TAG IMAGE ID CREATED SIZE
root/image-name latest 7ac1144c607e 21 minutes ago 175MB
my-repository:9090/root/image-name latest 7ac1144c607e 21 minutes ago 175MB
My docker version is: 17.06.0-ce
We didn't want to build all over again even if existing docker layers would be used. In the first execution we build and push and in the second execution we just tag and push.
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-maven-plugin.version}</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
<configuration>
<tag>${build.number}</tag>
</configuration>
</execution>
<execution>
<id>default-2</id>
<goals>
<goal>tag</goal>
<goal>push</goal>
</goals>
<configuration>
<tag>latest</tag>
</configuration>
</execution>
</executions>
<configuration>
<repository>${docker-remote.registry}/path/${project.version.lowercase}</repository>
<buildArgs>
<EAR_FILE>${project.build.finalName}.ear</EAR_FILE>
</buildArgs>
<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
</configuration>
</plugin>
</plugins>
</build>
Adding additional execution step to my configuration solved the issue:
<execution>
<id>tag-image</id>
<phase>deploy</phase>
<goals>
<goal>tag</goal>
</goals>
<configuration>
<repository>${docker.registry.url}/root/${project.artifactId}</repository>
</configuration>
</execution>
You can also tag your image manually after a successful build with
mvn dockerfile:tag -Dproject.plugin.dockerfile.tag=my-repository:9090/root/image-name

use different configurations for different maven plugin goals

I've seen maven plugins setting configurations tied to goals. I'd like to do that with my tomcat7-maven-plugin. However, this doesn't seem to work; when I run deploy it's defaulting to localhost. Does this plugin not accept different configs or am I doing something wrong?
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>deploy</id>
<goals>
<goal>deploy</goal>
<goal>redeploy</goal>
</goals>
<configuration>
<url>${tomcat-manager-url}/manager/text</url>
<username>${tomcat-manager-username}</username>
<password>${tomcat-manager-password}</password>
<path>/${project.artifactId}1</path>
</configuration>
</execution>
<execution>
<id>run</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<path>/</path>
</configuration>
</execution>
</executions>
</plugin>

Inegration test using maven

I am trying to create something like integration tests - i am using groovy to send requests and to parse answers. I'd also want starting of jboss and deploying of .ear to be automatically. Using cargo plugin i was able to start jboss. By using exec plugin i am trying to execute perl script that puts ear to deploy folder. Next phase - execute groovy tests, but this phase starts without waiting for ear to be deployed. Is it possible to make phase to wait for server to be deployed to jboss? My pom:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<id>unpack-application-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>${basedir}/src/main/script/appserver/unzip.groovy</source>
<defaults>
<installDirectory>${appserver.install.directory}</installDirectory>
<zipUrl>${appserver.zip.url}</zipUrl>
</defaults>
</configuration>
</execution>
<execution>
<id>prepare-application-server-configs</id>
<phase>pre-integration-test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>${basedir}/src/main/script/appserver/${suffix}/postUnzipAction.groovy</source>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
</executions>
<configuration>
<wait>false</wait>
<container>
<containerId>${appserver.id}</containerId>
<home>${appserver.home}</home>
<timeout>6000000</timeout> <!--in ms-->
</container>
<configuration>
<properties>
<cargo.servlet.port>${servlet.port}</cargo.servlet.port>
<cargo.rmi.port>${rmi.port}</cargo.rmi.port>
<!-- corresponds to -Djboss.bind.address=0.0.0.0 under jboss -->
<cargo.hostname>0.0.0.0</cargo.hostname>
</properties>
</configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>deploy-with-script</id>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>perl</executable>
<workingDirectory>.</workingDirectory>
<commandlineArgs>${deploy.pl.cmd} -x redeploy</commandlineArgs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
setup and tear down your server before and after integration test phase, something like that:
<executions>
<execution>
<id>start-tomcat</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>stop-tomcat</id>
<phase>post-integration-test</phase>
<goals>
<goal>shutdown</goal>
</goals>
</execution>
</executions>
Rename your unit tests to be skipped by surefire but executed by maven-failsave-plugin to *IT.java: http://maven.apache.org/surefire/maven-failsafe-plugin/examples/inclusion-exclusion.html

Install Maven itself from Maven Central

I have a maven plugin I would like to test against different Maven versions (Ex.: 2.2.1 & 3.0.4). Ideally I don't want users running the build to have to install these exact versions manually.
Is it possible to install specific versions of Maven itself from Maven Central or some other source that would then cache them in the local Maven repo for subsequent builds?
Maven distributions are stored in Maven Central Repository, as you can see here:
http://mvnrepository.com/artifact/org.apache.maven/apache-maven
https://repository.sonatype.org/index.html#nexus-search;gav~org.apache.maven~apache-maven~~~~kw,versionexpand
Therefore, it can be used as a normal dependency with following coordinates:
tar.gz variant:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>apache-maven</artifactId>
<version>3.0.4</version>
<classifier>bin</classifier>
<type>tar.gz</type>
</dependency>
zip variant:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>apache-maven</artifactId>
<version>3.0.4</version>
<classifier>bin</classifier>
<type>zip</type>
</dependency>
The rest is quite standard - you will probably use it in integration test poms, and call them with maven-invoker-plugin as recommended by #khmarbaise.
Why don't you simply just install a Continuous Integration (CI) server such as Jenkins / Hudson / TeamCity / etc? CI servers allow you to run your build against different versions of an SDK.
If your plugin is OSS (and on GitHub), I believe you can get free Jenkins hosting from Cloudbees.
Downloading Maven itself from Maven Central is not possible. You can only download it from their site.
You could do a thing like the following:
<profile>
<id>run-its</id>
<build>
<!-- Download the different Maven versions -->
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0-beta-3</version>
<executions>
<execution>
<id>download-maven-2.0.11</id>
<phase>prepare-package</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>http://archive.apache.org/dist/maven/binaries/</url>
<fromFile>apache-maven-2.0.11-bin.tar.gz</fromFile>
<toDir>${project.build.directory}/maven/download/</toDir>
</configuration>
</execution>
<execution>
<id>download-maven-2.2.1</id>
<phase>prepare-package</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>http://archive.apache.org/dist/maven/binaries/</url>
<fromFile>apache-maven-2.2.1-bin.tar.gz</fromFile>
<toDir>${project.build.directory}/maven/download/</toDir>
</configuration>
</execution>
<execution>
<id>download-maven-3.0.3</id>
<phase>prepare-package</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>http://archive.apache.org/dist/maven/binaries/</url>
<fromFile>apache-maven-3.0.3-bin.tar.gz</fromFile>
<toDir>${project.build.directory}/maven/download/</toDir>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<version>1.0-beta-4</version>
<executions>
<execution>
<id>extract-maven-2.0.11</id>
<goals>
<goal>copy</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<fileset>
<directory>${project.build.directory}/maven/download/apache-maven-2.0.11-bin.tar.gz</directory>
<outputDirectory>${project.build.directory}/maven/tools/</outputDirectory>
</fileset>
</configuration>
</execution>
<execution>
<id>extract-maven-2.2.1</id>
<goals>
<goal>copy</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<fileset>
<directory>${project.build.directory}/maven/download/apache-maven-2.2.1-bin.tar.gz</directory>
<outputDirectory>${project.build.directory}/maven/tools/</outputDirectory>
</fileset>
</configuration>
</execution>
<execution>
<id>extract-maven-3.0.3</id>
<goals>
<goal>copy</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<fileset>
<directory>${project.build.directory}/maven/download/apache-maven-3.0.3-bin.tar.gz</directory>
<outputDirectory>${project.build.directory}/maven/tools/</outputDirectory>
</fileset>
</configuration>
</execution>
</executions>
</plugin>
<!--
This is currently needed due to a bug of the truezip-plugin cause it unpacks without permission!
see http://jira.codehaus.org/browse/MOJO-1796
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>chmod-files</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<chmod file="${project.build.directory}/maven/tools/apache-maven-2.0.11/bin/mvn" perm="+x"/>
<chmod file="${project.build.directory}/maven/tools/apache-maven-2.2.1/bin/mvn" perm="+x"/>
<chmod file="${project.build.directory}/maven/tools/apache-maven-3.0.3/bin/mvn" perm="+x"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>1.8.4</version>
</dependency>
</dependencies>
<configuration>
<debug>false</debug>
<!-- src/it-ip as for integration tests invoker plugin for the time of transition to maven-invoker-plugin -->
<projectsDirectory>src/it</projectsDirectory>
<showVersion>true</showVersion>
<pomIncludes>
<pomInclude>*/pom.xml</pomInclude>
</pomIncludes>
<preBuildHookScript>setup</preBuildHookScript>
<postBuildHookScript>verify</postBuildHookScript>
<settingsFile>src/it/settings.xml</settingsFile>
</configuration>
<executions>
<execution>
<id>integration-test-maven-2.0.11</id>
<goals>
<goal>install</goal>
<goal>run</goal>
</goals>
<configuration>
<reportsDirectory>${project.build.directory}/invoker-reports-2.0.11</reportsDirectory>
<localRepositoryPath>${project.build.directory}/local-repo-2.0.11</localRepositoryPath>
<cloneProjectsTo>${project.build.directory}/it-2.0.11</cloneProjectsTo>
<mavenHome>${project.build.directory}/maven/tools/apache-maven-2.0.11</mavenHome>
<goals>
<goal>clean</goal>
<goal>test</goal>
</goals>
</configuration>
</execution>
<execution>
<id>integration-test-maven-2.2.1</id>
<goals>
<goal>install</goal>
<goal>run</goal>
</goals>
<configuration>
<reportsDirectory>${project.build.directory}/invoker-reports-2.2.1</reportsDirectory>
<localRepositoryPath>${project.build.directory}/local-repo-2.2.1</localRepositoryPath>
<cloneProjectsTo>${project.build.directory}/it-2.2.1</cloneProjectsTo>
<mavenHome>${project.build.directory}/maven/tools/apache-maven-2.2.1</mavenHome>
<goals>
<goal>clean</goal>
<goal>test</goal>
</goals>
</configuration>
</execution>
<execution>
<id>integration-test-maven-3.0.3</id>
<goals>
<goal>install</goal>
<goal>run</goal>
</goals>
<configuration>
<reportsDirectory>${project.build.directory}/invoker-reports-3.0.3</reportsDirectory>
<localRepositoryPath>${project.build.directory}/local-repo-3.0.3</localRepositoryPath>
<cloneProjectsTo>${project.build.directory}/it-3.0.3</cloneProjectsTo>
<mavenHome>${project.build.directory}/maven/tools/apache-maven-3.0.3</mavenHome>
<goals>
<goal>clean</goal>
<goal>test</goal>
</goals>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
This will download the different Maven version unpack the .tar.gz archives and make mvn executable and use maven-invoker-plugin to run all integration test with these different maven versions.
BUT i can't recommend that. The better way is to use a CI solution (as already mentioned) which contains the different installations of Maven. Than you can run the integration tests for each Maven version separately.

Resources