Background
In Java world, it's very common for us to use Apache Maven as the build infra to manage build process.How if we want to do it more interestingly by engaging together with Docker and Jenkins?
Issues We Have To Tackle
There already has pre-built Jenkins image for Docker, here.But some known permission issues keep making noise like what somebody mentioned here, while mounting a host folder for the data generated as a volume -- and typically that's a good practice.
Meanwhile, Maven will try to download all necessary artifacts from Maven repositories -- be it from Internet-based public repositories or in-house private repositories -- to local folder as the cache to facilitate the build process. But, this cache may be very huge (e.g. gigabytes level) so it's not practical to put it into Docker container.
Is it possible to share it from the host folder instead so that even we spin up new containers these cached artifacts are still there?
So, these major issues/concerns should be fully addressed while think of solutioning. As a summary, these issues/concerns are as below:
- How can we achieve the goal of having more control and flexibility while using Jenkins?
- Can we share resources from host so that we can always keep Docker container lightweight?
Tools We're Going to Use
Before wee deep dive into detailed solutions, we assume that below tools that we are going to use have already been installed and configured properly, in our host server (e.g. mine is Ubuntu 14.x, 64bit):
- Docker (e.g. mime is version 1.11.0, build 4dc5990)
- Docker Compose (e.g. mime is version 1.6.2, build 4d72027)
- JDK (e.g. mime is version 1.8.0_102)
- Apache Maven (e.g. mime is version 3.3.3)
Solutions & Practices
1. Customize Our Jenkins Docker Image To Gain More Control and Flexibility
It's pretty straightforward to think about building our own docker image for Jenkins so that we can have more control and flexibility. Why not?
$ whoami devops $ pwd /home/devops $ mkdir jenkins $ cd jenkins $ touch Dockerfile $ vim Dockerfile
~/jenkins/Dockerfile
FROM jenkins MAINTAINER Bright Zheng <bright.zheng AT outlook DOT com> USER root RUN GOSU_SHA=5ec5d23079e94aea5f7ed92ee8a1a34bbf64c2d4053dadf383992908a2f9dc8a \ && curl -sSL -o /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.9/gosu-$(dpkg --print-architecture)" \ && chmod +x /usr/local/bin/gosu && echo "$GOSU_SHA /usr/local/bin/gosu" | sha256sum -c - COPY entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
I believe some explanation is required here.
- The image we're going to build is based on official jenkins Docker image;
- We're trying to setup a simple but powerful tool gosu here which can be used for runing some specific scripts by specific user later;
- We will use a dedicated entry script file namely "entrypoint.sh" for our customize-able scripts
Okay, time to focus on our entry point:
$ touch entrypoint.sh $ vim entrypoint.sh
~/jenkins/entrypoint.sh
#! /bin/bash set -e # chown on the fly chown -R 1000 "$JENKINS_HOME" chown -R 1000 "/data/mvn_repo" # chmod for jdk and maven chmod +x /opt/maven/bin/mvn chmod +x /opt/jdk/java_home/bin/java chmod +x /opt/jdk/java_home/bin/javac exec gosu jenkins /bin/tini -- /usr/local/bin/jenkins.sh
Some more explanation as the important tricks come from here:
- Yes, we will change the $JENKINS_HOME's owner to user Jenkins (with uid=1000) which has been hardcoded in official Jenkins Dockerfile, here;
- We're going to expose a dedicated folder "/data/mvn_repo" to be the "home" folder for the cached Maven artifacts, which should be mounted from host as a Docker volume;
- We're going to grant execute permission for some Maven, JDK executable commands which would be mounted and shared from host also!
Now it's ready and let's build our customized Docker image -- we tag it as devops/jenkinsci.
docker build -t devops/jenkinsci .
BTW, if we run it behind proxy, some build-args are required to be part of our command, as below example:
docker build \ --build-arg https_proxy=http://192.168.56.1:3128 \ --build-arg http_proxy=http://192.168.56.1:3128 \ -t devops/jenkinsci .
Once succeeded, we can use below command to verify whether the newly built Docker image is in the local Docker repository or not:
$ docker images
Now we have successfully got our customized Docker image for Jenkins.
2. Engage Docker Compose
What's next? Well, it's time to engage Docker Compose to spin up our container(s).
(BTW, if there is just one container to spin up, simply use docker run command can work as well. But by consideration of more types of components would be involved in, Docker Compose is a better choice definitely...)
Let's prepare the docker-compose.yml:
$ pwd /home/devops $ touch docker-compose.yml $ vim docker-compose.yml
~/docker-compose.yml
# Jenkins CI Server
jenkins: # 1 - Yeah, we use our customized Jenkins image
image: devops/jenkinsci
volumes:
# 2 - JENKINS_HOME
- /data/jenkins:/var/jenkins_home
# 3 - Share host's resources to container
- /opt/jdk/java_home:/opt/jdk/java_home
- /opt/maven:/opt/maven
- /data/mvn_repo:/data/mvn_repo
# 4 - see explanation
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
# 5 - see explanation
- /lib/x86_64-linux-gnu/libsystemd-journal.so.0:/lib/x86_64-linux-gnu/libsystemd-journal.so.0
- /usr/lib/x86_64-linux-gnu/libapparmor.so.1:/usr/lib/x86_64-linux-gnu/libapparmor.so.1
- /lib/x86_64-linux-gnu/libcgmanager.so.0:/lib/x86_64-linux-gnu/libcgmanager.so.0
- /lib/x86_64-linux-gnu/libnih.so.1:/lib/x86_64-linux-gnu/libnih.so.1
- /lib/x86_64-linux-gnu/libnih-dbus.so.1:/lib/x86_64-linux-gnu/libnih-dbus.so.1
- /lib/x86_64-linux-gnu/libgcrypt.so.11:/lib/x86_64-linux-gnu/libgcrypt.so.11
ports:
- "8081:8080"
Again, the explanation is as below:
- We employ our own customized Jenkins image;
- We mount host's /data/jenkins folder to /var/jenkins_home which is the default JENKINS_HOME location by Jenkins;
- We share host's JDK, Maven and Maven local repository to the container by mounting as the volumes;
- That's from the instructions of the great Docker sharing solution (I'd like to name it "Docker with Docker", haha), see here;
- Some lib components have to be shared for above "Docker with Docker" solution.
To start it up, simply key in:
$ docker-compose up
After a few seconds, our Jenkins container will be ready for use and we can simply open browser of your choice and access URL like http://{IP}:8081/ -- a brand new and fully customized Jenkins will be showing in front of you.
What's next? Jenkins console might be your workspace where interesting stuff like build project creation and configuration will be your work items to get CI work.
You may refer to Jenkins documentation to get started.
Conclusion
From these practices, some useful points we have learned and gained are:
- We can gain more benefits (e.g. control, flexibility) if we'd customize our Jenkins image and the customization is pretty easy;
- We can share a lot of resources from our host, from libs, JDK, Maven to any other potentially heavy/big stuff, so that we can always make our Docker container as lightweight as possible.
Interesting right? Let me know if you have any comments.
Very informative blog post on Docker, so useful to DevOps candidates. thank you for such clear explanation.
ReplyDeleteBest Regards,
DevOps Training in Hyderabad
DevOps Online Training in Hyderabad
DevOps Online Training
DevOps Institutes in Hyderabad
Learn DevOps Online
Best DevOps Training Institute in Hyderabad
Best DevOps Online Training Institute in Hyderabad
Best DevOps Online Training in India
DevOps Institute in Hyderabad
Best DevOps Training
DevOps Training and Certification
learn DevOps
DevOps Institutes in Ameerpet
DevOps Training
DevOps Courses
DevOps Certification Training
CourseIng
the blog gives a complete working of devops. thank you for posting this. let me work on it to improve my knowledge.
ReplyDeletedevops training in chennai
Well written . Keep sharing Devops Online Course
ReplyDeleteI likable the posts and offbeat format you've got here! I’d wish many thanks for sharing your expertise and also the time it took to post!!
ReplyDeleteDevOps Online Training
DevOps Training in Pune
Great Blog.very interesting and informative Blog...
ReplyDeleteDocker Training in Hyderabad
Docker Training
A universal message I suppose, not giving up is the formula for success I think. Some things take longer than others to accomplish, so people must understand that they should have their eyes on the goal, and that should keep them motivated to see it out til the end.keep it up!!!
ReplyDeleteandroid training in chennai
android online training in chennai
android training in bangalore
android training in hyderabad
android Training in coimbatore
android training
android online training
A universal message I suppose, not giving up is the formula for success I think. Some things take longer than others to accomplish, so people must understand that they should have their eyes on the goal, and that should keep them motivated to see it out til the end.keep it up!!!
ReplyDeleteangular js training in chennai
angular js training in omr
full stack training in chennai
full stack training in omr
php training in chennai
php training in omr
photoshop training in chennai
photoshop training in omr
perde modelleri
ReplyDeleteSMS ONAY
Turkcell mobil ödeme bozdurma
nft nasil alinir
ankara evden eve nakliyat
trafik sigortası
dedektör
SİTE KURMAK
aşk kitapları