How to hot deploy Java EE applications in Docker containers How to hot deploy Java EE applications in Docker containers docker docker

How to hot deploy Java EE applications in Docker containers


I know this question is a little old but I want to share my knowledge about how to develop java EE apps with a tomee server in Docker.

Preparing the Docker image

The first thing to do is to enable logging. I use the official base image and redirect the logs to stdout in order to see it on my console:

# you can change the base image of courseFROM tomee:8-jre-1.7.5-jaxrsRUN ln -s /dev/stdout /usr/local/tomee/logs/catalina.out RUN echo '<?xml version="1.0" encoding="utf-8"?><tomcat-users><role rolename="tomee-admin"/><user username="tomee" password="tomee" roles="tomee-admin,manager-gui,manager-script"/></tomcat-users>' > /usr/local/tomee/conf/tomcat-users.xml

The log addition may not seem like a big deal but it is. With this enabled, you are able to see the success (or failure) of your deployment imediately.The ugly xml snippet is actually very important. It enables a user named tomee with all important permissions to deploy applications.

You can build the image with ordinary docker tooling:

docker build -t tomee-dev .

Preparing the development environment

I use a standard maven directory layout. Here is an example:

pom.xmlsrc | - main    |    - java    |   |    |   - boundary    |        |    |        - TestResource.java    - webapp        |        - WEB-INF            |            - web.xml

The content of those files can be found at the bottom of this answer.

Start the container like this:

docker run -it --rm -p 8080:8080 tomee-dev

The last piece of the puzzle is our maven configuration. You can use the tomee maven plugin for redeployment

<build>    <plugins>        <plugin>            <groupId>org.apache.tomcat.maven</groupId>            <artifactId>tomcat7-maven-plugin</artifactId>            <version>2.2</version>            <configuration>                <url>http://localhost:8080/manager/text</url>                <username>tomee</username>                <password>tomee</password>                                    <path>/${project.artifactId}</path>            </configuration>        </plugin>    </plugins></build>

You can now use mvn clean tomcat7:deploy and mvn clean tomcat7:redeploy commands to deploy/redeploy your application.

Appendix

here is the content of the source and config files I used in the example:

src/main/java/boundary/TestResource.java

import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.core.Response;@Path("/")public class TestResource {    @GET    @Path("test")    public Response test1() {        return Response.ok("this is a test").build();    }}

src/main/java/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"         version="3.0">    <module-name>hot-deploy</module-name>    <servlet>        <servlet-name>javax.ws.rs.core.Application</servlet-name>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>javax.ws.rs.core.Application</servlet-name>        <url-pattern>/resources/*</url-pattern>    </servlet-mapping></web-app>

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <artifactId>hot-reload</artifactId>    <groupId>org.test.stackoverflow.answers</groupId>    <version>1.0.0-snapshot</version>    <packaging>war</packaging>    <properties>        <maven.compiler.source>1.8</maven.compiler.source>        <maven.compiler.target>1.8</maven.compiler.target>        <tomee-plugin.pwd>tomee</tomee-plugin.pwd>        <tomee-plugin.user>tomee</tomee-plugin.user>    </properties>    <dependencies>        <dependency>            <groupId>javax</groupId>            <artifactId>javaee-api</artifactId>            <scope>provided</scope>            <version>7.0</version>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.apache.tomcat.maven</groupId>                <artifactId>tomcat7-maven-plugin</artifactId>                <version>2.2</version>                <configuration>                    <url>http://localhost:8080/manager/text</url>                    <username>tomee</username>                    <password>tomee</password>                                        <path>/${project.artifactId}</path>                </configuration>            </plugin>        </plugins>    </build></project>


If you mount the host's volume to a few containers read-only, make sure tomcat does not "explode" the war files, at least not to the same folder, then I think you have the hot-deployment, at least to the level tomcat can support. Replacing the .war file in the host folder should trigger a redeploy.