Spring Boot API deployment using GitLab CI/CD and Docker

In this post, we’ll explain step by step how to use GitLab CI/CD to build, test, and deploy Spring boot API using Docker.

· Prerequisites
· Spring boot application setup
· GitLab Ci/CD
∘ Using Docker inside GitLab CI
∘ Run GitLab Runner in a container
∘ Run GitLab CI/CD pipeline
∘ View pipeline status and jobs
· Source code
· Conclusion
· Troubleshooting
· References

Prerequisites

This is the list of all the prerequisites for following this story:

  • A Spring boot 3+ app with Java 17 and Maven 3.6.+
  • A Gitlab account
  • A virtual machine (VM) (with Centos7 as part of this story)
  • Git
  • Docker installed on the VM
  • Docker compose installed
  • Postman / Insomnia or any other API testing tool (optional)

Spring boot application setup

For the purpose of this article, we will create a simple Rest Spring Boot application using Spring Initializr.

Next, let’s create a Rest controller to test our application.

@RestController
@RequestMapping("/api")
public class WebDeploy {

    @GetMapping("/deploy")
    public String index() {
      return MessageFormat.format("Web deploy ok: {0}", LocalDateTime.now());
    }

}

We can test the new endpoint by starting the application and opening http://localhost:8080/api/deploy from our browser.

It works well. We need to create a new project on Gitlab, commit our code locally, and push it to the remote repository using the project URL Gitlab generated.

GitLab Ci/CD

We’re going to see how we can configure Gitlab to build our Spring boot application. GitLab CI/CD can automatically build, test, deploy, and monitor your applications by using Auto DevOps.

For this story, we’re using the Docker integration to set up our CI/CD workflow.

Using Docker inside GitLab CI

We can use GitLab CI/CD with Docker to create Docker images. There are 3 approaches to building images with GitLab CI:

  • Use the shell executor
  • Use Docker-in-Docker
  • Use the Docker executor with Docker socket binding

Run GitLab Runner in a container

To run Docker commands in CI/CD jobs, we must configure GitLab Runner to support Docker commands.

We first create a directory called my-gitlab-runner with the following content:

The docker-compose yml file contains all the instructions to run the GitLab-runner container.

version: '3.7'

services:
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    restart: always
    container_name: gitlab-runner
    volumes:
      - ./config/:/etc/gitlab-runner/
      - /var/run/docker.sock:/var/run/docker.sock

We use docker compose up -d to run the runner container.

The next step is to register a new runner. The GitLab Runner container doesn’t pick up any jobs until it’s registered.

Go to Project Settings > CI / CD > Runner section and get a token.

Register GitLab Runner from the command line.

docker compose run --rm gitlab-runner register -n \
  --url https://gitlab.com/ \
  --registration-token <TOKEN>\
  --executor docker \
  --description "Demo test my docker runner" \
  --docker-image "docker:stable" \
  --docker-privileged \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

This command registers a new runner to use the docker:stable image. To start the build and service containers, it uses the privileged mode.

When the runner registration is successful, the config/config.toml file is updated with this content:

concurrent = 1
check_interval = 0
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "Demo test my docker runner"
  url = "https://gitlab.com/"
  id = 23325305
  token = <TOKEN>
  token_obtained_at = 2023-05-10T17:33:55Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0

Back on GitLab, we can see the registered runner in Settings > CI / CD > Runner section:

Run GitLab CI/CD pipeline

  1. Dockerfile

To build the container image with docker, we’ll need to use a file Dockerfile. Let’s start by creating the Dockerfile in the root directory of our project.

# creates a layer from the openjdk:17-alpine Docker image.
FROM openjdk:17-alpine

MAINTAINER boottechnologies.ci@gmail.com

# cd /app
WORKDIR /app

# Refer to Maven build -> finalName
ARG JAR_FILE=target/spring-gitlab-ci-*.jar

# cp target/spring-gitlab-ci-0.0.1-SNAPSHOT.jar /app/spring-gitlab-ci.jar
COPY ${JAR_FILE} spring-gitlab-ci.jar

# java -jar /app/spring-gitlab-ci.jar
CMD ["java", "-jar", "-Xmx1024M", "/app/spring-gitlab-ci.jar"]

# Make port 8080 available to the world outside this container
EXPOSE 8080

2. .gitlab-ci.yml file

.gitlab-ci.yml file is a YAML file that specifies instructions for GitLab CI/CD.

It defines:

  • The structure and order of jobs that the runner should execute.
  • The decisions the runner should make when specific conditions are encountered.

Let’s create a .gitlab-ci.yml file at the root of the repository.

image: gitlab/dind
services:
  - docker:dind

variables:
  DOCKER_DRIVER: overlay
  APP_IMAGE: demo-cicd-image 

stages:
  - build
  - test
  - docker

maven-build:
  image: maven:3.8.5-openjdk-17
  stage: build
  script: "mvn clean package -B"
  artifacts:
    paths:
      - target/*.jar

maven-test:
  image: maven:3.8.5-openjdk-17
  stage: test
  script: "mvn test"
  artifacts:
    paths:
      - target/*.jar

docker-build:
  stage: docker
  script:
  - docker build -t $APP_IMAGE .
  - docker run -d -p 8090:8080 $APP_IMAGE

The pipeline consists of three jobs maven-build, maven-test, and docker-build which specify the build, test, and deploy (docker) stages.

The pipeline will start when we push the code to the remote origin.

View pipeline status and jobs

Now let’s see what the pipeline looks like. Go to CI/CD > Pipelines

Pipeline view by selecting the pipeline ID.

After the pipeline build is successful, we can verify that the container is running on our target server.

The application is well deployed. Congratulations.

Source code

The complete source code is available on GitHub.

Conclusion

In this post, We have seen how to deploy step by step a Spring boot application using GitLab CI/CD and Docker.

Thanks for reading!

Troubleshooting

References

👉 Link to Medium blog

Related Posts