In previous blog, I shared how to run Jenkins + Maven in Docker container here and we could already automate the Maven-based build automatically in our Jenkins CI server, which is great to kick off for the CI process.
But, while reviewing what we're going to achieve as below diagram, we realize that having a Spring Boot-powered jar file is not what we want, we want to have a Docker image built and registered into our private Docker Registry so that we're fully ready for the coming Continuous Deployment!
So let's focus on the highlighted part on above diagram to build an integrated Jenkins + Maven + docker-maven-plugin solution, by using Docker container technology also!
Build Up Our Private Docker Registry
Docker has provided a great Docker image for building up our private Docker Registry, here.
Let's do it by simply running through below commands:
$ sudo mkdir /data/registry $ sudo chown -R devops:docker /data/registry $ whoami devops $ pwd /home/devops $ vim docker-compose.yml ------------------------------- # Private Docker Registry docker-registry: image: registry volumes: - /data/registry:/var/lib/registry ports: - "5000:5000" -------------------------------
It's almost done, let's spin it up:
$ docker-compose up
And try it out:
$ curl http://127.0.0.1:5000/
"\"docker-registry server\""
Well, our private Docker Registry works but wait…the Docker client can’t push image to it yet.
We need to make some changes at Docker's configuration before pushing images:
$ sudo vim /etc/default/docker --------------------------- DOCKER_OPTS="--insecure-registry 192.168.56.118:5000" ---------------------------
And then restart the Docker daemon:
$ sudo service docker restart
Now our private Docker Registry is ready to rock.
But how to verify whether our Docker Registry is really working as what we expected?
It must be: 1) Ready for publishing; and 2) Ready for searching.
The idea is to use our greatest public available "hello-world" image which is lightweight enough to try, 960B!
$ docker pull hello-world
$ docker images
... hello-world latest 690ed74de00f 11 months ago 960 B
$ docker tag 690ed74de00f 192.168.56.118:5000/hello-world
$ docker images
... 192.168.56.118:5000/hello-world latest 690ed74de00f 11 months ago 960 B hello-world latest 690ed74de00f 11 months ago 960 B
$ docker push 192.168.56.118:5000/hello-world The push refers to a repository [192.168.56.118:5000/hello-world] 5f70bf18a086: Image successfully pushed b652ec3a27e7: Image succewr12334567ssfully pushed Pushing tag for rev [690ed74de00f] on {http://192.168.56.118:5000/v1/repositories/hello-world/tags/latest}
$ curl http://192.168.56.118:5000/v1/search?q=hello {"num_results": 1, "query": "hello", "results": [ {"description": "", "name": "library/hello-world"} ] }
Sure enough, our private Docker Registry is fully ready!
Okay, so far we already have a private Docker Registry, already can do a basic Maven build in Jenkins. What should we do next?
Enable the docker-maven-plugin
It's time to enable our glue, the docker-maven-plugin, in our project.The purposes of using this plugin are to:
- Automate the Docker image build process on top of our typical build which the output might be jar, war. Now, we want to have a Docker image equipped with our application as the deliverable!
- Publish our built Docker image to our private Docker Registry where is the starting point of our Continuous Deployment!
<Frankly speaking, there were many issues encountered along my experiment like here but to make long story short, I'll go directly to the points>
Firstly, please refer to my previous blog "Some Practices to Run Maven + Jenkins In Docker Container" here for the basic setup of the environment.
Below successful experiment would be on top of this environment.
Explicitly Specify Docker Host in /etc/default/docker
Edit the /etc/default/docker as below:
#DOCKER_OPTS="--insecure-registry 192.168.56.118:5000" DOCKER_OPTS="--insecure-registry 192.168.56.118:5000 -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock"
And restart the Docker daemon is required, of course:
$ sudo service docker restart
Enable the docker-maven-plugin In pom.xml
There are many Docker Maven plugins available and I simply choose spotify's one, here.The configuration of the plugin in pom.xml is as below:
<!-- Docker image building plugin --> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.13</version> <executions> <execution> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <dockerHost>${docker.host}</dockerHost> <baseImage>frolvlad/alpine-oraclejdk8:slim</baseImage> <imageName>${docker.registry}/devops/${project.artifactId}</imageName> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> <forceTags>true</forceTags> <imageTags> <imageTag>${project.version}</imageTag> </imageTags> </configuration> </plugin>
The Jenkins Job
Below screenshots are the major configuration parts of the Jenkins Job.Source Code Management
Build Triggers
Maven Goals
Console Output
Here I also posted a typical Console Output of the Jenkins Job for reference as a Gist here.Have A Check On What We Have
Firstly we can check whether our local repository has the cached image:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
... 192.168.56.118:5000/devops/springboot-jersey-swagger 1.0.0-SNAPSHOT 203fde08df84 44 minutes ago 191.9 MB
...
Great, then have a check whether this image has been registered into our private Docker Registry:
$ curl http://192.168.56.118:5000/v1/search?q=springboot-jersey-swagger {"num_results": 1, "query": "springboot-jersey-swagger", "results": [ {"description": "", "name": "devops/springboot-jersey-swagger"} ] }
Yeah! We made it!
Try Our Docker Image Out Also
To go deeper, we can also take a look on whether our application works or not:
docker run -d -p 8000:8000 192.168.56.118:5000/devops/springboot-jersey-swagger
Open the browser and key in: http://192.168.56.118:8000
Hooray, it works perfectly!
Conclusion
From this experiment we have learned that:
- By using a customized Docker container, we can put Jenkins, Maven and docker-maven-plugin together to automate our project build process and the deliverable can be our desired Docker image;
- The Docker image can be pushed automatically to our private Docker Registry within the pipeline which will enable us to make the Continuous Deployment happen soon.
So the CI part is done and let's look forward to our CD part soon!
Enjoy your CI experiments also!








