# Whaaat?

Build your local project on e.g. a Mac with docker so that you can do the build with Linux and all it provides.

Now you might ask me why for F**k sake?! Java is cross platform so why?

# Well why?!

I needed a dependency in my maven build with native bindings (Rados) on the target system.
These dependencies are not available for my local machine without doing some nasty stuff and installing it all on my machine.
As I don’t want to pollute my machine with software I only use professionally for a certain customer, I didn’t want to do the installation.

# So what to do…

A couple of things:

• Docker image(s) needed
• CentOs 7 base image (ivonet/centos-jdk:7-1.8.0) with java 1.8.0
• Extended image with maven and the native bindings
• Entrypoint script to run default mvn clean install if no parameters provided
• Expose VOLUMES for easy mounting
• Bash script to run the docker maven on the local project and use the local repository

## Docker images

### Base CentOs image with JDK 8

First create a base image with the target system and the needed java version. In my case this was CentOs as we use Redhat servers on production.

• Create a directory called centos-jdk
• Create a Dockerfile in that directory

Build and push it:

### Extended docker images with maven

Now that we have the base image we can create an extended version for our specific purposes.
So lets extend the just created image and add maven and the rados native bindings. This is of course something you might want to change
for your environment as this is just the reason I needed this.

• Create a directory called centos-maven
• Create a Dockerfile in that directory

This Dockerfile also tells us that we have two volumes we can mount as we like and one of the is the repository volume.
This is the only thing we overrode in the settings.xml file from the original settings.xml.
For those actually following the blog for their own purposes I will paste it in.
Note the <localRepository>/repository</localRepository> line in the file, as it maps the the volume declared in the Dockerfile.

I added an entrypoint.sh file which looks like this in the folder setup:

This is more or less just a placeholder as you can see, but in the version I use for my actual project I have stuff in there to set the proxy in the
settings.xml file correctly based on ENV settings on the commandline, for the environment I am working on and the nexus repository for the client I’m working for.
I left the placeholder script as a reminder one can do lots more than this straightforward example.

Now we can build and deploy it:

## Maven script

We are almost ready. The ingredients are there, now we can put it all together on the command line.
Note that this script will not go into the docker image. This one is used to run the docker image with the correct parameters

This command will run the just created image with the current directory mapped the the /project volume in the docker image and the local maven repository
mapped to the /repository in the docker image. As we throw away the state of this image after every command (--rm)
it would take a long time to build as no dependencies would be remembered and all would have to be downloaded every time. This is actually a good
thing to do now and then but not every time. That would be wasteful. So by mapping your own local maven repo to the docker image the dependencies
will be downloaded there and state is preserved and the image becomes ‘stateless’.
As the default CMD is mvn verify it will be performed.

But there is more…

If you create a shell script based on the above bash commands with a name like mvncentos and make it executable (chmod +x mvncentos)
and place it on your PATH it will be available for the projects you need it for.

# Done

With these ingredients you will be able to build your project without polluting your system with stuff you do not want to install.
When you are done with the project you can just throw away your docker image and shell script and you are set again for the next project.

Always welcome…