Build and push your application in a container image

The image goal allows you to build an application image that contains a server and your application. This application image contains your application ready to run on the cloud in a containerized platform such as Kubernetes.

The operations related to the image are executing using a Docker binary. This can be explicitly set with the <image><docker-binary> element. It can also be overridden with the wildfly.image.binary property. If no binary is defined in the configuration, an attempt will be made to determine a default binary. First docker is attempted to be resolved. If it cannot be resolved, then podman is attempted. If neither can be resolved an error will occur.

By default, the image goal will only build the application image. To push it to a container registry, you must configure the <image><push> element with to true.

Build an application image

The example below shows how to build an application image.

<project>
    <artifactId>my-app</artifactId>
    ...
    <build>
        ...
        <plugins>
            ...
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>4.2.2.Final</version>
                <configuration>
                    <feature-packs>
                        <feature-pack>
                            <!-- Latest released version -->
                            <location>wildfly@maven(org.jboss.universe:community-universe)</location>
                        </feature-pack>
                    </feature-packs>
                    <layers>
                        <!-- Galleon layer allows to trim the installed server to your needs. The 'jaxrs-server' 
                        contains the server content required to execute JAXRS applications -->
                        <layer>jaxrs-server</layer>
                    </layers>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>image</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            ...
        </plugins>
        ...
    </build>
...
</project>

Once mvn package is executed, a container image is available in with the docker binary with the name my-app:latest. The name of the image is based on the <artifactId> value of the Maven module.

You can then run the image locally using Docker:

docker run -p 8080:8080 my-app:latest

Push an application image to a container registry.

The example below shows how to configure the image goal to push the applicaition image to a container registry:

<project>
    <artifactId>my-app</artifactId>
    ...
    <build>
        ...
        <plugins>
            ...
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>4.2.2.Final</version>
                <configuration>
                    <feature-packs>
                        <feature-pack>
                            <location>wildfly@maven(org.jboss.universe:community-universe)</location>
                        </feature-pack>
                    </feature-packs>
                    <layers>
                        <layer>jaxrs-server</layer>
                    </layers>
                    <image>
                        <push>true</push>
                        <registry>quay.io</registry>
                        <group>${user.name}</group>
                        <user>${user.name}</user>
                        <password>${my.secret.password}</password>
                    </image>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>image</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            ...
        </plugins>
        ...
    </build>
...
</project>

When mvn package is executed, the image goal will build the image with the name quay.io/jdoe/my-app (jdoe being the name of the user running the Maven commands). Before the image is pushed, it will login to quay.io using the credentials specified by <image><user> and <image><password>. As it is not recommended to store credentials in clear in the pom.xml, we use a System propery (my.secret.password) to pass it when Maven is executed (with `mvn package -Dmy.secret.password=“********”).

Configure the JDK version used by the application image.

The application image is based on a runtime image provided by WildFly that contains all the runtimes required to run WildFly and your application.Push an application image to a container registry. At the moment, WildFly provides runtime images for OpenJDK 11 and OpenJDK 17.

By default, the image goal uses the OpenJDK 11 runtime image. It is possible to use the OpenJDK 17 image instead by configuring the <image><jdk-version> to 17 as shown in the example below:

<project>
    <artifactId>my-app</artifactId>
    ...
    <build>
        ...
        <plugins>
            ...
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>4.2.2.Final</version>
                <configuration>
                    <feature-packs>
                        <feature-pack>
                            <location>wildfly@maven(org.jboss.universe:community-universe)</location>
                        </feature-pack>
                    </feature-packs>
                    <layers>
                        <layer>jaxrs-server</layer>
                    </layers>
                    <image>
                        <jdk-version>17</jdk-version>
                    </image>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>image</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            ...
        </plugins>
        ...
    </build>
...
</project>