1. 环境准备
- 生产环境docker;
- maven
- DK1.8
- gitlab 以及gitlab-runner
总:根据之前的几篇博客,配置好对应的runner,这里 以 test_spring_boot 为runner tag为例说明;
2. 项目目录
在项目跟目录下,创建如下几个文件:
.feature.env --测试环境变量配置文件
.master.env--生产环境变量配置文件
.gitlab-ci.yml--CI/CD核心配置文件
Dockerfile--用于构建Java镜像的文件
如下图所示(注意每个文件前面的点):
3. 文件详细内容解析
a. .feature.env:
#你的spring启动环境
export SPRING_ACTIVE_PROFILE='test'
#推送docker镜像的服务器地址
export DOCKER_REPO_PUSH='192.168.1.26:5000/spring_boot_test'
#拉取docker镜像的服务器地址
export DOCKER_REPO_PULL='192.168.1.26:5000/spring_boot_test'
#Java服务地址
export SERVER_IP='192.168.1.55'
#登录服务器时,用到的key(在gitlab中配置的参数)
export SSH_PRIVATE_KEY="$DEV_SSH_PRIVATE_KEY"
b. .master,env:具体内容同上,注意,生产环境无外网,所以通过跳板进行 登录到部署服务的服务器:
export SPRING_ACTIVE_PROFILE='prod'
export DOCKER_REPO_PUSH='docker镜像服务器外网地址:6500/spring_boot_test'
export DOCKER_REPO_PULL='docker镜像服务器内网地址:6500/spring_boot_test'
export SERVER_IP='部署服务服务器内网地址'
export SPRINGBOARD_IP='跳板机器外网地址'
export SSH_PRIVATE_KEY="$MASTER_SSH_PRIVATE_KEY"
c . Dockerfile:
FROM openjdk:8
MAINTAINER test
ARG JAR_PATH
WORKDIR /app
COPY target/lib /app/lib
COPY $JAR_PATH /app/
EXPOSE 8283
ENTRYPOINT ["java","-jar","-Duser.timezone=GMT+08","-Dloader.path=lib","spring_boot_test.jar"]
d. .gitlab-ci.yml:
# 该文件,会根据你的参数文件,判定分支上有变动,则运行
services:
- docker:20.10.6-dind
variables:
MAVEN_OPTS: "-Dmaven.repo.local=/root/.m2/repository"
# 定义阶段
stages:
- build jar
- build and push docker image
- deploy
# 全局缓存-缓存打包完成的所有jar包
cache: &global_cache
key: ${CI_COMMIT_REF_NAME}"spring_boot_test"
paths:
- .m2/repository/
- target/lib/*.jar
#tags 标记的是使用哪个runner
build:
image: maven:3.8.1-jdk-8-slim
stage: build jar
cache:
# 继承全局缓存配置
<<: *global_cache
tags:
- test_spring_boot
#判断提交分支是否为feature,如果是feature,直接截取分支名的 feature(原分支名:feature/v1.0.0-**)
before_script:
- source .${CI_COMMIT_REF_NAME:0:7}.env
# package时,关闭单元测试,不然会比较耗时
script:
- mvn clean && mvn package -B -e -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE -Dmaven.test.skip=true;
artifacts:
paths:
- target/*.jar
expire_in: 3600 seconds
#docker构建
docker build and push:
image: docker:stable
stage: build and push docker image
tags:
- test_spring_boot
before_script:
- source .${CI_COMMIT_REF_NAME:0:7}.env
script:
- docker build --build-arg JAR_PATH=target/*.jar -t $DOCKER_REPO_PUSH .
- docker push $DOCKER_REPO_PUSH
after_script:
- source .${CI_COMMIT_REF_NAME:0:7}.env
- docker rmi $DOCKER_REPO_PUSH
#部署
deploy:
image: ubuntu:latest
stage: deploy
tags:
- test_spring_boot
before_script:
- source .${CI_COMMIT_REF_NAME:0:7}.env
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- source .${CI_COMMIT_REF_NAME:0:7}.env
script:
- >
if [ "$CI_COMMIT_REF_NAME" == "master" ]; then
ssh -J root@$SPRINGBOARD_IP root@$SERVER_IP "docker stop spring_boot_test;
docker system prune -a -f;
docker pull $DOCKER_REPO_PULL;
docker container run -d \
--name spring_boot_test\
-p 8283:8283 \
-e SPRING_PROFILES_ACTIVE=$SPRING_ACTIVE_PROFILE $DOCKER_REPO_PULL;
docker logout";
else
ssh root@$SERVER_IP "docker stop spring_boot_test;
docker system prune -a -f;
docker pull $DOCKER_REPO_PULL;
docker container run -d \
--name spring_boot_test\
-p 8283:8283 \
-e SPRING_PROFILES_ACTIVE=$SPRING_ACTIVE_PROFILE $DOCKER_REPO_PULL;
docker logout";
fi
说明:本项目中,打包时,是吧lib包单独打出来的,没有放到jar包中,避免jar包过大;
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>target/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
4. 汇总
完成上述配置,当你提交代码时,就会在你的gitlab项目下的ci/cd看到任务的运行了:
在每个环节,可以点击进去,看到相应的日志,包括运行不通过时,可以查看相关报错信息:
5. 常见问题
-
dial tcp: lookup docker on 192.168.1.1:53: no such host
错误。This error occurs with docker-based gitlab runners such as the one we’re that are configured using a docker executor. The error message means that the inner docker container doesn’t have a connection to the host docker daemon.
解决:将
/etc/gitlab-runner/config.toml
中对应的[runners.docker]节点设置privileged = true
,增加卷映射volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
[或|并]在.gitlab-ci.yml的job定义中增加services: - docker:dind;
-
Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?错误
解决:增加卷映射
volumes = ["/certs/client", "/cache"]
,然后在.gitlab-ci.yml中增加变量DOCKER_TLS_CERTDIR: "/certs"
。 -
拉取代码时提示
warning: failed to remove xxxx: Permission denied
简单粗暴地编辑/etc/passwd,将gitlab-runner账号对应的
uid:gid
改为0:0
(和root一样)。
以上,就是gitlab-CI/CD在spring-boot项目中的应用,后续会上传相关代码,请持续关注!
你的努力,终将成为你最有力的资本!