Docker As a Build Tool

Suppose you want to build a java maven project, but you don't have the correct environment to do so. Or you just don't want to mess up your local machine. You can use docker to do the build without installing JDK or Maven.

We are going to use Spring PetClinic application as a sample for this post. Let's start by checking out the sources from github.

git clone https://github.com/spring-projects/spring-petclinic.git  

Change into the directory.

cd spring-petclinic  

Now for the magic part:

docker run -it --rm -v "$PWD":/work -w /work \  
  maven:3.3.9-jdk-7 mvn package

Here we are running the maven docker image maven:3.3.9-jdk-7. You can choose different java and maven versions from the docker repository according to your project needs. We also added the current directory as a volume mounted to /work.

Docker command will take some time to complete. It will get the container image first, if its not downloaded before. The container just runs mvn package when the image is downloaded and started. Than maven will fetch all its dependencies, run the tests and build the project artifacts. petclinic.war in this case. After the build is complete the container will exit and remove itself (-rm) from the docker server.

Build results will be inside the target directory on your local file system:

$ ls -1 target/
classes  
generated-sources  
generated-test-sources  
maven-archiver  
maven-status  
petclinic  
petclinic.war  
surefire-reports  
test-classes  

Persistent Maven Repository

Above procedure can be optimized by making the maven repository persistent between further runs. You'll save loads of time and bandwith by not downloading all the dependencies for every build.

Docker volumes to the rescue.

docker volume create --name m2repo  

And add this volume when running the container.

docker run -it --rm -v "$PWD":/work -v m2repo:/root/.m2 -w /work \  
  maven:3.3.9-jdk-7 mvn package

only difference here is the second -v parameter that maps the volume we just created to /root/.m2 directory.

This optimization dropped the build time to 90 seconds from 200 seconds on my old mac with a decent network.