![maven install packaging maven install packaging](https://docs.wso2.com/download/attachments/43990609/maven2.png)
This leaves us with images which are much smaller: REPOSITORY TAG IMAGE ID CREATED SIZE We select the -alpine suffix as it's even smaller as the base, to optimize our sizes further. The start of the Dockerfile is basically the same, the only different is that we add another FROM clause to define our final image, and then copy across the build my-project-*.jar file, which we can then run in an image which contains just a JRE. # copy over the built artifact from the maven imageĬOPY -from=maven target/my-project-*.jar. This is fairly easy to change, as follows: # our base build image For the actual runtime, you only require a JRE compatible with the JDK version you built with. There are several options here an easy one being to just flip the base image to maven:3.5-jdk-8-alpine for around a 60% reduction, but the result is still around 336MB.Ī better approach is to use a multi-stage Docker build, and only actually use a JDK based image for the build stages.
![maven install packaging maven install packaging](https://img.javatt.com/64/64128506e31884260028f3752cc8432a.png)
Optimizing Build SizesĮven with the speed increase, the image is still far too large. This is probably near the optimal build time for this project that I can gain at this point (at least, it's where I've gotten to so far), due to most of it being related to shading. If we run it again, we should see an improvement (but make sure to change a file to correctly simulate changing source code): Maven build time: 31.4s This is expected though, because this is the first build with our new Dockerfile, and so nothing was cached. The total build time is roughly the same.
MAVEN INSTALL PACKAGING DOWNLOAD
Very little has changed, aside from the Maven build time (as it's now separate to the download of dependencies). Let's run a build and see if this changes anything: Maven build time: 33.6s The Dockerfile above is optimized in such a way that most of your dependencies will be cached until the next time you change your pom.xml - and as that changes infrequently, you'll often take advantage of this cache. We can use this to trick the Docker cache into holding onto our Maven dependencies: # select image Fortunately for us, Maven allows you to pull in dependencies before actually building anything. Alone this wouldn't really help the cache, because you're not gaining anything at each of these steps. This can be done by copying your project components in stages, in such a way that the most frequently changed files are copied across last. Our next step is to avoid that cache invalidation.
MAVEN INSTALL PACKAGING CODE
Every time your code is copied across, if anything at all has changed, it automatically voids the Docker cache! Definitely not what we want. In our case, we're invalidating the Docker cache every time we copy across our working directory.
![maven install packaging maven install packaging](https://cdn.ttgtmedia.com/rms/editorial/TSS_how_to_install_maven_fig3_mobile.png)
The Docker cache is easily the most valuable tool when it comes to speeding up Docker builds, so we need to make sure we play nice with it. There are several layers to why builds done the way shown above are so slow firstly that we're not taking advantage of the Docker cache. However there's definite room for improvement here, and now we have our baseline to compare to! Let's see what improvements we can make. That's not too bad really, a build of ~2 minutes and an image size of just under 1GB. Let's look at how a build like this fares (assuming you have the base image maven:3.5-jdk-8 already downloaded): Maven build time: 123s Note that I'm not going to cover disabling things like tests in the lifecycle as it's different for everyone, but you may wish to do so (in my case using -DskipTests). It's quite straightforward and works well your project is quickly copied across and packaged using Maven. # set the startup command to run your binaryĬMD A very basic (yet functional) Dockerfile for this project could look something like this: # select image For the sake of simplicity I'm going to work against JDK 8 for the time being. For my example project I'm going to use a work project (so I can't share too much about it), but the project is relatively large and has several dependencies (which all have their own wonderful tree of dependencies). To begin with, we'll take a really basic Dockerfile that a developer might use to ship a Maven project.
![maven install packaging maven install packaging](https://www.mavenpackaging.com/wp-content/uploads/2017/02/merc1.jpg)
Just like the other post, this is derived from a project at work where I quickly tired of sitting through long builds and attempted to optimize both the size and speed of the build. I recently wrote a post on optimizing Docker images for Rust projects, which turned out to be quite popular, so I figured I'd follow it up with another for those Java developers out there who have to painfully sit through slow Maven builds inside Docker.