Enterprise Java

Java EE, Docker and Maven (Tech Tip #89)

Java EE applicationsĀ are typically built and packaged using Maven. For example,Ā github.com/javaee-samples/javaee7-docker-mavenĀ is a trivial Java EE 7 application and shows the Java EE 7 dependency:

<dependencies>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

And the two Maven plugins thatĀ compiles the source and builds the WAR file:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <source>1.7</source>
        <target>1.7</target>
    </configuration>
</plugin>
<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.3</version>
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>

This application can then be deployed to a Java EE 7 container, such as WildFly, using the wildfly-maven-plugin:

<plugin>
    <groupId>org.wildfly.plugins</groupId>
    <artifactId>wildfly-maven-plugin</artifactId>
    <version>1.0.2.Final</version>
</plugin>

Tests can be invoked using Arquillian, again using Maven. So if you were to package this application as a Docker image and run itĀ inside a Docker container, there should be a mechanism to seamlessly integrate in the Maven workflow.

Docker MavenĀ Plugin

MeetĀ docker-maven-plugin!

This plugin allowsĀ you to manage DockerĀ images and containers from your pom.xml. It comes withĀ predefined goals:

GoalDescription
docker:startCreate and start containers
docker:stopStop and destroy containers
docker:buildBuild images
docker:pushPush images to a registry
docker:removeRemove images from local docker host
docker:logsShow container logs

IntroductionĀ provides a high level introduction to the plugin including building images, running containers and configuration.

Run Java EE 7 Application as Docker ContainerĀ using Maven

TLDR;

  1. CreateĀ and Configure a Docker Machine as explained in Docker Machine to Setup Docker Host
  2. Clone the workspace as: git cloneĀ https://github.com/javaee-samples/javaee7-docker-maven.git
  3. Build the Docker image as: mvn package -Pdocker
  4. Run the Docker container as: mvn install -Pdocker
  5. Find outĀ IP address ofĀ the Docker Machine as: docker-machine ip mydocker
  6. Access your application
    javaee7-docker-maven> curl http://192.168.99.100:8080/javaee7-docker-maven/resources/persons
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?><collection><person><name>Penny</name></person><person><name>Leonard</name></person><person><name>Sheldon</name></person><person><name>Amy</name></person><person><name>Howard</name></person><person><name>Bernadette</name></person><person><name>Raj</name></person><person><name>Priya</name></person></collection>
    

Docker Maven Plugin Configuration

Lets look little deeper in our sample application.

pom.xml is updated to include docker-maven-plugin as:

<plugin>
    <groupId>org.jolokia</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>0.11.5-M1</version>
    <configuration>
        <images>
            <image>
                <alias>user</alias>
                <name>arungupta/javaee7-docker-maven</name>
                <build>
                    <from>arungupta/wildfly:8.2</from>
                    <assembly>
                        <descriptor>assembly.xml</descriptor>
                        <basedir>/</basedir>
                    </assembly>
                    <ports>
                        <port>8080</port>
                    </ports>
                </build>
                <run>
                    <ports>
                        <port>8080:8080</port>
                    </ports>
                </run>
            </image>
        </images>
    </configuration>
    <executions>
        <execution>
            <id>docker:build</id>
            <phase>package</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
        <execution>
            <id>docker:start</id>
            <phase>install</phase>
            <goals>
                <goal>start</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Each image configuration has three parts:

  • Image name and alias
  • <build> that defines how the imageĀ is created. Base image, build artifacts and their dependencies, ports to be exposed, etc to beĀ included in the imageĀ are specified here.Assembly descriptor formatĀ is used to specify the artifacts to be included and is defined in src/main/docker directory. assembly.xml in our case looks like:
    <assembly . . .>
      <id>javaee7-docker-maven</id>
      <dependencySets>
        <dependencySet>
          <includes>
            <include>org.javaee7.sample:javaee7-docker-maven</include>
          </includes>
          <outputDirectory>/opt/jboss/wildfly/standalone/deployments/</outputDirectory>
          <outputFileNameMapping>javaee7-docker-maven.war</outputFileNameMapping>
        </dependencySet>
      </dependencySets>
    </assembly>
    
  • <run> that defines how the container is run. Ports that need to be exposed are specified here.

In addition, package phase is tied to docker:build goal and install phase is tied to docker:start goal.

There are four docker-maven-plugin and you canĀ read more details in theĀ shootout on what serves your purpose the best.

How are you creatingĀ your Docker images from existing applications?

Enjoy!

Arun Gupta

Arun is a technology enthusiast, avid runner, author of a best-selling book, globe trotter, a community guy, Java Champion, JavaOne Rockstar, JUG Leader, Minecraft Modder, Devoxx4Kids-er, and a Red Hatter.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button