How I Setup Jenkins On Docker Container Using Ansible (Part 2)
7 Min Read
This post continues from How I Setup Jenkins On Docker Container Using Ansible (Part 1)
In this post, we will detail how an auto-configured Jenkins environment was built and deployed as a Docker container.
This post-walk-through mainly focuses on containerization.
sudo apt install docker.io # The Docker service needs to be set up to run at startup. sudo systemctl start docker sudo systemctl enable docker python3 -m pip install docker-compose
Using a container offers convenience and ensures that deployments are deterministic. It also offers a great deal of flexibility.
But before continuing, the directory structure shown below should resemble what we should have once we are done with the walk-through.
tree -L 3 . ├── Dockerfile ├── jenkins_config.yaml ├── jenkins_plugins.txt ├── populate_jenkins_casc.py ├── requirements.txt └── userContent └── README.md 1 directory, 6 files
The following sections will explain some of the files and directories we will be creating.
Create Docker container
The code snippets below do the following:
- Creates a directory where we will store all our files and scripts
mkdir -p ~/tmp/jenkins-docker && cd "$_" mkdir -p userContent
- Creates 5 empty
- Note: The contents of these files are discussed in other posts to avoid this post getting too long and confusing.
touch jenkins_config.yaml \ jenkins_plugins.txt \ populate_jenkins_casc.py \ requirements.txt \ userContent/README.md echo "Files in this directory will be served under your http://<server>/jenkins/userContent/" > userContent/README.md
- Creates a
Dockerfilethat includes all relevant dependencies (Note: Jenkins is pinned to a specific version to ensure determinism)
cat > Dockerfile << "EOF" FROM jenkins/jenkins:2.321 USER root # set your timezone ENV TZ="/usr/share/zoneinfo/Africa/Johannesburg" # hadolint ignore=DL3008,DL3009,DL3015 RUN apt-get update && \ apt-get -yq install \ apt-transport-https \ bzip2 \ ca-certificates \ curl \ gnupg2 \ iputils-* \ net-tools \ software-properties-common \ wget SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - RUN apt-key fingerprint 0EBFCD88 RUN add-apt-repository -y \ "deb [arch=amd64] https://download.docker.com/linux/debian \ $(lsb_release -cs) \ stable" # hadolint ignore=DL3008,DL3009,DL3015 RUN apt-get update \ && apt-get install -yq \ docker-ce-cli VOLUME /var/run/docker.sock # ------------ extra-tools ------------ # hadolint ignore=DL3008,DL3015 RUN apt-get update \ && apt-get -yq install \ graphviz \ rsync \ vim \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # ------------ Jenkins configurations ------------ # Change to Jenkins user USER jenkins # increase http login session timeout ENV JENKINS_OPTS --sessionTimeout=10080 # https://www.jenkins.io/doc/book/managing/casc/ ENV CASC_JENKINS_CONFIG "/usr/share/jenkins/ref/jenkins_config.yaml" # disable setup wizard on first start ENV JAVA_OPTS=-Djenkins.install.runSetupWizard=false # install plugins # hadolint ignore=DL3059 COPY --chown=jenkins:jenkins jenkins_plugins.txt /usr/share/jenkins/ref/jenkins_plugins.txt RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/jenkins_plugins.txt # copy user contents which might include images and other files COPY --chown=jenkins:jenkins userContent/* /usr/share/jenkins/ref/userContent/ # hadolint ignore=DL3059 RUN chown -R jenkins:jenkins /var/backups # hadolint ignore=DL3059 RUN chown -R jenkins:jenkins /var/jenkins_home EOF
To ensure that we follow the Docker’s best practices, we use Hadolint which is a
Dockerfile linter that helps you build best practice Docker images. I use it in all of my projects to ensure I’m creating small, secure, efficient, and maintainable images.
Let’s run our
docker run --rm -i hadolint/hadolint < Dockerfile
Once we have established that our
Dockerfile is valid (no linting errors), we can explore the
requirements.txt empty files created above.
To learn more about Jenkins plugins (
jenkins_plugin.txt), read the blog post on Managing Jenkins Plugins was written.
Jenkins Configuration as Code
To learn more about Jenkins configuration as code (
, andrequirements.txt`), read the blog post on Managing Jenkins Configuration As Code And Secrets Management was written.
Putting it all together
Once all of the files are created, we can execute the sequence of commands that are needed to assemble the Jenkins image using through the
Dockerfile that was created.
Let’s build the image using the following command:
docker build -t jenkins-docker .
Ensure that the image was successfully built by listing all available images:
docker image ls
which gives us a similar output
Now let’s tag the image before publishing (push) it to Docker Hub.
To tag a docker image you use the following command:
docker tag jenkins-docker <<dockerhub username>>/jenkins-image .
Now let’s publish the new image by logging into Docker Hub using our Docker Hub credentials, if you do not have any then sign up for Docker Hub.
Thereafter login using the following command in order to push the image to Docker Hub:
After a successful login, then push the image to Docker Hub using the following command:
Thereafter, we verify that the image was successfully pushed to Docker Hub
Congratulations! You have successfully created a Jenkins container (containing Jenkins plugins and configuration as code) and published it to Docker Hub. You can now use the instance as part of the Ansible playbooks.