Operations 15 min read

Automate Spring Boot & Vue Deployments with GitLab, Jenkins, Docker, Kubernetes

This guide demonstrates how to integrate GitLab, Jenkins, Docker, Kubernetes, and Helm to achieve fully automated, environment‑specific deployments for Spring Boot backend services and Vue.js front‑end applications, covering configuration files, pipeline scripts, credential setup, and webhook integration for seamless CI/CD across development, testing, and production.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Automate Spring Boot & Vue Deployments with GitLab, Jenkins, Docker, Kubernetes

This article explains how to combine GitLab, Jenkins, Docker, Kubernetes, and Helm to implement automated deployment for a Spring Boot backend project and a Vue.js web project.

Tools and Technologies

GitLab – source code management

Jenkins & Jenkins Pipeline – build and deployment automation

Docker & Dockerfile – container image creation

Kubernetes – container orchestration

Helm – Kubernetes package manager

Environment Background

GitLab branches: develop (dev), pre-release (test), master (prod)

Jenkins service already set up

Docker Registry (Alibaba Cloud or self‑hosted)

Kubernetes cluster ready

Expected Effects

Separate deployment for dev, test, and prod environments, using different namespaces or clusters

Highly reusable configuration – only a few parameters need to be changed per project

Automatic trigger on code push (dev/test) and tag push (prod)

Project Configuration Files

In the project root, add the following files:

Dockerfile

