A Simple Guide to Build CI/CD Pipeline with Docker and GitLab for Spring Boot Project
Table of Contents
- What is CI/CD and Why We Need It?
- Prepare Tools: Install Docker and GitLab
- Setup GitLab Runner for Automation
- Create a Simple Spring Boot Project
- Write Dockerfile for Containerization
- Configure GitLab CI/CD Pipeline (.gitlab-ci.yml)
- Example: Auto Build, Test, and Deploy
- Common Errors and Solutions
1. What is CI/CD and Why We Need It?
CI/CD means “Continuous Integration” and “Continuous Delivery.” It help developers automatically build, test, and deploy code. For example, when you push code to GitLab, it can auto make a Docker image and deploy to server. No need manual work! This save time and reduce mistakes
2. Prepare Tools: Install Docker and GitLab
2.1 Install Docker
Steps for CentOS:
sudo yum install docker-ce docker-ce-cli containerd.io
ps: here is only one way to install this tool, for more detail you can go to the official website, and pick up which version you want.
Common Errors:
- If see “Permission denied” error,
like:
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied
run:
sudo usermod -aG docker $USER
# Then logout and login again
-
If Docker service not start, check with:
systemctl status docker
2.2 Install GitLab
Use Docker to install GitLab (easy way):
sudo docker run -d \
--hostname gitlab.example.com \
-p 9080:80 -p 9443:443 \
--name gitlab \
--restart always \
gitlab/gitlab-ce:latest
Wait 5-10 minutes. Then open http://your-server-ip:9080
in browser. Set password for “root” user when first time login.
Important Notes:
-
GitLab need at least 4GB RAM. If your server has less, it may crash
-
Always backup GitLab data. Use this command:
sudo docker exec -t gitlab gitlab-backup create
3. Setup GitLab Runner for Automation
GitLab Runner is tool to run CI/CD jobs. We install it with Docker:
sudo docker run -d --name gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
-v gitlab-runner-config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest
Register Runner to GitLab:
-
Go to GitLab > Your Project > Settings > CI/CD > Runners.
-
Copy “Registration Token”.
-
Run this command:
sudo docker exec -it gitlab-runner \ gitlab-runner register \ --url "http://your-server-ip:9080/" \ --registration-token "YOUR_TOKEN" \ --executor "docker" \ --description "my-runner" \ --docker-image "docker:latest"
Troubleshooting:
-
If jobs stuck in “Pending” status, check if Runner tags match
.gitlab-ci.yml
-
If see “403 Forbidden” error,
restart Runner:sudo docker restart gitlab-runner
4. Create a Simple Spring Boot Project
We make a basic app for example.
4.1 Project Structure
Remember to push the project in correct structure like this:
4.2 HelloController.java
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/")
public String hello() {
return "Hello from CI/CD Pipeline!";
}
}
ps: all right, this is only a simple example program which have no specific feature, ah ah…
4.3 pom.xml
Add Spring Boot and testing dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
5. Write Dockerfile for Containerization
Create Dockerfile
in project root:
FROM maven:3.8.5-openjdk-17 AS build
COPY . /app
WORKDIR /app
RUN mvn clean package
FROM openjdk:17-slim
COPY --from=build /app/target/*.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
Notes:
-
Use Java 17 for best compatibility
-
If build slow in China, change Maven mirror in settings.xml because of some reasons we all know, ah ah…
you can do add this json into this file:
/etc/docker/daemon.json{ "registry-mirrors": [ "https://t6480gpj.mirror.aliyuncs.com", "https://registry.docker-cn.com" ] }
and then
sudo systemctl daemon-reload
sudo systemctl restart docker
6. Configure GitLab CI/CD Pipeline (.gitlab-ci.yml)
Create .gitlab-ci.yml
file:
stages:
- build
- test
- deploy
variables:
DOCKER_IMAGE: "my-spring-app:$CI_COMMIT_REF_NAME"
build-job:
stage: build
script:
- docker build -t $DOCKER_IMAGE .
tags:
- my-runner
test-job:
stage: test
script:
- docker run $DOCKER_MODULE sh -c "./mvnw test"
tags:
- my-runner
deploy-job:
stage: deploy
script:
- docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
- docker push $DOCKER_IMAGE
- ssh user@server "docker pull $DOCKER_IMAGE && docker run -d -p 8080:8080 $DOCKER_IMAGE"
tags:
- my-runner
7. Example: Auto Build, Test, and Deploy
Follow these steps:
- Push code to GitLab:
git init
git add .
git commit -m "First commit"
git push http://your-gitlab-url/root/demo-project.git
- Check pipeline status in GitLab > CI/CD > Pipelines.
- If all green, access your app at
http://server-ip:8080
.
8. Common Errors and Solutions
Error 1: “Docker connection refused”
Fix: Add these lines to .gitlab-ci.yml
:
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
And make sure Runner has /var/run/docker.sock
mounted
Error 2: Tests fail randomly
Fix: Add retry logic:
test-job:
retry:
max: 2
when:
- runner_system_failure
Error 3: “No space left on device”
Fix: Clean old Docker images periodically:
docker system prune -f
This guide give you all steps to build working CI/CD pipeline. If meet problems, check error messages and compare with our “Common Errors” section. Happy coding!