背景
简单记录下Spring boot项目通过maven自动打包,然后打镜像的的Gitlab ci流程
Gitlab Runner部署
Runner是实际的Job运行者,可以直接部署在主机上,也可以直接容器部署
这里为了方便,Gitlab Runner就直接用docker容器部署了
docker run -d --name xxx-public-runner --restart always -v /data/ci_xxx_public/gitlab/runner/:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock -v /data:/data gitlab/gitlab-runner:latest
这里的第一个挂载是为了runner配置的持久化;
下面是一份配置,指向的是Gitlab代码库,并且指定了使用容器方式运行我们的任务
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "xxx-public-runner"
url = "https://git.sysop.xxx.xx/"
token = "9TfGzxxxxxxxxxxxxWbks"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "alpine:3.16.2"
pull_policy = "if-not-present"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache","/var/run/docker.sock:/var/run/docker.sock","/root/.m2:/.m2"]
shm_size = 0
-
这里的
/var/run/docker.sock
挂载是为了共享宿主机上的docker文件,这样Gitlab Runner使用容器运行任务的时候,将会直接和宿主机上的dockerd交互;而不需要使用dind方式; -
第三个挂载是为了共享宿主机上的maven依赖,避免每次都要重新下载依赖;
代码修改
上述Runner部署完成后,还需要对代码进行修改,主要是添加Gitlab的配置文件.gitlab-ci.yml;容器化部署的时候还需要添加Dockerfile文件
Dockerfile
FROM myharbor.xxx.com:80/library/jdk:8u292-jdk-jfx
WORKDIR /work
COPY my-web/target/my-web-0.0.1-SNAPSHOT.jar /work/bin/
COPY my-web/src/main/resources/log4j2.yml my-web/src/main/resources/application-test.properties my-web/src/main/resources/application-prod.properties my-service/src/main/resources/application-servicetest.properties my-service/src/main/resources/application-serviceprod.properties /work/conf/
ENTRYPOINT ["java", "-jar", "./bin/my-web-0.0.1-SNAPSHOT.jar"]
CMD ["-Xms4096m", "-Xmx4096m", "-Xmn2048m", "-Dfile.encoding=UTF-8", "-Dsun.net.inetaddr.ttl=5", "-Dsun.net.inetaddr.negative.ttl=1", "-Dlog4j.configurationFile=./conf/log4j2.yml", "--spring.profiles.active=test,servicetest", "--spring.config.location=./conf/", "--server.port=8334", "--cas.default.domain=https://my-public.xxx.com"]
这里的基础镜像是自定义的,主要是为了解决项目中使用JFX相关的工具类,这个自定义也比较简单,只需要往openjdk中加入JFX的依赖即可,它的构建Dockerfile:
FROM openjdk:8u292-jdk
COPY jfxrt.jar /usr/local/openjdk-8/jre/lib/ext/
其次Gitlab的配置文件.gitlab-ci.yml,这份配置文件是CI工作的关键
image: alpine:3.17.1
# 本次构建的阶段:build package
stages:
- package
- build
# 生产jar的job
make_jar:
image: myharbor.xxx.com:80/library/maven:3.8.6-jdk-8-jfx
stage: package
rules:
- if: '$CI_PIPELINE_SOURCE == "web" && $CI_COMMIT_BRANCH == "dev"'
tags:
- my-public-runner
script:
- echo "=============== 开始编译 ==============="
- mvn -Dmaven.repo.local=/.m2/repository -Dmaven.test.skip=true clean package
- echo "=============== 编译完成 ==============="
artifacts:
paths:
- my-web/target/my-web-0.0.1-SNAPSHOT.jar
expire_in: 30 days
# 生产镜像的job
make_image:
image: docker:20.10.7
stage: build
rules:
- if: '$CI_PIPELINE_SOURCE == "web" && $CI_COMMIT_BRANCH == "dev"'
tags:
- my-public-runner
script:
- echo "target文件夹" `ls my-web/target/`
- echo "=============== login==============="
- echo $HARBOR_PWD | docker login $HARBOR_URL -u $HARBOR_USER --password-stdin
- echo "=============== build =============="
- docker build -t $HARBOR_URL/library/my_public_be:$CI_COMMIT_SHORT_SHA .
- echo "=============== push==============="
- docker push $HARBOR_URL/library/my_public_be:$CI_COMMIT_SHORT_SHA
- echo "=============== logout==============="
- docker logout $HARBOR_URL
- echo "clear"
- rm -rf my-web/target/my-web-0.0.1-SNAPSHOT.jar
这份配置文件主要指定了CI流程包括两步:
-
打包:这一步主要是启动一个maven容器,对项目代码进行打包,生成jar文件
-
镜像:这一步主要是启动一个docker cli容器,读取我们的Dockerfile,并使用第一步中生成的jar包,然后构建镜像并推送;由于我们挂载了宿主机上的dockerd文件,因此会直接在宿主机上创建一个容器来运行Job
简单说明:
-
使用的基础镜像,如 myharbor.xxx.com:80/library/maven:3.8.6-jdk-8-jfx 都是重新构建出来的,因为都必须加入jfx依赖
-
都指定了条件
$CI_PIPELINE_SOURCE == "web" && $CI_COMMIT_BRANCH == "dev"
,仅在dev分支触发,并且只能从web触发 -
$HARBOR_URL
这些参数是直接定义在Gitlab上面的
踩坑
-
$HARBOR_PWD
也是直接定义在Gitlab上的,如果密码中包含$
字符,需要转义,如$anc
需要写成$$anc
网友评论