Jenkins官网:https://www.jenkins.io/zh/download/
docker pull jenkins/jenkins:2.346.1
创建
jenkins_home
文件夹
赋予
jenkins_home
文件夹访问权限
chown -R 1000 /software/jenkins/jenkins_home/
chmod 777 jenkins_home
赋予
/var/run/docker.sock
文件访问权限
chmod 777 /var/run/docker.sock
docker run -d -m 2g -p 8600:8080 -p 50000:50000 \
--restart=always \
-v /home/software/jenkins/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
--name jenkins \
jenkins/jenkins:2.346.1
-d
: 后台启动-m
: 设置内存大小(m-M,g-G
)-u
: 使用管理员权限启动--restar=always
: 开机启动,失败也会一直重启-p
: 映射端口-v
: 挂载数据卷
/var/jenkins_home
: jenkins
挂载目录/var/run/docker.sock
: 外部docker
挂载目录/usr/bin/docker
: 外部docker
启动目录--name
: 容器名称进入
jenkens
容器内部,查看docker是否挂载成功
docker exec -it jenkins /bin/bash
docker version
IP:8600
启动jenkins并初始化/var/jenkins_home/secrets/initiaAdminPassword
点击
Manage Jenkins
(系统管理) ->Manage Plugins
(插件管理)
maven
插件
Publish Over SSH
和SSH
插件
安装完插件,重启
Jenkins
下载maven3.8.6版本并上传到jenkins文件夹下
mkdir /software/jenkins/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation
修改maven3.8.6
文件夹下面的conf
文件夹下面的settings.xml
,修改下载源
<mirror>
<id>alimavenid>
<name>aliyun mavenname>
<url>
http://maven.aliyun.com/nexus/content/groups/public/
url>
<mirrorOf>centralmirrorOf>
mirror>
给mvn命令添加权限
chmod a+x /software/jenkins/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation/maven3.8.6/bin/mvn
系统管理 -> 全局工具配置 ->
maven
系统管理 -> 系统配置 -> 环境变量
MAVEN_HOME
/var/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation/maven3.8.6
PATH+EXTRA
$MAVEN_HOME/bin
系统管理 -> 系统配置 ->
Publish over SSH
设置jenkins时区
新增流水线
勾选参数化构建过程,添加字符参数和选项参数
添加流水线使用Jenkinsfile文件配置
test-cloud
|-test-common
|-test-common-cloud
|-test-common-mybatisplus
|-test-common-redis
|-test-common-spring
|-test-common-swagger
|-test-common-tool
|-test-seata
|-test-seata-account
|-src
|-Dockerfile
|-pom.xml
|-test-seata-order
|-src
|-Dockerfile
|-pom.xml
|-test-seata-storage
|-src
|-Dockerfile
|-pom.xml
|-pom.xml
|-Jenkinsfile
|-pom.xml
Jenkinsfile
文件node {
def mvnHome
stage('测试') {
sh "echo 测试流水线Jenkinsfile文件"
}
}
Jenkins的选择
立即构建
,查看构建结果
流水线项目 -> 流水线语法 ->
checkout: Check out from version control
-> 复制流水线脚本
编辑
Jenkinsfile
文件,添加拉取代码
node {
def mvnHome
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '2524582f-70ea-4384-a607-06e4c82a971f', url: 'https://gitee.com/lingjian1027/test-cloud.git']]])
}
}
添加
Dockerfile
文件,在每个微服务中都需要添加
FROM openjdk:8-jdk-oraclelinux8
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
在
pom.xml
文件中添加maven
打包命令,在每个微服务中都需要添加
<version>1.0.0version>
<build>
<finalName>test-seata-accountfinalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<artifactId>maven-resources-pluginartifactId>
<configuration>
<encoding>utf-8encoding>
<useDefaultDelimiters>trueuseDefaultDelimiters>
configuration>
plugin>
<plugin>
<groupId>com.spotifygroupId>
<artifactId>dockerfile-maven-pluginartifactId>
<version>1.4.10version>
<executions>
<execution>
<id>defaultid>
<goals>
<goal>buildgoal>
<goal>pushgoal>
goals>
execution>
executions>
<configuration>
<repository>${project.build.finalName}repository>
<tag>${project.version}tag>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jarJAR_FILE>
buildArgs>
configuration>
plugin>
plugins>
build>
编辑
Jenkinsfile
文件,添加maven打包
node {
def mvnHome
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '2524582f-70ea-4384-a607-06e4c82a971f', url: 'https://gitee.com/lingjian1027/test-cloud.git']]])
}
stage('编译,打包微服务工程') {
// 编译打包
sh "mvn clean install"
}
}
添加全局
docker
凭证: 系统管理 -> Manage Credentials -> 全局 -> 添加凭证
流水线项目 -> 流水线语法 ->
withCredentials: Bind credentials to variables
-> 绑定新增(Username and password (separated)
)
编辑
Jenkinsfile
文件,添加上传镜像
def tag = "1.0.7"
def aliyun_url = "registry.cn-hangzhou.aliyuncs.com"
def aliyun_project = "testcloud1"
def storage = "test-seata-storage"
def order = "test-seata-order"
def account = "test-seata-account"
node {
def mvnHome
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '2524582f-70ea-4384-a607-06e4c82a971f', url: 'https://gitee.com/lingjian1027/test-cloud.git']]])
}
stage('编译,打包微服务工程') {
// 编译打包
sh "mvn clean install"
}
stage('上传镜像') {
sh "docker version"
// 定义镜像名称
def storageName = "test-seata-storage:${tag}"
def orderName = "test-seata-order:${tag}"
def accountName = "test-seata-account:${tag}"
withCredentials([usernamePassword(credentialsId: '034e0cb5-d092-4d59-a3d9-2df6b47cc47e', passwordVariable: 'password', usernameVariable: 'username')]) {
// some block
sh "docker login --username=${username} --password=${password} ${aliyun_url}"
sh "docker tag ${storageName} ${aliyun_url}/${aliyun_project}/${storageName}"
sh "docker tag ${orderName} ${aliyun_url}/${aliyun_project}/${orderName}"
sh "docker tag ${accountName} ${aliyun_url}/${aliyun_project}/${accountName}"
sh "docker push ${aliyun_url}/${aliyun_project}/${storageName}"
sh "docker push ${aliyun_url}/${aliyun_project}/${orderName}"
sh "docker push ${aliyun_url}/${aliyun_project}/${accountName}"
sh "echo 镜像上传成功"
sh "docker rmi ${storageName}"
sh "docker rmi ${orderName}"
sh "docker rmi ${accountName}"
sh "echo 删除原始镜像成功"
}
}
}
流水线项目 -> 流水线语法 ->
sshPublisher: Send build artifacts over SSH
-> 生成流水线脚本
编辑
Jenkinsfile
文件,添加应用部署
注意
:execCommand: "/software/project/deploy.sh $tag"
,后面的路径必须由单引号改为双引号,不然外部传参,无法传参
def tag = "1.0.7"
def aliyun_url = "registry.cn-hangzhou.aliyuncs.com"
def aliyun_project = "testcloud1"
def storage = "test-seata-storage"
def order = "test-seata-order"
def account = "test-seata-account"
node {
def mvnHome
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '2524582f-70ea-4384-a607-06e4c82a971f', url: 'https://gitee.com/lingjian1027/test-cloud.git']]])
}
stage('编译,打包微服务工程') {
// 编译打包
sh "mvn clean install"
}
stage('上传镜像') {
sh "docker version"
// 定义镜像名称
def storageName = "test-seata-storage:${tag}"
def orderName = "test-seata-order:${tag}"
def accountName = "test-seata-account:${tag}"
withCredentials([usernamePassword(credentialsId: '034e0cb5-d092-4d59-a3d9-2df6b47cc47e', passwordVariable: 'password', usernameVariable: 'username')]) {
// some block
sh "docker login --username=${username} --password=${password} ${aliyun_url}"
sh "docker tag ${storageName} ${aliyun_url}/${aliyun_project}/${storageName}"
sh "docker tag ${orderName} ${aliyun_url}/${aliyun_project}/${orderName}"
sh "docker tag ${accountName} ${aliyun_url}/${aliyun_project}/${accountName}"
sh "docker push ${aliyun_url}/${aliyun_project}/${storageName}"
sh "docker push ${aliyun_url}/${aliyun_project}/${orderName}"
sh "docker push ${aliyun_url}/${aliyun_project}/${accountName}"
sh "echo 镜像上传成功"
sh "docker rmi ${storageName}"
sh "docker rmi ${orderName}"
sh "docker rmi ${accountName}"
sh "echo 删除原始镜像成功"
}
}
stage('拉取镜像并应用部署') {
sh "echo 应用部署"
sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/software/project/deploy.sh $tag", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
在服务器的
/software/project
目录下面添加deploy.sh
执行文件
#!/bin/bash
#接收外部参数,$1对应第一个参数,$2对应第二个参数,参数之间使用空格分割
tag=$1
aliyun_url='registry.cn-hangzhou.aliyuncs.com'
aliyun_project='testcloud1'
storage='test-seata-storage'
order='test-seata-order'
account='test-seata-account'
storageName=${aliyun_url}/${aliyun_project}/${storage}:${tag}
orderName=${aliyun_url}/${aliyun_project}/${order}:${tag}
accountName=${aliyun_url}/${aliyun_project}/${account}:${tag}
echo "${tag}" >> /software/project/log.txt
echo "storageName ${storageName}" >> /software/project/log.txt
echo "orderName ${orderName}" >> /software/project/log.txt
echo "accountName ${accountName}" >> /software/project/log.txt
#删除镜像
storageImageId=`docker images -q --filter reference=${storageName}`
if [ "$storageImageId" != "" ]; then
#删除镜像
docker rmi -f $storageImageId
echo "成功删除storage镜像"
fi
orderImageId=`docker images -q --filter reference=${orderName}`
if [ "$orderImageId" != "" ]; then
#删除镜像
docker rmi -f $orderImageId
echo "成功删除order镜像"
fi
accountImageId=`docker images -q --filter reference=${accountName}`
if [ "$accountImageId" != "" ]; then
#删除镜像
docker rmi -f $accountImageId
echo "成功删除account镜像"
fi
#登录docker
docker login --username=剑灵服务器3 --password=ling10jian1992 ${aliyun_url}
# 拉取镜像
docker pull ${storageName}
docker pull ${orderName}
docker pull ${accountName}
#查询容器是否存在,存在则删除
storageContainerId=`docker ps -aq --filter name=${storage}`
if [ "$storageContainerId" != "" ]; then
#停掉容器
docker stop $storageContainerId
#删除容器
docker rm $storageContainerId
echo "成功删除storage容器"
fi
orderContainerId=`docker ps -aq --filter name=${order}`
if [ "$orderContainerId" != "" ]; then
#停掉容器
docker stop $orderContainerId
#删除容器
docker rm $orderContainerId
echo "成功删除order容器"
fi
accountContainerId=`docker ps -aq --filter name=${account}`
if [ "$accountContainerId" != "" ]; then
#停掉容器
docker stop $accountContainerId
#删除容器
docker rm $accountContainerId
echo "成功删除account容器"
fi
# 启动容器
docker run -d -p 8882:8882 -m 512m --name ${account} ${accountName}
docker run -d -p 8881:8881 -m 512m --name ${order} ${orderName}
docker run -d -p 8883:8883 -m 512m --name ${storage} ${storageName}
下载
gitee
插件,安装完成后重启Jenkins
ngrok官网地址:https://ngrok.com/
注册账号并下载Linux版本
上传服务器,启用并映射
IP:8600
端口
tar xvzf ngrok-v3-stable-linux-amd64.tgz -C /usr/local/bin
ngrok config add-authtoken <token>
ngrok http 192.168.80.128:8600
Generic Webhook Trigger
apiToken
Generic Webhook Trigger
的Post content parameters
中添加参数ref
$.ref // 勾选JSONpath
Optional filter
添加正则匹配^refs/heads/(test|main)$
$ref
点击
Manage Jenkins
(系统管理) ->Manage Plugins
(插件管理) -> 可选插件(DingTalk)
在钉钉中创建钉钉群,并设置机器人
点击
Manage Jenkins
(系统管理) ->Configure System
(系统配置) -> 钉钉
在流水线中勾选钉钉,即可使用
下载
nodejs16.15.1
包并上传到jenkins_home
文件夹下面
系统管理 -> 全局工具配置 -> NodeJs
node {
def mvnHome
stage('测试vue') {
}
}
流水线项目 -> 流水线语法 ->
checkout: Check out from version control
-> 复制流水线脚本
编辑Jenkinsfile文件,添加拉取代码
node {
def mvnHome
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/test']], extensions: [], userRemoteConfigs: [[credentialsId: '2b610a7f-5a1a-4d0c-8f93-29aabe182c88', url: 'https://codeup.aliyun.com/6191d29d38b0ff04d2a421d4/huameng_safe_product/safe-product-web.git']]])
}
}
流水线项目 -> 流水线语法 ->
nodejs: Provide Node & npm bin/folder to PATH
-> 复制流水线脚本
编辑Jenkinsfile文件,添加nodejs打包
node {
def mvnHome
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/test']], extensions: [], userRemoteConfigs: [[credentialsId: '2b610a7f-5a1a-4d0c-8f93-29aabe182c88', url: 'https://codeup.aliyun.com/6191d29d38b0ff04d2a421d4/huameng_safe_product/safe-product-web.git']]])
}
stage('打包,部署vue项目') {
nodejs('nodejs16') {
sh "npm install"
sh "npm run build:stage"
}
}
}
流水线项目 -> 流水线语法 ->
sshPublisher: Send build artifacts over SSH
-> 生成流水线脚本
编辑Jenkinsfile文件,添加上传服务器
sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/home/projects/server', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])