CI/CD#
I won't go into the concept and explanation of CI/CD here, you can read this article for more information.
Why choose GitLab's pipeline#
The reason is simple, the company's code is hosted on GitLab, and GitLab's free quota seems to be quite high.
The reason for not choosing Jenkins is also simple, the UI is outdated, and although it has many features, it also consumes a lot of resources.
If you are a beginner, maybe Drone is also a good choice? After all, it has a visual interface and consumes very little resources.
Register a runner#
If you just want to test or try it out, you can use a shared runner without registering.
But if you want to deploy it on your own server, you must use a registered runner.
There are generally two ways to register a runner:
docker
docker run -d --name gitlab-runner --restart always \\n -v /home/jk/docker/gitlabRunner/config:/etc/gitlab-runner \\n -v /var/run/docker.sock:/var/run/docker.sock \\n gitlab/gitlab-runner:latest
Note that the runner registered using the docker method cannot deploy new containers at the host level. DIND (Docker in Docker) is like adding an extra layer, so it is only suitable for building, not for deployment.
shell
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
sudo gitlab-runner register --url https://gitlab.com/ --registration-token {gitlab registration token}
sudo gpasswd -a gitlab-runner docker
The shell mode can pull and run docker images on the host machine, suitable for deploying services.
For more detailed installation instructions, you can refer to the official documentation.
Create a configuration file#
You can create a configuration file in the Build ---> CI/CD ---> Pipeline Editor of your GitLab project, or use the official configuration template.
The configuration file is named .gitlab-ci.yml
and must be placed in the root directory of the project.
.gitlab-ci.yml
has its specified keywords and format. You can refer to the official syntax documentation for more information.
Here are some commonly used keywords:
Keyword | Description | Usage |
---|---|---|
image | Specify the Docker image required for the pipeline | image: docker:latest |
services | Specify additional images | services:- name: docker:dind |
variables | Define global variables | variables:PORT: 9005 |
stages | Define stages of the pipeline | stages:- build - docker-build |
tags | Specify the runner to be used for this stage | tags: - shell-node |
artifacts | Job artifacts, using the build command will generate files, this keyword can save the built files | artifacts:paths:- target/jk_testing-1.0-SNAPSHOT.jar |
script | Specify the command script to be run in this stage | script:- mvn clean install |
Of course, GitLab also provides a considerable number of variables for use.
For example, $CI_COMMIT_SHORT_SHA
represents the commit's short SHA, and you can also use custom variables in variables
.
You can check all the variables in the official documentation.
I highly recommend using a Dockerfile
to package your project into a Docker image, which will make it easier to manage and deploy.
Example#
Below, I will use a spring boot
project to explain the configuration file to you. I will try to add comments.
# Specify the Docker image required for the pipeline
image: docker:latest
# Specify additional images
services:
- name: docker:dind
# Define variables
variables:
PORT: 9005
APPLICATION_NAME: test
# Define stages of the pipeline
stages:
- build
- docker-build
- deploy
- notify
# Build stage: execute Maven build
build:
image: maven:3.6.3-openjdk-8
stage: build
# Define the script to be executed
script:
- mvn clean install
artifacts:
paths:
- target/jk_testing-1.0-SNAPSHOT.jar
# Docker build stage: build Docker image and push it to the image registry
docker-build:
stage: docker-build
script:
- docker build -t $APPLICATION_NAME .
- docker tag $APPLICATION_NAME $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
# Deploy stage: rolling update of the image
deploy:
stage: deploy
# Specify a shell runner
tags:
- shell-node
script:
# Define multiple scripts
# Stop the container with the name containing "test", then remove the container and image
# Then pull the latest image from the image registry and run it
- >
if [[ $(docker ps -q -f name=$APPLICATION_NAME) ]]; then
docker stop $APPLICATION_NAME 2>/dev/null;
docker rm $APPLICATION_NAME 2>/dev/null;
docker images | grep test | awk '{print $3}' | xargs -I {} docker rmi {};
fi
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker run -d -p $PORT:9004 --name $APPLICATION_NAME $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
# Notification message when the build fails
notifyFailWeChat:
stage: notify
script:
- apk add curl
- curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key= {WeChat robot token}' -H 'Content-Type:application/json' -d "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"Mini Program project build result: <font color=\\"warning\\">Failed</font>\n>This build was triggered by: $GITLAB_USER_NAME\n>Project name: $CI_PROJECT_NAME\n>Commit SHA: $CI_COMMIT_SHA\n>Commit message: $CI_COMMIT_MESSAGE\n>Build branch: $CI_COMMIT_BRANCH\n>Pipeline URL: [$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}"
# Only run on the master branch
only:
- master
# Specify when to execute, in this case, it will be executed when the pipeline build fails
when: on_failure
# Notification message when the build succeeds
notifySuccessWeChat:
stage: notify
script:
- apk add curl
- curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key= {WeChat robot token}' -H 'Content-Type:application/json' -d "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"Mini Program project build result: <font color=\\"info\\">Success</font>\n>This build was triggered by: $GITLAB_USER_NAME\n>Project name: $CI_PROJECT_NAME\n>Commit SHA: $CI_COMMIT_SHA\n>Commit message: $CI_COMMIT_MESSAGE\n>Build branch: $CI_COMMIT_BRANCH\n>Pipeline URL: [$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}"
only:
- master
when: on_success