Operations 13 min read

Automate CI/CD with Jenkins and Docker: A Step‑by‑Step Guide

This guide walks you through building an efficient CI/CD pipeline using Jenkins and Docker, covering benefits, architecture design, Maven‑based Docker image creation, Alibaba Cloud registry integration, custom Jenkins Docker image setup, permission handling, GitLab webhook configuration, and deployment automation with scripts.

Raymond Ops
Raymond Ops
Raymond Ops
Automate CI/CD with Jenkins and Docker: A Step‑by‑Step Guide

Benefits of an Efficient CI/CD Environment

Early detection of issues: get integration feedback and fixes promptly.

Significantly reduce failure rate: process‑driven workflow minimizes human error.

Accelerate iteration speed: run dozens or hundreds of builds in minutes.

Reduce time cost: eliminate repetitive project setup and deployment tasks.

End‑to‑end pipeline: one‑click deployment, elastic scaling, gray‑release.

To achieve this, integrate DevOps tools and multi‑environment adaptation with automation principles such as one‑click deploy and upgrade.

Release Process Design

Release process diagram 1
Release process diagram 1
Release process diagram 2
Release process diagram 2
Release process diagram 3
Release process diagram 3
Release process diagram 4
Release process diagram 4

Jenkins + Docker Architecture

The following diagram shows the overall network structure.

Overall architecture diagram
Overall architecture diagram

CI/CD Workflow

Developer tags a version in GitLab.

GitLab pushes the tag event to Jenkins.

Jenkins fetches the source, compiles, packages, and builds a Docker image.

Jenkins pushes the image to Alibaba Cloud registry.

Jenkins runs a remote script to pull the image, stop the old container, and start the new one.

Notify testers of the deployment result.

Build Docker Image with Maven and Push to Alibaba Cloud

Add the Docker Maven plugin to pom.xml:

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>0.4.11</version>
    <configuration>
        <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
        <imageTags>
            <imageTag>${project.version}</imageTag>
            <imageTag>latest</imageTag>
        </imageTags>
        <dockerDirectory>src/main/docker</dockerDirectory>
        <resources>
            <resource>
                <targetPath>/</targetPath>
                <directory>${project.build.directory}</directory>
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
    </configuration>
</plugin>
${docker.image.prefix} is the image prefix. ${project.artifactId} is the image name. ${project.version} is the version tag.

Create src/main/docker/Dockerfile:

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD demo-service-ver-0.0.1.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

Build and push the image: $ sudo mvn package docker:build Login to Alibaba Cloud Docker registry and push the image:

$ sudo docker login --username=YOUR_USER --password=YOUR_PASS registry-internal.cn-hangzhou.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/xxx/demo-service:[TAG]
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/xxx/demo-service:[TAG]
Image list in Alibaba Cloud registry
Image list in Alibaba Cloud registry

Custom Jenkins Docker Image

Dockerfile for Jenkins:

FROM jenkins
USER root
RUN apt-get update && apt-get install -y sudo && rm -rf /var/lib/apt/lists/*
RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
USER jenkins

Build and run the Jenkins container:

$ sudo docker build -t buxiaoxia/jenkins:1.0 .
$ sudo docker run --memory 1.5G --name buxiaoxia-jenkins \
    -p 18181:8080 -p 50000:50000 -u root -d \
    --env JAVA_OPTS="-Xms256m -Xmx512m -XX:MaxNewSize=256m" \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /usr/bin/docker:/usr/bin/docker \
    -v /home/buxiaoxia/software/jenkins:/var/jenkins_home \
    -v /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 \
    buxiaoxia/jenkins:1.0
-v /var/run/docker.sock:/var/run/docker.sock and -v /usr/bin/docker:/usr/bin/docker map the host Docker into the container. -v /home/buxiaoxia/software/jenkins:/var/jenkins_home sets the Jenkins home directory on the host. -v /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 resolves missing libraries on CentOS 7.

If permission issues arise, either run: $ sudo chmod 777 /var/run/docker.sock or add the Jenkins user to the Docker group:

$ usermod -a -G docker jenkins

Jenkins Job Configuration

Install required plugins: Maven Integration, docker‑build‑step, Docker, GitLab Hook, GitLab.

Configure Maven settings to use the Alibaba Cloud repository.

Create a Maven job, set the source repository, and trigger builds on tag events.

After build, execute a custom script to push the image and start it remotely:

echo '================开始推送镜像================'
sudo docker login --username=YOUR_USER --password=YOUR_PASS registry-internal.cn-hangzhou.aliyuncs.com
sudo docker push registry-internal.cn-hangzhou.aliyuncs.com/xxx/demo-service
echo '================结束推送镜像================'

echo '================开始远程启动================'
ssh [email protected] -tt << remotessh
cd /home/buxiaoxia/xiaw
./jenkins.sh registry-internal.cn-hangzhou.aliyuncs.com/xxx/demo-service
sudo docker login --username=YOUR_USER --password=YOUR_PASS registry-internal.cn-hangzhou.aliyuncs.com
sudo docker pull registry-internal.cn-hangzhou.aliyuncs.com/xxx/demo-service
sudo docker run -d -m 300m --name=demo-service-`date +%Y-%m-%d` --restart=always registry-internal.cn-hangzhou.aliyuncs.com/xxx/demo-service
echo "finished!"
exit
remotessh

echo '================结束远程启动================'

Helper script jenkins.sh stops the previous container and starts the new one:

#!/bin/sh
sudo docker stop $(sudo docker ps | grep $1 | awk '{print $1}' | sed 's/%//g')

GitLab Webhook Configuration

Install the GitLab plugin in Jenkins, then set the build trigger to respond to tag push events. Copy the generated URL from Jenkins and paste it into the GitLab project's webhook settings.

Summary

With the above steps, a functional CI/CD pipeline is established: pushing a tag to GitLab automatically triggers Jenkins to build, package, push a Docker image to Alibaba Cloud, and deploy it to the target server, eliminating manual deployment steps.

Known Issues and Optimizations

Docker containers are managed individually; using an orchestrator like Swarm or Kubernetes would improve scalability.

Credentials are stored in plain text; consider using secret management.

No rollback mechanism for failed deployments.

Shell scripts lack robust error handling.

Future improvements may include integrating Docker Swarm or Kubernetes for container orchestration and enhancing security and reliability.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Dockerci/cdGitLabmavenShellJenkins
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.