对于 Jenkins 我只能用两个字形容,难用。就不过多吐槽了,本篇是基于 docker 环境的使用
寻找需要的 Jenkins 镜像:https://hub.docker.com/r/jenkinsci/blueocean
docker pull jenkinsci/blueocean
我选择的镜像是 Jenkins-blueocean Jenkins 海洋版,为什么选这个?
启动镜像
docker run --name jenkinsci-blueocean -u root --rm -d -p 7005:8080 -p 50000:50000 -v /data/jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
附带下删除 jenkinsci/blueocean 容器
# 删除对应绑定网桥
docker network disconnect --force bridge jenkinsci-blueocean
# 删除 jenkinsci-blueocean 容器,xxxx 容器 ID
docker rm -f xxxx
输入密码进入
由于我们挂载映射到服务器,所以可以直接通过服务器路径找密码
cat /data/jenkins/secrets/initialAdminPassword
或者直接通过容器日志可以看到密码:docker logs xxxx(容器 ID)
接下来,我选择推荐插件安装
创建第一个账号,我用的 root 123456
然后完成安装,由于是用的是镜像,所以安装起来非常的简单,海洋版也没有出现插件无法下载的问题
踩坑PS:为什么说难用,就是在这。一开始我是把 jdk 和 maven 也挂载到容器里的,但是配置完全局变量后,根本无法使用,可能是容器内也要配置好这些才行,我就搞不懂容器内配了那还要专门配个全局环境变量干啥。。。自动安装也是完全没用,所以我放弃了,用我自己的方法进行持续集成部署。
接下来配置项目,选择流水线
配置
这里我们通过 webhook,让项目提交后,自动调用钩子函数进行部署,进行持续集成
配置构建触发器,也就是钩子函数
身份验证令牌自己写的,所以这里钩子函数的路径就是
http://127.0.0.1:7005/job/spring-cloud/build?token=123456
PS:身份验证令牌框下面就是钩子函数的请求路径说明,不太明白的,可以自己看看,我上面给的这个是示例
配置项目
公私密钥的可参考:https://blog.csdn.net/weixin_41235146/article/details/81780894
然后保存,这里暂时就配好了
root 创建 API token
记住这串 token,后面要和钩子函数一起使用,离开这个页面后再进入就看不到这串 token 了
系统管理 => 全局安全配置
PS踩坑:这里不配置的话,后面钩子函数的请求都会 403 失败
接下来配置钩子函数的请求了,这里以 gitee 为例
进入项目 => 管理 => WebHook
请求历史可以看到请求成功 201
先说下本人用于测试的这个项目是父子项目,打包时候把每个子项目打成 jar 包,然后通过 Dockerfile 生产 docker 镜像,然后启动镜像生成容器,这就是我的部署流程
项目根目录下新增 Jenkinsfile
PS踩坑:由于 maven 配置不成功,我也不想进容器配置 maven,因为服务器才 1G ,进容器就死机了,所以我改了依赖 maven 镜像部署,然后再通过另一个任务把 jar 包生成镜像,因为 maven 容器里没有 docker 环境
思路:
package:利用 docker 镜像构建 maven 环境,然后让项目打包,因为 Jenkins 是在容器内的,里面没有 maven 环境,虽说是在 docker 另一个容器环境内打包,但是 Jenkins 会自动把他挂到自己项目下的某个路径里。
build:由于已经打包完成,我们就不需要 maven 环境了,因此后续直接在 Jenkins 容器里操作即可,对项目打包镜像,发布运行
pipeline {
agent any
stages {
stage('package') {
agent {
docker {
image 'maven:3-alpine'
args '-v /root/.m2:/root/.m2 -v /data/maven/apache-maven-3.6.0/conf/settings.xml:/root/.m2/settings.xml --entrypoint='
}
}
steps {
script{
echo "WORKSPACE:${env.WORKSPACE}"
echo "Branch:${env.NODE_NAME}"
if ("${env.NODE_NAME}" == "master") {
sh "sh package-prod.sh"
}
}
}
}
stage('build') {
agent none
steps {
script{
echo "WORKSPACE:${env.WORKSPACE}"
echo "Branch:${env.NODE_NAME}"
if ("${env.NODE_NAME}" == "master") {
sh "sh build-prod.sh"
}
}
}
}
}
}
先 pull 个 maven 镜像,以及在构建镜像时候所需要的 jdk8 的镜像
# maven:3-alpine 用于 Jenkins 构建有 maven 环境的容器
# Jenkins 官方提供的 maven 镜像,能避免不少问题
# 不自己 pull 也行,会自动 pull
docker pull maven:3-alpine
# jdk8 的镜像用于 Dockerfile 中设置构建拥有 jdk8 环境镜像的基础镜像
docker pull kdvolder/jdk8
Jenkins 内置环境变量可参考:https://www.cnblogs.com/puresoul/p/4828913.htm
可以看到,我这部署先判度为 master 分支的情况下,package 任务中调用脚本进行打包,build 任务下调用脚本部署
下面贴下这两个脚本,大伙可以参考下
package-prod.sh
#!/bin/sh
#进入文件根目录
#cd "$WORKSPACE"
#项目打包
mvn clean install package '-Dmaven.test.skip=true'
build-prod.sh
#!/bin/sh
#进入文件根目录
#cd "$WORKSPACE"
#启用 prod 配置
ActiveProfiles=prod
#基本信息需要配置
#内部端口
targetPort=8081
#旧镜像版本号
oldVendor=1.0.0
#镜像版本号
vendor=1.0.0
#项目名
projectName=eureka
#进入target文件夹
#直接的构建是再容器里,这个是在 Jenkins 容器里,所以空间不一样
#容器的空间是原空间路径后面多了 @2
cd $WORKSPACE@2/$projectName/target
#创建Dockerfile文件
#-jar -Duser.timezone=GMT+08 保证生成出来的容器的时区与服务器一致
cat << EOF > Dockerfile
FROM kdvolder/jdk8
MAINTAINER $projectName
VOLUME /tmp
LABEL app="$projectName" version="$vendor" by="$projectName"
COPY $projectName.jar $projectName.jar
EXPOSE $targetPort
CMD -Xmx100m -Xms100m -jar -Duser.timezone=GMT+08 $projectName.jar --spring.profiles.active=$ActiveProfiles
ENTRYPOINT java
EOF
#删除镜像下所有容器
docker rm -f $(docker ps -a | grep "$projectName" | awk '{print $1}')
#删除旧镜像
docker rmi -f $projectName:$oldVendor
#创建镜像
docker build -t $projectName:$vendor .
#启动镜像生成容器
docker run --name $projectName -d -p $targetPort:$targetPort $projectName:$vendor
我写配置喜欢统一性配置,后面改起来简单,上面参数换下下面都不需要改,这里我的文件夹名,镜像名和生产的 jar 名都用一样的也是这个目的
打包成功,这画面看的好看不少