I have two maven spring boot applications and I was set up two docker file for that.
Inside each container, I am performing the maven install.
The two containers are performing a lot of download for the dependencies and finally packing the application.
Since these two containers are built sequentially, Can I share the maven's local repository of the first container to the second container, so that the second container's maven install will skip the locally available dependency and only fetch extra libraries mentioned in its pom?
Yes, you can.
We do something similar so that our builds are always clean. But to save time on the maven download, we use a docker volume mounted to the m2 directory so that the downloads can be used between builds & docker containers.
docker run -v m2Repository:/root/.m2 some-image
docker run -v m2Repository:/root/.m2 some-other-image
First run takes a while, but the following builds are much faster.
You did not mention, which environment you are running builds on, so I would like to share my solution for Bitbucket Pipelines CI.
We build our ~20 containers in Bitbucket Pipelines CI and every container is Java application with almost same set of dependencies. Bitbucket Pipelines CI uses Docker images for running builds (yes, they are using Docker images to build Docker images). There is an option to specify which Docker image to use for builds.
To avoid downloading all dependencies over and over again and reduce build time, I built custom Docker image which contains all external dependencies of all our modules. All dependencies were gathered using Maven's command in each module:
mvn -Dmaven.repo.local=c:/projects/bitbucket-pipelines-baseimage/local-maven-repo clean install
After that I removed project's artifacts from temp repository "c:/projects/bitbucket-pipelines-baseimage/local-maven-repo" and built Docker image, which includes that temp repository. That image was deployed to Docker Hub and now all our build in Bitbucket Pipelines are using it. Build times were reduced drastically!
Related
I need to know why in my jenkins pipeline when creating a docker container for building a java app with maven everytime that I run the pipeline it downloads all the java artifacts/requirements again and again from the pom.xml file,, help please!
Because the directory, where maven caches these artifacts (~/.m2) is inside the docker container and thus not preserved between runs.
I am trying to figure out how to build Docker images as part of the Maven build process. Basically, I want to create a Maven project which builds a Docker image. I think this makes sense.
But what should the packaging type look like? It's obviously not jar, war or maven-plugin. I tried with docker but that does not exist.
Should I just go for pom or is there a way to configure custom package types?
Having it at pom feels wrong to me, as we are producing an output - a Docker image - which is usually not the case in regular pom types (parent pom, bom, ...).
Wow that's ambitious! When you say you want to build a docker image using Maven, I'm assuming you won't be using docker build or other docker commands to generate the final image. Docker images are TAR files so you can use the Maven Assembly plugin to generate the desired tar-file image.
In this case, your project's "type" would be "pom" so that the project itself generates a POM file containing the information about how it was built (such as name and version number). The Assembly plugin will also generate and attach the corresponding TAR file so that when you use mvn deploy or other commands which reference the package, the associated TAR file will be included.
If you are using docker commands to build the images then you are probably going to have to write a custom Maven extension -- depending on what you want to happen when you run mvn deploy. It really depends on your ultimate goal but if you are using this within the confines of Docker then you might do better with a plugin like dockerfile-maven which will allow your build to drive the docker workflow of docker build and/or docker push.
Spotify has created a dockerfile-maven-plugin that allows you to build and publish Docker images with maven. There is an example and lots of other useful info on the project page.
Of today, there's a Maven docker plugin that enables <packaging>docker</packaging>, here:
https://github.com/fabric8io/docker-maven-plugin
Doc here:
https://dmp.fabric8.io/
But take care to specify <extensions>true</extensions>!
We are using TFS in our organisation and we manage our whole build through shell scripts (which isn't great)...
Our agent have docker installed and we run our build script inside docker. We have several images for maven, gradle, NodeJs, ...
Because of our use of Docker we cant use the maven plugin for example.
I am wondering if I can somehow benefits from the maven plugin while still running on docker?
You could directly use Docker Integration instead of managing build through shell scripts.
The Docker extension adds a task that enables you to build Docker
images, push Docker images to an authenticated Docker registry, run
Docker images or execute other operations offered by the Docker CLI.
It also adds a Docker Compose task that enables you to build, push and
run multi-container Docker applications or execute other operations
offered by the Docker Compose CLI. Lastly, it offers a Docker Deploy
task that enables you to deploy single Docker images or
multi-container Docker applications into Azure.
Making an image for maven project should be straightforward, as maven know how to build (and can know how to run)
How to build docker image and run it with maven?
Let's say the app also needs MongoDB, that I can run as docker run -p 27017:27017 mongo. Is it possible also to specify with some maven plugin?
The maven plugin created by fabric8 allows you to do this:
the plugin and its documentation is available on github: https://github.com/fabric8io/docker-maven-plugin
The samples include for example https://github.com/fabric8io/docker-maven-plugin/blob/master/samples/data-jolokia-demo/pom.xml (which seems to be similar to what you plan).
An alternative could be using Docker-compose and some scripts outside maven, once the images are created.
I currently following this methods for my maven java project in jenkins
created a compose file with maven image, and given a entry point command "mvn clean install"
Created a Dockerfile, From tomcat image. that will copy my war to ../webapps folder
Once the docker compose up is exited with the code 0, I am starting the docker build with the Dockerfile.
Then pushing the image to my registry
Now the problem is. I need to push my war to nexus.
I know , still we can achive by command mvn deploy ....
But is going like all we need to maintain for each and every project.
Previouly I used m2release plugin. that plugin have option to execute the try run and release run. once it done, it automatically change my pom to next vertion and commits to git.
Now I want to achieve that with docker build in jenkins. Or my way of doing is wrong? if yes, what is the correct solution for doing this?