FROM frolvlad/alpine-java:jdk8-slim
# Build‑arg to select profile
ARG profile
ENV SPRING_PROFILES_ACTIVE=${profile}
EXPOSE 8000
WORKDIR /mnt
# Set timezone
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \
    && apk add --no-cache tzdata \
    && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    && apk del tzdata \
    && rm -rf /var/cache/apk/* /tmp/* /var/tmp/* $HOME/.cache
COPY ./target/your-project-name-1.0-SNAPSHOT.jar ./app.jar
ENTRYPOINT ["java", "-jar", "/mnt/app.jar"]

The SPRING_PROFILES_ACTIVE variable can be set at build time with --build-arg profile=xxx to generate environment‑specific images.

Helm Chart Structure

helm                # chart directory name
├── templates       # k8s manifest templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml
├── values.yaml     # configurable values
├── Chart.yaml      # chart metadata
└── charts          # optional sub‑charts (often empty)

Example Chart.yaml:

apiVersion: v2
name: your-chart-name
description: A Helm chart for Kubernetes
type: application
version: 1.0.0
appVersion: 1.16.0

Example values.yaml (only the relevant parts):

replicaCount: 1
image:
  repository: registry.cn-hangzhou.aliyuncs.com/demo/demo
  pullPolicy: Always
  tag: "dev"
imagePullSecrets:
  - name: aliyun-registry-secret
nameOverride: ""
fullnameOverride: ""
container:
  port: 8000
  env: []
serviceAccount:
  create: false
  annotations: {}
  name: ""
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
service:
  type: NodePort
  port: 8000
ingress:
  enabled: true
  hosts:
    - host: demo.com
      paths: ["/demo"]
  tls: []

Jenkinsfile (Pipeline Script)

image_tag = "default"
pipeline {
    agent any
    environment {
        GIT_REPO = "${env.gitlabSourceRepoName}"
        GIT_BRANCH = "${env.gitlabTargetBranch}"
        GIT_TAG = sh(returnStdout: true, script: 'git describe --tags --always').trim()
        DOCKER_REGISTER_CREDS = credentials('aliyun-docker-repo-creds')
        KUBE_CONFIG_LOCAL = credentials('local-k8s-kube-config')
        KUBE_CONFIG_PROD = ""
        DOCKER_REGISTRY = "registry.cn-hangzhou.aliyuncs.com"
        DOCKER_NAMESPACE = "your-namespace"
        DOCKER_IMAGE = "${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/${GIT_REPO}"
        INGRESS_HOST_DEV = "dev.your-site.com"
        INGRESS_HOST_TEST = "test.your-site.com"
        INGRESS_HOST_PROD = "prod.your-site.com"
    }
    parameters {
        string(name: 'ingress_path', defaultValue: '/your-path', description: 'Service context path')
        string(name: 'replica_count', defaultValue: '1', description: 'Number of pod replicas')
    }
    stages {
        stage('Code Analyze') {
            steps { echo "1. Code static analysis" }
        }
        stage('Maven Build') {
            agent { docker { image 'maven:3-jdk-8-alpine' args '-v $HOME/.m2:/root/.m2' } }
            steps {
                echo "2. Build and package"
                sh 'mvn clean package -Dfile.encoding=UTF-8 -DskipTests=true'
            }
        }
        stage('Docker Build') {
            steps {
                echo "3. Build Docker image"
                echo "Image: ${DOCKER_IMAGE}"
                script {
                    def profile = "dev"
                    if (env.gitlabTargetBranch == "develop") {
                        image_tag = "dev.${GIT_TAG}"
                    } else if (env.gitlabTargetBranch == "pre-release") {
                        image_tag = "test.${GIT_TAG}"
                        profile = "test"
                    } else if (env.gitlabTargetBranch == "master") {
                        image_tag = GIT_TAG
                        profile = "prod"
                    }
                    sh "docker build --build-arg profile=${profile} -t ${DOCKER_IMAGE}:${image_tag} ."
                    sh "docker push ${DOCKER_IMAGE}:${image_tag}"
                    sh "docker rmi ${DOCKER_IMAGE}:${image_tag}"
                }
            }
        }
        stage('Helm Deploy') {
            agent { docker { image 'lwolf/helm-kubectl-docker' args '-u root:root' } }
            steps {
                echo "4. Deploy to K8s"
                sh "mkdir -p /root/.kube"
                script {
                    def kube_config = env.KUBE_CONFIG_LOCAL
                    def ingress_host = env.INGRESS_HOST_DEV
                    if (env.gitlabTargetBranch == "pre-release") {
                        ingress_host = env.INGRESS_HOST_TEST
                    } else if (env.gitlabTargetBranch == "master") {
                        ingress_host = env.INGRESS_HOST_PROD
                        kube_config = env.KUBE_CONFIG_PROD
                    }
                    sh "echo ${kube_config} | base64 -d > /root/.kube/config"
                    sh "helm upgrade -i --namespace=${env.gitlabTargetBranch} \
                        --set replicaCount=${params.replica_count} \
                        --set image.repository=${DOCKER_IMAGE} \
                        --set image.tag=${image_tag} \
                        --set nameOverride=${GIT_REPO} \
                        --set ingress.hosts[0].host=${ingress_host} \
                        --set ingress.hosts[0].paths[0]=${params.ingress_path} \
                        ${GIT_REPO} ./helm/"
                }
            }
        }
    }
}

Jenkins Configuration

Create a Pipeline job, set the SCM to pull the Jenkinsfile from the repository, configure the trigger for the develop branch (or pre-release for testing) and generate a token for GitLab webhooks.

Jenkins pipeline configuration
Jenkins pipeline configuration

Add credentials in Jenkins:

Docker Registry credentials (username/password)

Kubernetes kube‑config as a secret text (base64‑encoded ~/.kube/config)

Docker registry credentials
Docker registry credentials
K8s credentials
K8s credentials

GitLab Webhook Configuration

In GitLab project Settings → Integrations, add a webhook with the Jenkins URL and secret token, enable “Push events” for dev/test branches and “Tag push events” for production.

GitLab webhook settings
GitLab webhook settings

Conclusion

The article demonstrates a complete CI/CD pipeline using GitLab, Jenkins, Docker, Kubernetes, and Helm to automate deployment of Spring Boot applications (and can be adapted to other Spring Boot projects). By adjusting the configuration files, the same process can be reused for similar projects.

Footer image
Footer image
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/cdKubernetesGitLabSpring BootJenkinshelm
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

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.