说明

  • 任务描述

    • 现实研发系统:一个生产环境,多个测试环境
    • 具体实战通过代码来部署生产与测试环境
  • 基本思路

    • 利用Jenkins任务参数来控制切换生产与测试环境部署
    • 利用配置文件来控制生产与测试环境实际运行参数与数据库连接
  • 技术特性

    • -Dspring.profiles.active=myProfileName,通过这个参数可以控制运行SpringBoot实例时,挂载不同的配置文件:application-prod.yml或者application-qa.yml
  • 任务示意图

    image-20210227141623625

环境准备

根据说明可知,我们需要准备两个MySQL,分别是生产和测试的数据库,因此,我们在服务器上搭建两个mysql,配置如下:

  • mysql:端口号3306,用户名root,密码123123,Docker内网地址172.17.0.2
  • mysql_test:端口号3308,用户名root,密码123123,Docker内网地址172.17.0.3

“Jenkins Docker部署持续交付实战”一文中,已经具体介绍了mysql的配置,则mysql_test配置也是一样的,具体参考该文的介绍

SpringBoot应用的HTTP端口号:

  • 生产:8899
  • 测试:8811

Jenkins流水线构建

Jenkinsfile内容如下

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
pipeline {
agent {
label 'master'
}

parameters {
string(name: 'branch', defaultValue: 'master', description: 'Git branch')
choice(name: 'env_type', choices: ['prod', 'qa'], description: 'Environment Type')
}

environment {
docker_image = 'jeesite4'
docker_container = 'iJeesite4'
env = "$params.env_type"
}

stages{
stage('同步源码') {
steps {
git url:'https://gitee.com/jeanlv/jeesite4.git', branch:"$params.branch"
}
}

stage('设定配置文件'){
steps{
sh '''
. ~/.bash_profile

if [[ "${env}" == "prod" ]]; then
export mysql_ip=${mysql_prod_ip}
export mysql_port=${mysql_prod_port}
else
export mysql_ip=${mysql_qa_ip}
export mysql_port=${mysql_qa_port}
fi

export os_type=`uname`
cd ${WORKSPACE}/web/bin/docker
if [[ "${os_type}" == "Darwin" ]]; then
sed -i "" "s/mysql_ip/${mysql_ip}/g" application-${env}.yml
sed -i "" "s/mysql_port/${mysql_port}/g" application-${env}.yml
sed -i "" "s/mysql_user/${mysql_user}/g" application-${env}.yml
sed -i "" "s/mysql_pwd/${mysql_pwd}/g" application-${env}.yml
sed -i "" "s/<env>/${env}/g" Dockerfile-param
else
sed -i "s/mysql_ip/${mysql_ip}/g" application-${env}.yml
sed -i "s/mysql_port/${mysql_port}/g" application-${env}.yml
sed -i "s/mysql_user/${mysql_user}/g" application-${env}.yml
sed -i "s/mysql_pwd/${mysql_pwd}/g" application-${env}.yml
sed -i "s/<env>/${env}/g" Dockerfile-param
fi
'''
}
}

stage('Maven 编译'){
steps {
sh '''
. ~/.bash_profile

cd ${WORKSPACE}/root
mvn clean install -Dmaven.test.skip=true

cd ${WORKSPACE}/web
mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
'''
}
}

stage('停止 / 删除 现有Docker Container/Image '){
steps {
script{
try{
sh 'docker stop ${docker_container}-${env}'
}catch(exc){
echo "The container ${docker_container}-${env} does not exist"
}

try{
sh 'docker rm ${docker_container}-${env}'
}catch(exc){
echo "The container ${docker_container}-${env} does not exist"
}

try{
sh 'docker rmi ${docker_image}-${env}'
}catch(exc){
echo "The docker image ${docker_image}-${env} does not exist"
}
}
}
}

stage('生成新的Docker Image'){
steps {
sh '''
cd ${WORKSPACE}/web/bin/docker
rm -f web.war
cp ${WORKSPACE}/web/target/web.war .
docker build -t ${docker_image}-${env} -f Dockerfile-param .
'''
}
}

stage('启动新Docker实例'){
steps {
sh '''
if [[ "${env}" == "prod" ]]; then
export port="8899"
else
export port="8811"
fi

docker run -d --name ${docker_container}-${env} -p ${port}:8980 ${docker_image}-${env}
'''
}
}
}
}

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FROM frolvlad/alpine-java:jdk8-slim
MAINTAINER ThinkGem@163.com
ENV TZ "Asia/Shanghai"
ENV LANG C.UTF-8
VOLUME /tmp

WORKDIR /app
ADD web.war .
RUN jar -xvf web.war

WORKDIR /app/WEB-INF
ENV JAVA_OPTS "-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"
ENV JAVA_OPTS "$JAVA_OPTS -Dspring.profiles.active=<env>"

ADD application-<env>.yml ./classes/config

ENTRYPOINT java -cp /app $JAVA_OPTS org.springframework.boot.loader.WarLauncher

EXPOSE 8980

Jenkins创建流水线Job进行部署

  1. [新建任务]创建一个“构建一个自由风格的软件项目”的Job,进入配置页

  2. [General] -> [This project is parameterized]进行参数配置,mysql相关的配置信息等

    image-20210227145121397

  3. 配置”流水线” -> “定义”选择”Pipeline script from SCM”,配置Git信息

    image-20210227145239536

    配置Groovy脚本的路径

    image-20210227145310109

  4. 完成以上配置后,点击[保存],回到Job页面,点击[Build with Parameters],查看配置的参数

    image-20210227145400016

  5. 选择“prod”生产环境,点击[开始构建],查看“控制台日志”

    image-20210227145808472

  6. 查看到是执行成功的,回到Job Build页面,查看流水线执行图

    image-20210227150018611

这时我们浏览器再次访问:http://ip:8899,访问成功

image-20210227150103979

以上生产环境部署,我们也可以选择测试环境,在进行部署

image-20210227150246874

执行成功

image-20210227150420396

这时我们浏览器再次访问:http://ip:8811,访问成功

image-20210227151555851