Docker方式部署Jenkins
部署自定义Docker网络
部署Docker网络的作用:
- 隔离性
- 便于同一网络内容器相互通信
# 创建名为jenkins的docker网络
docker network create --subnet 172.18.0.0/16 --gateway 172.18.0.1 jenkins
# 查看docker网络列表
docker network ls
# 查看名为jenkins的docker网络详情
docker network inspect jenkins
部署Jenkins
拉取镜像
docker pull hub.rat.dev/jenkins/jenkins:lts-jdk17
运行容器
docker run \
--name jenkins \
--restart=on-failure \
--detach \
--network jenkins \
--env DOCKER_HOST=tcp://docker:2376 \
--env DOCKER_CERT_PATH=/certs/client \
--env DOCKER_TLS_VERIFY=1 \
--publish 8088:8080 \
--publish 50000:50000 \
--volume jenkins-data:/var/jenkins_home \
--volume jenkins-docker-certs:/certs/client:ro \
hub.rat.dev/jenkins/jenkins:lts-jdk17
参数解析
- –name jenkins:
- 为容器指定一个名称,这里是 jenkins。
- –restart=on-failure:
- 配置容器的重启策略。如果容器因错误退出(非正常退出),Docker 将自动重启它。
- –detach:
- 在后台运行容器,而不是在前台运行。这使得容器在后台持续运行,而不会阻塞终端。
- –network jenkins:
- 将容器连接到一个名为 jenkins 的 Docker 网络。这通常用于容器之间的通信。
- –env DOCKER_HOST=tcp://docker:2376:
- 设置环境变量 DOCKER_HOST,指定 Docker 守护进程的地址。这里指向 docker 服务的 2376 端口。
- –env DOCKER_CERT_PATH=/certs/client:
- 设置环境变量 DOCKER_CERT_PATH,指定 Docker 客户端证书的路径。证书用于 TLS 验证。
- –env DOCKER_TLS_VERIFY=1:
- 设置环境变量 DOCKER_TLS_VERIFY,启用 TLS 验证。这确保了与 Docker 守护进程的通信是安全的。
- –publish 8088:8080:
- 将容器的 8080 端口映射到宿主机的 8088 端口。Jenkins 的 Web 界面通常运行在 8080 端口。
- –publish 50000:50000:
- 将容器的 50000 端口映射到宿主机的 50000 端口。这是 Jenkins 用于与代理节点通信的端口。
- –volume jenkins-data:/var/jenkins_home:
- 将宿主机的 jenkins-data 卷挂载到容器的 /var/jenkins_home 目录。这是 Jenkins 的主目录,用于存储配置文件、插件和构建历史。
- –volume jenkins-docker-certs:/certs/client:ro:
- 将宿主机的 jenkins-docker-certs 卷挂载到容器的 /certs/client 目录,并设置为只读(ro)。这个卷包含用于 TLS 验证的客户端证书。
- hub.rat.dev/jenkins/jenkins:lts-jdk17:
- 指定要运行的 Docker 镜像。这里是 hub.rat.dev/jenkins/jenkins 镜像的 lts-jdk17 版本。
这段命令的作用是:
- 启动一个名为 jenkins 的 Jenkins 容器。
- 配置了重启策略、网络连接、环境变量、端口映射和卷挂载。
- 使用了 TLS 验证来确保与 Docker 守护进程的安全通信。
- 将 Jenkins 数据持久化到宿主机的卷中,以便在容器重启后数据不会丢失。
- 这个配置通常用于在 Docker 环境中运行 Jenkins,并确保其能够安全地与 Docker 守护进程通信。
访问Jenkins
打开浏览器,输入URL:http://${server_url}:8088
,安装Jenkins推荐插件,例如:Git、Publish Over SSH 等。
配置环境
Java
查询自带JDK
Docker方式安装Jenkins,容器内部已经自带了Java环境,可以进入容器内部查看
jenkins@192.168.100.102:~$ sudo docker exec -it jenkins /bin/bash
[sudo] password for jenkins:*****(输入密码)
jenkins@cc89b70ab9ae:/$ java -version
openjdk version "17.0.15" 2025-04-15
OpenJDK Runtime Environment Temurin-17.0.15+6 (build 17.0.15+6)
OpenJDK 64-Bit Server VM Temurin-17.0.15+6 (build 17.0.15+6, mixed mode)
配置其他JDK版本
如果想要使用其他JDK版本,可以在 Manage Jenkins -> Tools 中配置(这里演示配置 JDK1.8版本)。
下载JDK
上传到容器
先将 jdk 上传到服务器(例如:上传到了 /home/jdk
),然后拷贝到容器中(这里也可以直接拷贝到挂载目录下)
cd /home/jdk
# 拷贝到jenkins容器,目录自定义
$ sudo docker cp jdk-8u202-linux-x64.tar.gz jenkins:/var/jenkins_home/tools/hudson.model.JDK/JDK1.8
# 进入容器内部
$ sudo docker exec -it jenkins /bin/bash
# 解压
$ cd /var/jenkins_home/tools/hudson.model.JDK/JDK1.8
$ tar -zxvf jdk-8u202-linux-x64.tar.gz
$ mv jdk-8u202-linux-x64/* ./
$ rm jdk-8u202-linux-x64.tar.gz
在 Jenkins 控制台配置
进入 Manage Jenkins -> Tools 。
Git
Docker方式安装Jenkins,容器内部已经自带了Git环境,这里就不配置其他版本了。
查询自带Git
可以进入容器内部查看
jenkins@192.168.100.102:~$ sudo docker exec -it jenkins /bin/bash
[sudo] password for jenkins:*****(输入密码)
jenkins@cc89b70ab9ae:/$ git --version
git version 2.39.5
Maven
下载Maven
Maven需要自己安装,这里演示安装Maven 3.9.10 版本。同样也是在 Manage Jenkins -> Tools 中配置
查看Maven安装路径
# 进入容器内部
$ sudo docker exec -it jenkins /bin/bash
jenkins@cc89b70ab9ae:~$ cd /var/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation
jenkins@cc89b70ab9ae:~/tools/hudson.tasks.Maven_MavenInstallation$ ls
Maven_3.9.10
jenkins@cc89b70ab9ae:~/tools/hudson.tasks.Maven_MavenInstallation/Maven_3.9.10$ ls Maven_3.9.10
LICENSE NOTICE README.txt bin boot conf lib
配置SSH Server目标服务器
可以有两种方式配置:
- 账号密码方式
- 公私钥方式
这里介绍一下 公私钥方式(密码方式直接输入相关密码即可)
生成公私钥
############ 在Jenkins容器中生成公私钥 ################
# 进入容器内部
$ docker exec -it jenkins /bin/bash
# 生成路径:/var/jenkins_home/.ssh
jenkins@cc89b70ab9ae:~$ ssh-keygen -t rsa -b 4096
jenkins@cc89b70ab9ae:~$ cd .ssh
jenkins@cc89b70ab9ae:~/.ssh$ ls
id_rsa id_rsa.pub
############# 拷贝公钥内容,将其放在目标服务器的 ~/.ssh/authorized_keys 文件下 ##############
$ cd ~/.ssh
# 目录不存在直接新建即可,然后将公钥拷贝进去
$ vim authorized_keys
Jenkins控制台配置SSH Server
进入 Manage Jenkins >> System >> Publish over SSH
配置凭证
在 Jenkins控制台 >> Manage Jenkins >> Credentials >> System >> Global credentials (unrestricted) 中配置
配置Git仓库指纹凭证
后续从Git仓库拉取代码会需要用到
配置SSH Server凭证
与前面提到的 配置SSH Server目标服务器 相比,可以理解为:有些SSH插件可以用上面那种,这种是通用的。
部署Pipeline任务
项目部署到目标服务器上,以系统服务方式运行
在这里编写
Pipeline Script
在Jenkins控制台手动触发
第一版使用了 sshPublisher 命令,这个命令用到了 Publish over SSH 配置,但是这个命令在 Jenkins控制台不会打印日志。
pipeline {
agent any
parameters {
string(name: 'VERSION', description: '请输入jar包版本号 (例如: 1.0.0)')
string(name: 'GIT_BRANCH', description: '请输入部署分支 (例如: master)')
}
environment {
BASE_JAR_NAME = "jenkins-study" // jar包名称,根据实际项目修改
GIT_REPO = 'https://xxx.git' // 替换为Git仓库地址
GIT_CRE_ID = "xxx" // git指纹凭证ID
SSH_SERVER = 'test_server' // ssh server名称
DEPLOY_PATH = '/home/projects/xxx' // 替换为目标服务器的项目部署路径
// jar包以系统服务方式运行
MDM_SYSTEM_SVC = 'xxxx.service'
}
tools {
jdk 'JDK1.8' // jdk版本号
maven 'Maven 3.9.10' // 使用全局工具配置中定义的 Maven
}
stages {
stage('拉取代码') {
steps {
git branch: "${params.GIT_BRANCH}", url: "${GIT_REPO}", credentialsId: "${GIT_CRE_ID}"
echo "代码拉取完成"
}
}
stage('编译打包') {
steps {
dir("code") { // 进入code目录下,我的代码仓是因为实际项目代码在code目录下(如果不需要去掉这一行)
// 1. 先执行打包
sh "mvn clean package"
script { // 将jar修改为指定的版本号,并移动到根目录下
def jarFiles = sh(script: 'ls target/${BASE_JAR_NAME}-*.jar', returnStdout: true).trim().split('\n')
if (jarFiles.size() == 0 || jarFiles[0].contains('No such file')) {
error "未找到JAR包"
}
// 取第一个匹配的 JAR 文件
def originalJarPath = jarFiles[0]
env.VERSIONED_JAR = "${BASE_JAR_NAME}-v${params.VERSION}.jar"
// 将jar包移动到根目录下
sh """
mv ${originalJarPath} ../${VERSIONED_JAR}
"""
}
}
}
}
stage('上传到目标服务器') {
steps {
script {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: "${SSH_SERVER}",
transfers: [
sshTransfer(
sourceFiles: "${VERSIONED_JAR}",
remoteDirectory: "${DEPLOY_PATH}",
remoteDirectorySDF: false,
flatten: false,
execCommand: """
echo '已上传 ${VERSIONED_JAR} 到服务器'
# 确保目标目录存在
mkdir -p ${DEPLOY_PATH}
"""
)
]
)
]
)
}
}
}
stage('执行启动脚本') {
steps {
script {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: "${SSH_SERVER}",
transfers: [
sshTransfer(
execCommand: """
cd ${DEPLOY_PATH} || exit 1
echo '当前目录:' && pwd
echo '开始执行启动脚本...'
echo 1 | sudo -S ./run.sh ${VERSIONED_JAR}
"""
)
]
)
]
)
}
}
}
stage('输出服务日志') {
steps {
script {
def result = sshPublisher(
publishers: [
sshPublisherDesc(
configName: "${SSH_SERVER}", // SSH 服务器名称
transfers: [
sshTransfer(
execCommand: """
sleep 5s
echo '===== 开始获取服务日志 ====='
echo '服务名称: ${MDM_SYSTEM_SVC}'
echo "当前时间: \$(date '+%Y-%m-%d %H:%M:%S')"
echo '---------------------------'
journalctl -u ${MDM_SYSTEM_SVC} -n 50 --no-pager || {
echo '错误:无法获取服务日志'
exit 1
}
echo '===== 日志获取结束 ====='
"""
)
]
)
]
)
echo "服务最新50条日志:"
echo "${result}"
}
}
}
}
post {
always {
archiveArtifacts artifacts: "*.jar", allowEmptyArchive: true
echo "构建流程结束 - ${currentBuild.result}"
}
success {
echo "部署成功! 版本 ${params.VERSION} 已发布"
}
failure {
echo "部署失败,请检查日志"
}
}
}
所以有了第二版:使用 sshCommand 命令,这一版用到了 ssh Server 凭证,使用这个命令就 可以在Jenkins控制台看到日志 了。
ps:使用 sshCommand 命令需要安装插件:SSH Pipeline Steps
pipeline {
agent any
parameters {
string(name: 'VERSION', description: '请输入jar包版本号 (例如: 1.0.0)')
string(name: 'GIT_BRANCH', description: '请输入部署分支 (例如: master)')
}
environment {
BASE_JAR_NAME = "jenkins-study" // jar包名称,根据实际项目修改
GIT_REPO = 'https://xxx.git' // 替换为Git仓库地址
GIT_CRE_ID = "xxx" // git指纹凭证ID
SSH_SERVER = 'test_server' // 这个配置在这里就没什么实际作用了,只是一个名称
SSH_HOST = "192.168.100.102" // 远程服务器的IP地址
SSH_CREDENTIALS_ID = "xxx" // SSH凭证ID
DEPLOY_PATH = '/home/projects/xxx' // 替换为目标服务器的项目部署路径
// jar包以系统服务方式运行
MDM_SYSTEM_SVC = 'xxxx.service'
}
tools {
jdk 'JDK1.8' // jdk版本号
maven 'Maven 3.9.10' // 使用全局工具配置中定义的 Maven
}
stages {
stage('拉取代码') {
steps {
git branch: "${params.GIT_BRANCH}", url: "${GIT_REPO}", credentialsId: "${GIT_CRE_ID}"
echo "代码拉取完成"
}
}
stage('编译打包') {
steps {
dir("code") {
sh "mvn clean package"
script {
def jarFiles = sh(script: 'ls target/${BASE_JAR_NAME}-*.jar', returnStdout: true).trim().split('\n')
if (jarFiles.size() == 0 || jarFiles[0].contains('No such file')) {
error "未找到JAR包"
}
def originalJarPath = jarFiles[0]
env.VERSIONED_JAR = "${BASE_JAR_NAME}-v${params.VERSION}.jar"
sh "mv ${originalJarPath} ../${VERSIONED_JAR}"
}
}
}
}
stage('上传到目标服务器') {
steps {
script {
withCredentials([sshUserPrivateKey(
credentialsId: "${env.SSH_CREDENTIALS_ID}",
keyFileVariable: 'identity',
passphraseVariable: '',
usernameVariable: 'userName'
)]) {
// 定义 remote 对象
def remote = [
name: "${env.SSH_SERVER}",
host: "${env.SSH_HOST}",
allowAnyHosts: true,
user: userName,
identityFile: identity
]
sshCommand remote: remote, command: """
echo '已上传 ${env.VERSIONED_JAR} 到服务器'
mkdir -p ${env.DEPLOY_PATH}
"""
sshPut remote: remote, from: "${env.VERSIONED_JAR}", into: "${env.DEPLOY_PATH}"
}
}
}
}
stage('执行启动脚本') {
steps {
script {
withCredentials([sshUserPrivateKey(
credentialsId: "${env.SSH_CREDENTIALS_ID}",
keyFileVariable: 'identity',
passphraseVariable: '',
usernameVariable: 'userName'
)]) {
// 定义 remote 对象
def remote = [
name: "${env.SSH_SERVER}",
host: "${env.SSH_HOST}",
allowAnyHosts: true,
user: userName,
identityFile: identity
]
sshCommand remote: remote, command: """
cd ${env.DEPLOY_PATH} || exit 1
echo '当前目录:' && pwd
echo '开始执行启动脚本...'
echo 1 | sudo -S ./run.sh ${env.VERSIONED_JAR}
"""
}
}
}
}
}
post {
always {
archiveArtifacts artifacts: "*.jar", allowEmptyArchive: true
echo "构建流程结束 - ${currentBuild.result}"
}
success {
echo "部署成功! 版本 ${params.VERSION} 已发布"
}
failure {
echo "部署失败,请检查日志"
}
}
}
集成Git WebHook实现事件触发流水线
第一步:在Git上配置WebHook
这里用到的是 Gogs 类型,其他类型根据情况修改
token 在Linux中可以通过一下命令自动生成:
$ openssl rand -hex 16
第二步:Jenkins通过触发器接收Git WebHook事件
这里我列举了两种场景:(之所以分成两个脚本,是因为他们的body不同)
1.提交代码触发
2.发布版本触发
提交代码触发
// webhook触发(git)
triggers {
GenericTrigger(
genericVariables: [
[key: "GIT_REF", value: '$.ref'] // 格式为:refs/heads/xxx
],
token: "xxxx", // 与git webhook 保持一致,需要替换
causeString: "Triggered by Gogs Release",
printPostContent: true, // 调试:打印Webhook原始数据
printContributedVariables: true // 调试:打印解析后的变量
)
}
完整脚本
pipeline {
agent any
parameters {
string(name: 'GIT_BRANCH', defaultValue: '', description: '部署分支,例如:master')
}
environment {
BASE_JAR_NAME = "mdm" // 项目名称,需要替换
USE_JAR_NAME = "${BASE_JAR_NAME}-webhook-deploy-v1.0.0.jar" // jar包名称(版本发布),需要替换
GIT_REPO = 'https://xxx.git' // Git仓库地址,需要替换
GIT_CRE_ID = "xxxxx" // git仓库凭证ID,需要替换
SSH_SERVER = 'test_server' // 服务器名称,自定义即可
DEPLOY_PATH = '/home/project' // 目标服务器的部署路径,需要替换
MDM_SYSTEM_SVC = 'xxx-jar.service' // jar包以系统服务方式运行的服务名称,需要替换
SSH_HOST = "192.168.100.102" // 远程服务器的IP地址,需要替换
SSH_CREDENTIALS_ID = "xxx" // SSH凭证ID,需要替换
}
tools {
jdk 'JDK1.8' // jdk版本号
maven 'Maven 3.9.10' // 使用全局工具配置中定义的 Maven
}
// webhook触发(git)
triggers {
GenericTrigger(
genericVariables: [
[key: "GIT_REF", value: '$.ref'] // 格式为:refs/heads/xxx
],
token: "xxxx", // 与git webhook 保持一致,需要替换
causeString: "Triggered by Gogs Release",
printPostContent: true, // 调试:打印Webhook原始数据
printContributedVariables: true // 调试:打印解析后的变量
)
}
stages {
stage('Extracted Branch Name') {
steps {
script {
if (env.GIT_REF != null && env.GIT_REF.trim()) {
// 提取分支名称
env.GIT_BRANCH = env.GIT_REF.tokenize('/').last()
env.ACTION = "PUSH"
echo "Extracted branch name: ${env.GIT_BRANCH}"
} else { // 手动触发
env.GIT_BRANCH = params.GIT_BRANCH
env.ACTION = "MANUAL_TRIGGER"
echo "manual_trigger:Extracted branch name: ${env.GIT_BRANCH}"
}
}
}
}
stage('拉取代码') {
steps {
git branch: "${GIT_BRANCH}", url: "${GIT_REPO}", credentialsId: "${GIT_CRE_ID}"
echo "代码拉取完成"
}
}
stage('编译打包') {
steps {
dir("code") {
sh "mvn clean package"
script {
def jarFiles = sh(script: 'ls target/${BASE_JAR_NAME}-*.jar', returnStdout: true).trim().split('\n')
if (jarFiles.size() == 0 || jarFiles[0].contains('No such file')) {
error "未找到JAR包"
}
def originalJarPath = jarFiles[0]
sh "mv ${originalJarPath} ../${USE_JAR_NAME}"
}
}
}
}
stage('上传到目标服务器') {
steps {
script {
withCredentials([sshUserPrivateKey(
credentialsId: "${env.SSH_CREDENTIALS_ID}",
keyFileVariable: 'identity',
passphraseVariable: '',
usernameVariable: 'userName'
)]) {
// 定义 remote 对象
def remote = [
name: "${env.SSH_SERVER}",
host: "${env.SSH_HOST}",
allowAnyHosts: true,
user: userName,
identityFile: identity
]
sshCommand remote: remote, command: """
echo '已上传 ${env.USE_JAR_NAME} 到服务器'
mkdir -p ${env.DEPLOY_PATH}
"""
sshPut remote: remote, from: "${env.USE_JAR_NAME}", into: "${env.DEPLOY_PATH}"
}
}
}
}
stage('执行启动脚本') {
steps {
script {
withCredentials([sshUserPrivateKey(
credentialsId: "${env.SSH_CREDENTIALS_ID}",
keyFileVariable: 'identity',
passphraseVariable: '',
usernameVariable: 'userName'
)]) {
// 定义 remote 对象
def remote = [
name: "${env.SSH_SERVER}",
host: "${env.SSH_HOST}",
allowAnyHosts: true,
user: userName,
identityFile: identity
]
sshCommand remote: remote, command: """
cd ${env.DEPLOY_PATH} || exit 1
echo '当前目录:' && pwd
echo '开始执行启动脚本...'
echo 1 | sudo -S ./run.sh ${env.USE_JAR_NAME}
"""
}
}
}
}
}
post {
always {
archiveArtifacts artifacts: "*.jar", allowEmptyArchive: true
echo "构建流程结束 - ${currentBuild.result}"
}
success {
echo "部署成功! 触发行为:${env.ACTION},分支:${env.GIT_BRANCH}"
}
failure {
echo "部署失败,请检查日志"
}
}
}
发布版本触发
webHook触发器
triggers {
GenericTrigger(
genericVariables: [
[key: "RELEASE_ACTION", value: '$.action'],
[key: "TAG_NAME", value: '$.release.tag_name'],
[key: "GIT_BRANCH", value: '$.release.target_commitish']
],
token: "xxx", // 与git webhook 保持一致,需要替换
causeString: "Triggered by Gogs Release",
printPostContent: true, // 调试:打印Webhook原始数据
printContributedVariables: true // 调试:打印解析后的变量
)
}
完整脚本
pipeline {
agent any
parameters {
string(name: 'GIT_BRANCH', defaultValue: '', description: '部署分支,例如:master')
}
environment {
BASE_JAR_NAME = "mdm" // 项目名称,需要替换
USE_JAR_NAME = "${BASE_JAR_NAME}-webhook-deploy-v1.0.0.jar" // jar包名称(版本发布),需要替换
GIT_REPO = 'https://xxx.git' // Git仓库地址,需要替换
GIT_CRE_ID = "xxx" // git仓库凭证ID,需要替换
SSH_SERVER = 'test_server' // 服务器名称,自定义即可
DEPLOY_PATH = '/home/project' // 目标服务器的部署路径,需要替换
MDM_SYSTEM_SVC = 'xxx-jar.service' // jar包以系统服务方式运行的服务名称,需要替换
SSH_HOST = "192.168.100.102" // 远程服务器的IP地址,需要替换
SSH_CREDENTIALS_ID = "xxxx" // SSH凭证ID,需要替换
}
tools {
jdk 'JDK1.8' // jdk版本号
maven 'Maven 3.9.10' // 使用全局工具配置中定义的 Maven
}
// webhook触发(git)
triggers {
GenericTrigger(
genericVariables: [
[key: "RELEASE_ACTION", value: '$.action'],
[key: "TAG_NAME", value: '$.release.tag_name'],
[key: "GIT_BRANCH", value: '$.release.target_commitish']
],
token: "xxx", // 与git webhook 保持一致,需要替换
causeString: "Triggered by Gogs Release",
printPostContent: true, // 调试:打印Webhook原始数据
printContributedVariables: true // 调试:打印解析后的变量
)
}
stages {
stage('Add in-params into env-var') {
steps {
script {
// jenkins界面手动触发
if (params.GIT_BRANCH != null && params.GIT_BRANCH.trim()) {
// 将入参设置为环境变量
env.GIT_BRANCH = params.GIT_BRANCH
echo "in-params GIT_BRANCH is set to: ${env.GIT_BRANCH}"
} else {
echo "in-params GIT_BRANCH is null or empty, not setting GIT_BRANCH"
}
if (env.RELEASE_ACTION == null || env.RELEASE_ACTION.trim().isEmpty()) {
// 手动触发
env.RELEASE_ACTION = 'manual_trigger'
echo "RELEASE_ACTION is set to default value: ${env.RELEASE_ACTION}"
}
}
}
}
stage('拉取代码') {
steps {
git branch: "${GIT_BRANCH}", url: "${GIT_REPO}", credentialsId: "${GIT_CRE_ID}"
echo "代码拉取完成"
}
}
stage('编译打包') {
steps {
dir("code") {
sh "mvn clean package"
script {
def jarFiles = sh(script: 'ls target/${BASE_JAR_NAME}-*.jar', returnStdout: true).trim().split('\n')
if (jarFiles.size() == 0 || jarFiles[0].contains('No such file')) {
error "未找到JAR包"
}
def originalJarPath = jarFiles[0]
sh "mv ${originalJarPath} ../${USE_JAR_NAME}"
}
}
}
}
stage('上传到目标服务器') {
steps {
script {
withCredentials([sshUserPrivateKey(
credentialsId: "${env.SSH_CREDENTIALS_ID}",
keyFileVariable: 'identity',
passphraseVariable: '',
usernameVariable: 'userName'
)]) {
// 定义 remote 对象
def remote = [
name: "${env.SSH_SERVER}",
host: "${env.SSH_HOST}",
allowAnyHosts: true,
user: userName,
identityFile: identity
]
sshCommand remote: remote, command: """
echo '已上传 ${env.USE_JAR_NAME} 到服务器'
mkdir -p ${env.DEPLOY_PATH}
"""
sshPut remote: remote, from: "${env.USE_JAR_NAME}", into: "${env.DEPLOY_PATH}"
}
}
}
}
stage('执行启动脚本') {
steps {
script {
withCredentials([sshUserPrivateKey(
credentialsId: "${env.SSH_CREDENTIALS_ID}",
keyFileVariable: 'identity',
passphraseVariable: '',
usernameVariable: 'userName'
)]) {
// 定义 remote 对象
def remote = [
name: "${env.SSH_SERVER}",
host: "${env.SSH_HOST}",
allowAnyHosts: true,
user: userName,
identityFile: identity
]
sshCommand remote: remote, command: """
cd ${env.DEPLOY_PATH} || exit 1
echo '当前目录:' && pwd
echo '开始执行启动脚本...'
echo 1 | sudo -S ./run.sh ${env.USE_JAR_NAME}
"""
}
}
}
}
}
post {
always {
archiveArtifacts artifacts: "*.jar", allowEmptyArchive: true
echo "构建流程结束 - ${currentBuild.result}"
}
success {
echo "部署成功! 触发行为:${env.RELEASE_ACTION} 标签:${env.TAG_NAME}"
}
failure {
echo "部署失败,请检查日志"
}
}
}
Git上查看WebHook触发情况
可以看到WebHook推送的具体内容(包括URL、请求头、请求体等);
流水线可视化界面
编写完Pipeline Script脚本后,既可以在Pipeline任务内执行,也可以通过安装 blue Ocean 插件 到可视化界面进行操作,实现全局流水线管理。
安装 blue Ocean 插件
安装成功后,可以看到Open Blean Ocean 菜单
点击进入,随便选择一个流水线
进入其中一个流水线的执行列表,这里可以看到历史执行记录,也可以在这里直接触发流水线执行
点击上一步的数字进入流水线执行详情,这里可以看到每一步的具体细节
PS:脚本注意事项
- 脚本中引用全局变量必须用双引号
""
,不能用单引号''
,否则会报错; - 脚本中引用全局变量,如果不是用
env.
,则如果变量不存在会报错,如果用了env.
,会输出 null值