基于 Docker 搭建,
附带流水线、部署脚本

Docker Run

1
2
3
4
sudo mkdir -p /data/docker/jenkins
sudo chown -R 1000:1000 /data/docker/jenkins

sudo docker run -d -p 8090:8080 -v /data/docker/jenkins:/var/jenkins_home --restart=always --name jenkins jenkinsci/blueocean

Jenkins Pipeline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
node {
// maven 模块路径
def mavenModule="gateway"

// 服务名称
def serverName="gateway"

// maven build 后制品所在目录
def sourceDirectory="${mavenModule}/target/"

// 部署环境
def env="prod"

// JVM 参数
def jvmOptions=""

// 要部署到到主机列表 (系统配置 -> Publish Over SS -> SSH Server -> Name)
def hosts=["187", "152"]

// ---------------------------------------

// 远程服务器目录
def remoteDirectory="data/sango/server/"
// 远程服务器部署脚本路径
def deployShellFile="/data/sango/shell/deploy.sh"
// 制品文件
def sourceFiles="${sourceDirectory}${serverName}.jar"
// 到远程服务器执行的命令(三个参数: serverName, env, jvmOptions)
def execCommand="cd ${remoteDirectory}${serverName} && sudo sh ${deployShellFile} ${serverName} ${env} ${jvmOptions}"

def mvnHome
def workspace = pwd()

stage('git pull') {
println(workspace)

// for display purposes
// Get some code from a GitHub repository
git branch: 'master', credentialsId: 'xxxx-xxxx', url: 'git repository'
}
stage('maven build') {
println(workspace)

// Get the Maven tool.
// ** NOTE: This 'M3' Maven tool must be configured
// ** in the global configuration.
mvnHome = tool 'M3'

sh "${mvnHome}/bin/mvn --version"
// Run the maven build
sh "${mvnHome}/bin/mvn -B clean package -pl ${mavenModule} -am -Dmaven.test.skip=true -Dautoconfig.skip"
archiveArtifacts "${sourceFiles}"
}
stage('deploy') {
println(workspace)

script {
// 先发布一台验证
success = false
while (!success) {
try {
sshPublisher(
continueOnError: false, failOnError: true,
publishers: [
sshPublisherDesc(
configName: hosts.pop(),
verbose: true,
transfers: [
sshTransfer(
sourceFiles: "${sourceFiles}",
removePrefix: "${sourceDirectory}",
remoteDirectory: "${remoteDirectory}/${serverName}",
execCommand: "${execCommand}"
)
]
)
]
)
success = true
} catch (e) {
println(e)
success = false
result = input message: '', ok: 'Retry', submitterParameter: 'operator'
}
}

// 人工卡点
result = input message: '', ok: 'Confirm', parameters: [choice(choices: ['Resume'], description: '', name: 'action')], submitterParameter: 'operator'
if (result.action == 'Resume') {
for (host in hosts) {
success = false
while (!success) {
try {
sshPublisher(
continueOnError: false, failOnError: true,
publishers: [
sshPublisherDesc(
configName: host,
verbose: true,
transfers: [
sshTransfer(
sourceFiles: "${sourceFiles}",
removePrefix: "${sourceDirectory}",
remoteDirectory: "${remoteDirectory}/${serverName}",
execCommand: "${execCommand}"
)
]
)
]
)
success = true
} catch (e) {
println(e)
success = false
result = input message: '', ok: 'Retry', submitterParameter: 'operator'
}
}
}
} else {
// 回滚至上个版本
}
}
}
}

Deploy Shell Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# ServerName
SERVER=$1

# Spring Profiles Active
ENV=$2

# JVM Options
JVM_OPTIONS=$3

# Default Value
DEFAULT_ENV="dev"
DEFAULT_JVM_OPTIONS="-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms512m -Xmx512m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC"

if [ ! -n "$ENV" ]; then
ENV=$DEFAULT_ENV
fi

if [ ! -n "$JVM_OPTIONS" ]; then
JVM_OPTIONS=$DEFAULT_JVM_OPTIONS
fi

# kill old
PID=`ps -ef | grep ${SERVER}.jar | grep -v grep | awk '{print $2}'`
if [ 0 -ne ${#PID} ]; then
echo "kill ${SERVER}"
kill $PID
fi

# run new
nohup java -jar ${SERVER}.jar ${JVM_OPTIONS} --spring.profiles.active=${ENV} > ${SERVER}.log 2>&1 &
echo "start server ${SERVER}:${ENV} [${JVM_OPTIONS}]"

完成效果

jrnkind-blue.png

jenkins-input.png

jenkins-publish-over-ssh.png

Git 仓库过大的问题

默认十分钟超时, 手动 clone 即可.

1
2
sudo docker exec -it jenkins /bin/bash
cd /var/jenkins_home/workspace/

参考资料