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.