此处将为大家介绍关于docker+jenkins实现springboot项目持续集成自动化部署的详细内容,并且为您解答有关jenkins和docker实现自动化构建部署的相关问题,此外,我们还将为您介
此处将为大家介绍关于docker+jenkins 实现 spring boot 项目持续集成自动化部署的详细内容,并且为您解答有关jenkins和docker实现自动化构建部署的相关问题,此外,我们还将为您介绍关于.NET 持续集成与自动化部署之路第一篇 - 半天搭建你的 Jenkins 持续集成与自动化部署系统、.NET 持续集成与自动化部署之路第一篇 —— 半天搭建你的 Jenkins 持续集成与自动化部署系统、Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(一):Jenkins安装、Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(四):发布与回滚的有用信息。
本文目录一览:- docker+jenkins 实现 spring boot 项目持续集成自动化部署(jenkins和docker实现自动化构建部署)
- .NET 持续集成与自动化部署之路第一篇 - 半天搭建你的 Jenkins 持续集成与自动化部署系统
- .NET 持续集成与自动化部署之路第一篇 —— 半天搭建你的 Jenkins 持续集成与自动化部署系统
- Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(一):Jenkins安装
- Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(四):发布与回滚
docker+jenkins 实现 spring boot 项目持续集成自动化部署(jenkins和docker实现自动化构建部署)



1 [root@iZuf635fwy8k6ubk6r9yonZ ms_backend]# vim Dockerfile
2
3 FROM hub.c.163.com/wuxukun/maven-aliyun:3-jdk-8 //下载maven与java的镜像
4 # 指定当前操作目录
5 WORKDIR /usr/ms_backend
6 #指定对外端口号
7 EXPOSE 8040
8 #启动java程序
9 #--spring.profiles.active=dev 多环境下指定环境 。 -c为清除以前启动的数据
10 ENTRYPOINT ["java","-jar","ms_backend.jar","--spring.profiles.active=dev","-c"]
先看下jenkins构建后项目存放的路径,以便在docker.sh中用到

1 [root@iZuf635fwy8k6ubk6r9yonZ ms_backend]# vim docker.sh
2 #操作/项目路径(Dockerfile存放的路劲)
3 BASE_PATH=/usr/ms_backend
4 # 源jar路径 即jenkins构建后存放的路径(
5
6 )
7 SOURCE_PATH=/var/lib/jenkins/workspace
8 #docker 镜像/容器名字或者jar名字 这里都命名为这个
9 SERVER_NAME=ms_backend
10 #容器id
11 CID=$(docker ps | grep "$SERVER_NAME" | awk ''{print $1}'')
12 #镜像id
13 IID=$(docker images | grep "$SERVER_NAME" | awk ''{print $3}'')
14
15 echo "最新构建代码 $SOURCE_PATH/$SERVER_NAME/target/ms_backend.jar 迁移至 $BASE_PATH ...."
16 #把项目从jenkins构建后的目录移动到我们的项目目录下同时重命名下
17 mv $SOURCE_PATH/$SERVER_NAME/target/ms_backend-0.0.1-SNAPSHOT.jar $BASE_PATH/ms_backend.jar
18 #修改文件的权限
19 chmod 777 /usr/ms_backend/ms_backend.jar
20 echo "迁移完成"
21
22
23 # 构建docker镜像
24 if [ -n "$IID" ]; then
25 echo "存在$SERVER_NAME镜像,IID=$IID"
26 else
27 echo "不存在$SERVER_NAME镜像,开始构建镜像"
28 cd $BASE_PATH
29 docker build -t $SERVER_NAME .
30 fi
31
32 # 运行docker容器
33 docker rm $SERVER_NAME //删除原来的容器
34 # --name docker-test 容器的名字为docker-test
35 # -d 容器后台运行
36 # -p 3636:3636 指定容器映射的端口和主机对应的端口都为3636
37 # -v /usr/ms_backend/:/usr/ms_backend/ 将主机的/usr/ms_backend/目录挂载到容器的/usr/ms_backend/ 目录中(不可少每次本地更新jar包重启容器即可,不用重新构建镜像
38 docker run --name $SERVER_NAME -v $BASE_PATH:$BASE_PATH -d -p 8040:8040 $SERVER_NAME
39 echo "$SERVER_NAME容器创建完成"



.NET 持续集成与自动化部署之路第一篇 - 半天搭建你的 Jenkins 持续集成与自动化部署系统
.NET 持续集成与自动化部署之路第一篇 (半天搭建你的 Jenkins 持续集成与自动化部署系统)#
前言#
相信每一位程序员都经历过深夜加班上线的痛苦!而作为一个加班上线如家常便饭的码农,更是深感其痛。由于我们所做的系统业务复杂,系统庞大,设计到多个系统之间的合作,而核心系统更是采用分布式系统架构,由于当时对系统划分的不合理等等原因导致每次发版都会设计到多个系统的发布,小的版本三五个,大的版本十几个甚至几十个系统的同时发布!而我们也没有相应的基础设施的支撑,发版方式更是最传统的,开发人员将发布包发给运维人员,由其讲各个发布包一个一个覆盖到生产环境。因此每次上线仅仅发版就需要 2-3 个小时。这种方式不仅仅耗时、耗力,更是由于人工操作经常导致一些丢、落的现象。而我们当时的测试也是采用纯手工的测试,发版完毕后一轮回归测试就需要 3-4 个小时 (当时主要是手工测试)。之前也一直提倡持续集成、自动化的测试和运维,但迟迟没有推进落地。终于在一个加班到凌晨四点的夜晚后,我再也受不了。回家后躺在床上迟迟睡不着,心想这个自动化的发布能有多难,他们搞不了,老子自己搞,于是 6 点爬起来来到公司,正式开始了我的持续集成、自动化部署的研究与推进之路。
一、初识 Jenkins#
由于之前亦没有相关知识的积累,因此也是对如何实现也是一头雾水。于是只能找度娘,关键字 "自动化发布"。搜索到很多工具和方法,但都是以 Java 平台居多,.net 平台相关资料不多。其中以 Jenkins 介绍较多,微软也提供一套自动化部署的方式,也有一些其他持续集成工具可以实现自动化的发布,但最终还是选择了 Jenkins。主要有以下几个原因:
- 代码开源、插件丰富完善、系统稳定
- 社区活跃,成功实践和网上资源较为丰富
- 安装配置简单
- web 形式的可视化的管理页面
1. Jenkins 是什么#
Jenkins 是一个开源软件项目,是基于 Java 开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
** 持续集成: **
持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
2.Jenkins 能干什么#
众所周知,工业革命解放了人类的双手,使得人们避免了很多重复性的工作,而 Jenkins 能帮助开发测试运维人员解决很多重复性工作,我们可以将一些重复性的工作,写成脚本,如:代码提交,执行单元测试,程序的编译、构建、发布等封装成脚本,由 Jenkins 替我们定时或按需执行。事实上 Jenkins 的众多插件就是如此,究其根本就是执行一个或多个 windows 或 linux 命令来完成我们的需求。
3.Jenkins 的一个工作流程#
通过对 Jenkins 的简单了解后,对完成自动化发布有了大致思路,如下图为 Jenkins 的一个工作流程
思路已经有了,接下来就是针对此流程,一步一步简单实现.NET Web 应用程序基于 Jenkins 的自动化部署。
二、Jenkins 安装#
Jenkins 有 windows 版本也有 linux 版本,由于我们项目都是基于.net freamwork 进行开发,而 jenkins 构建需要编译.net 程序,为了更方便的编译,因此选择安装 windows 版本。
1. 下载#
可从 Jenkins 官网 https://jenkins.io/download/ 下载 windows 安装包。
2. 安装#
下载完成后,可按照提示进行安装即可。(windows 下傻瓜式安装,注意 Jenkins 是 java 开发,因此需先安装对应 jdk 版本)
3. 配置#
安装完成后会自动安装并启动一个 windows 服务,名为 Jenkins,打开浏览器 localhost:8080 (Jenkins 默认端口号为 8080,如需修改可打开 Jenkins 安装目录找到 Jenkins.xml 修改其中端口,然后打开服务重启 Jenkins 服务即可) 之后按照提示进行配置即可!配置完成后看到如下界面代表安装成功!
整个安装过程非常简单,基本上是傻瓜式按照提示操作即可,期间并未遇到问题,基本上 10 分钟左右就搞定了!接下来将介绍如何按照上述流程实现.NET 下 Jenkins 的持续集成与自动化部署!
三、通过 SVN 获取源代码#
1. 安装插件#
根据我们的思路,首先要做的就是获取到我们的源代码。由于我们公司使用的源代码管理工具主要是 SVN 因此在这里主要介绍 SVN 的方式方法。根据度娘的指引,我们需要安装一个 SVN 的插件:Subversion Plug-in (如果:安装 Jenkins 时选择的安装推荐的插件,则 Jenkins 会直接给安装上这个插件,无需自己安装)。
2. 项目配置#
安装插件后,选择新建一个自由风格的软件项目,起个名字,进入到项目配置后,找到源代码管理选项:
主要有以下几个选项需要配置:
-
Repository URL: 要获取的 SVN 的路径,如:https://127.0.0.1:9666/svn/HS.Mall/SoureCode/Trunk/Test
-
Credentials: 配置 SVN 用户名和密码
-
Ignore externals: 是否忽略 SVN 外部引用 (这个很重要,稍后会用到,关于 SVN 外部引用,可自行百度)
-
Additional Credentials: 当你的 SVN 版本库使用外部引用关联其它版本库是这个就很重要了
Realm:填写 SVN 服务器的地址
Copy<https://127.0.0.1:9666> VisualSVN Server //(注意这个格式)
Credentials: 填写 SVN 用户名和密码信息
其它一些选项直接按照默认值就可以,关于每一项的详细介绍可以点击后面的小?号查看。
配置完成后点击保存后,构建该项目查看结果。若能够将源代码更新至 Jenkins 的工作空间内,则代表配置成功!
四、通过 MSBuild 编译应用程序#
1. 安装插件与环境#
编译.NET 应用程序可通过微软提供的 MSBuild 工具,先安装插件:MSBuild。(注意:Jenkins 服务器需安装 MSBuild,建议在 Jenkins 上安装 VS 开发工具,可以在构建出问题的时候打开 VS 调试,省去很多不必要的麻烦)。
2. 全局配置#
插件安装完毕后,进入系统管理 -> 全局工具配置 (ConfigureTools) 找到 MSBuild 配置选项:
- Name:自己起个名字
- Path to MSBuild:MSBuild.exe 程序的物理路径
注意:此处 MSBuild.exe 必须与程序所使用 freamwork 版本相对应,此处我在这就遇到了一个大坑,一开始随便找个一个 MSBuild 工具,没想到根本编译不了 C#6.0 的语法。建议直接指向 visual studio 安装目录内的 MSBuild.exe, 可以避免很多问题。如 VS2017 在:Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin 路径内。
3. 项目配置#
打开我们之前创建的项目,找到构建选项 -> 增加构建步骤 ->Build a Visual Studio project or solution using MSBuild
-
Name: 选择全局 MSBuild 配置的名称
-
MSBuild Build File: 填写我们的要构建的项目.csproj 文件,所相对工作的路径。如:/Test.csproj
-
Command Line Arguments:MSBuild 的参数如:/t:Rebuild /P:Configuration=Release /p:VisualStudioVersion=14.0 /p:DeployOnBuild=True;PublishProfile=Test.pubxml
- /t:Rebuild 重新生成
- /p:Configuration=Release Release 生成模式
- /p:VisualStudioVersion=14.0 指定子工具集 (VS2015 为 14.0,2017 为 15.0),不设置会报错
- /p:DeployOnBuild=True;PublishProfile=Test.pubxml 使用 Test.pubxml 发布文件来发布项目 .pubxml 文件可在 VS 发布时配置,位于 Properties 文件夹内。
配置完成后,点击构建,查看控制台信息,如能构建成功,则代表我们的配置无误!
4. 遇到的问题#
原以为按照度娘的一系列解决方案能够很顺利的构建,可是在连续失败了几十次之后,才明白远远没有那么简单。期间主要遇到几个问题:
- MSBuild 版本不对导致构建不了 C#6.0 的语法
- Jenkins 是讲版本库源代码更新到自己的工作空间内,再执行后续的构建工作。我们的程序很不规范,其中引用了许多不属于自己版本库的第三方依赖包,和一些自己开发的公共库,当时这些第三方包和公共库放在我们 SVN 的另一个版本库里进行管理,因此在构建的时候导致很多程序集找不到引用。
关于问题 1: 上面已经提过,只需要找到对应版本即可
而问题 2: 一开始找了很多资料也没有找到解决方案,后来还是从源代码管理上找到了方案。
方案 1:
借鉴 Nuget 的思想,使用 Nuget 服务器管理我们自己开发的一些公共依赖库。关于 Nuget 管理依赖的文章在另一篇博客里。
方案 2:
就是上面提到的 SVN 外部引用,当时也是走投无路,于是疯狂翻译 Jenkins 的这些英文解释,在翻译到 SVN 插件的 Ignore externals 时,找到了这种方案,就是 SVN 可以设置外部引用,这样在更新版本库的时候就可以把依赖的版本库也更新下来,然后 Jenkins SVN 插件把这个 Ignore externals 选项去掉,然后在 Additional Credentials 选项里填上所依赖版本库的 SVN 配置,就能够把这些依赖也更新到 SVN 工作空间内。
以上两个问题解决后,基本没有遇到太难的问题。由此可见我们的源代码管理的科学、规范是多么的重要。
几十次的构建失败,一堆乱七八糟的引用是多么痛的领悟!
五、通过 Ftp 发布至应用服务器#
构建成功后,Test.pubxml 会指定发布的包的路径 (最好是放到工作空间下),按照思路,接下来就是要想办法把发布包 Copy 到应用服务器的根目录下。由于我们的应用服务器都是 windows 系统,因此不能像 linux 系统一样通过 ssh 远程 Copy 过去,当时能想到的就是使用 Ftp 直接上传到应用服务器。
1. 安装插件与环境#
Jenkins 安装插件 Publish Over FTP, 应用服务器上需开启 Ftp。
2. 全局配置#
系统管理 -> 系统配置下找到 Publish over FTP 配置项
- Name: 起个名字,后面项目配置里会用的到
- HostName:Ftp 主机名 (端口号默认 21,在高级里面可以改)
- Username:Ftp 用户名
- Password:Ftp 密码
3. 项目配置#
打开我们之前建的项目,找到构建后操作 -> 增加构建后操作步骤 ->Send build artifacts over FTP
- Name: 选择全局配置里的
- Source files: 选择你的发布包路径 (这里是相对于工作空间的路径)
- Remote directory:放到远程的哪个路径里 (这里是相对于 Ftp 根目录的路径)
配置完成后,点击保存,构建即可!
六、结束语#
如上,就基本实现了我们的自动化发布的需求,这期间从早晨六点开始,差不多中午就完成了,当然也并不像上面介绍的那么简单,期间也遇到了许多问题,构建了大概一百多次,才最终成功了第一次。本文主要介绍实现自动化部署的一种基本的思路,当然还有很多方案可以实现我们的需求,甚至不仅仅局限于 Jenkins。而这种方案其中也有许多细节的地方在文章中没有提到,如:如何实现自动化的 Nunit 单元测试,如何定时构建......,因为当时我在完成之后也给我的团队成员提供了一个非常详细的配置文档,并且培训了很多次,但事实证明,讲的越详细越会限制他们自己的主动思考与动手的能力。这也导致了后来我去做其他工作的时候,我们将近一年的时间还是停留在我这半天的研究结果的层面上,而生产环境更是迟迟没有使用。其实思路才是最重要的,有了思路我们就可以通过各种方式来解决我们的问题,还是建议大家注重解决问题的思路,多动手,自己实践,才能学得更透!关于.NET 平台下 Jenkins 实现持续集成与自动化部署的落地与实现的问题与讨论,可以在文章下留言。
.NET 持续集成与自动化部署之路第一篇 —— 半天搭建你的 Jenkins 持续集成与自动化部署系统
文章导航 - readme
.NET 持续集成与自动化部署之路第一篇 (半天搭建你的 Jenkins 持续集成与自动化部署系统)
前言
相信每一位程序员都经历过深夜加班上线的痛苦!而作为一个加班上线如家常便饭的码农,更是深感其痛。由于我们所做的系统业务复杂,系统庞大,设计到多个系统之间的合作,而核心系统更是采用分布式系统架构,由于当时对系统划分的不合理等等原因导致每次发版都会设计到多个系统的发布,小的版本三五个,大的版本十几个甚至几十个系统的同时发布!而我们也没有相应的基础设施的支撑,发版方式更是最传统的,开发人员将发布包发给运维人员,由其讲各个发布包一个一个覆盖到生产环境。因此每次上线仅仅发版就需要 2-3 个小时。这种方式不仅仅耗时、耗力,更是由于人工操作经常导致一些丢、落的现象。而我们当时的测试也是采用纯手工的测试,发版完毕后一轮回归测试就需要 3-4 个小时 (当时主要是手工测试)。之前也一直提倡持续集成、自动化的测试和运维,但迟迟没有推进落地。终于在一个加班到凌晨四点的夜晚后,我再也受不了。回家后躺在床上迟迟睡不着,心想这个自动化的发布能有多难,他们搞不了,老子自己搞,于是 6 点爬起来来到公司,正式开始了我的持续集成、自动化部署的研究与推进之路。
系列文章
.NET 实现持续集成与自动化部署 1-Jenkins
.NET 实现持续集成与自动化部署 2-NuGet
.NET 实现持续集成与自动化部署 3 - 测试环境到生产环境策略
一、初识 Jenkins
由于之前亦没有相关知识的积累,因此也是对如何实现也是一头雾水。于是只能找度娘,关键字 "自动化发布"。搜索到很多工具和方法,但都是以 Java 平台居多,.net 平台相关资料不多。其中以 Jenkins 介绍较多,微软也提供一套自动化部署的方式,也有一些其他持续集成工具可以实现自动化的发布,但最终还是选择了 Jenkins。主要有以下几个原因:
- 代码开源、插件丰富完善、系统稳定
- 社区活跃,成功实践和网上资源较为丰富
- 安装配置简单
- web 形式的可视化的管理页面
1. Jenkins 是什么
Jenkins 是一个开源软件项目,是基于 Java 开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
** 持续集成: **
持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
2.Jenkins 能干什么
众所周知,工业革命解放了人类的双手,使得人们避免了很多重复性的工作,而 Jenkins 能帮助开发测试运维人员解决很多重复性工作,我们可以将一些重复性的工作,写成脚本,如:代码提交,执行单元测试,程序的编译、构建、发布等封装成脚本,由 Jenkins 替我们定时或按需执行。事实上 Jenkins 的众多插件就是如此,究其根本就是执行一个或多个 windows 或 linux 命令来完成我们的需求。
3.Jenkins 的一个工作流程
通过对 Jenkins 的简单了解后,对完成自动化发布有了大致思路,如下图为 Jenkins 的一个工作流程
思路已经有了,接下来就是针对此流程,一步一步简单实现.NET Web 应用程序基于 Jenkins 的自动化部署。
二、Jenkins 安装
Jenkins 有 windows 版本也有 linux 版本,由于我们项目都是基于.net freamwork 进行开发,而 jenkins 构建需要编译.net 程序,为了更方便的编译,因此选择安装 windows 版本。
1. 下载
可从 Jenkins 官网 https://jenkins.io/download/ 下载 windows 安装包。
2. 安装
下载完成后,可按照提示进行安装即可。(windows 下傻瓜式安装,注意 Jenkins 是 java 开发,因此需先安装对应 jdk 版本)
3. 配置
安装完成后会自动安装并启动一个 windows 服务,名为 Jenkins,打开浏览器 localhost:8080 (Jenkins 默认端口号为 8080,如需修改可打开 Jenkins 安装目录找到 Jenkins.xml 修改其中端口,然后打开服务重启 Jenkins 服务即可) 之后按照提示进行配置即可!配置完成后看到如下界面代表安装成功!
整个安装过程非常简单,基本上是傻瓜式按照提示操作即可,期间并未遇到问题,基本上 10 分钟左右就搞定了!接下来将介绍如何按照上述流程实现.NET 下 Jenkins 的持续集成与自动化部署!
三、通过 SVN 获取源代码
1. 安装插件
根据我们的思路,首先要做的就是获取到我们的源代码。由于我们公司使用的源代码管理工具主要是 SVN 因此在这里主要介绍 SVN 的方式方法。根据度娘的指引,我们需要安装一个 SVN 的插件:Subversion Plug-in (如果:安装 Jenkins 时选择的安装推荐的插件,则 Jenkins 会直接给安装上这个插件,无需自己安装)。
2. 项目配置
安装插件后,选择新建一个自由风格的软件项目,起个名字,进入到项目配置后,找到源代码管理选项:
主要有以下几个选项需要配置:
-
Repository URL: 要获取的 SVN 的路径,如:https://127.0.0.1:9666/svn/HS.Mall/SoureCode/Trunk/Test
-
Credentials: 配置 SVN 用户名和密码
-
Ignore externals: 是否忽略 SVN 外部引用 (这个很重要,稍后会用到,关于 SVN 外部引用,可自行百度)
-
Additional Credentials: 当你的 SVN 版本库使用外部引用关联其它版本库是这个就很重要了
Realm:填写 SVN 服务器的地址
<https://127.0.0.1:9666> VisualSVN Server //(注意这个格式)
Credentials: 填写 SVN 用户名和密码信息
其它一些选项直接按照默认值就可以,关于每一项的详细介绍可以点击后面的小?号查看。
配置完成后点击保存后,构建该项目查看结果。若能够将源代码更新至 Jenkins 的工作空间内,则代表配置成功!
四、通过 MSBuild 编译应用程序
1. 安装插件与环境
编译.NET 应用程序可通过微软提供的 MSBuild 工具,先安装插件:MSBuild。(注意:Jenkins 服务器需安装 MSBuild,建议在 Jenkins 上安装 VS 开发工具,可以在构建出问题的时候打开 VS 调试,省去很多不必要的麻烦)。
2. 全局配置
插件安装完毕后,进入系统管理 -> 全局工具配置 (ConfigureTools) 找到 MSBuild 配置选项:
- Name:自己起个名字
- Path to MSBuild:MSBuild.exe 程序的物理路径
注意:此处 MSBuild.exe 必须与程序所使用 freamwork 版本相对应,此处我在这就遇到了一个大坑,一开始随便找个一个 MSBuild 工具,没想到根本编译不了 C#6.0 的语法。建议直接指向 visual studio 安装目录内的 MSBuild.exe, 可以避免很多问题。如 VS2017 在:Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin 路径内。
3. 项目配置
打开我们之前创建的项目,找到构建选项 -> 增加构建步骤 ->Build a Visual Studio project or solution using MSBuild
-
Name: 选择全局 MSBuild 配置的名称
-
MSBuild Build File: 填写我们的要构建的项目.csproj 文件,所相对工作的路径。如:/Test.csproj
-
Command Line Arguments:MSBuild 的参数如:/t:Rebuild /P:Configuration=Release /p:VisualStudioVersion=14.0 /p:DeployOnBuild=True;PublishProfile=Test.pubxml
- /t:Rebuild 重新生成
- /p:Configuration=Release Release 生成模式
- /p:VisualStudioVersion=14.0 指定子工具集 (VS2015 为 14.0,2017 为 15.0),不设置会报错
- /p:DeployOnBuild=True;PublishProfile=Test.pubxml 使用 Test.pubxml 发布文件来发布项目 .pubxml 文件可在 VS 发布时配置,位于 Properties 文件夹内。
配置完成后,点击构建,查看控制台信息,如能构建成功,则代表我们的配置无误!
4. 遇到的问题
原以为按照度娘的一系列解决方案能够很顺利的构建,可是在连续失败了几十次之后,才明白远远没有那么简单。期间主要遇到几个问题:
- MSBuild 版本不对导致构建不了 C#6.0 的语法
- Jenkins 是讲版本库源代码更新到自己的工作空间内,再执行后续的构建工作。我们的程序很不规范,其中引用了许多不属于自己版本库的第三方依赖包,和一些自己开发的公共库,当时这些第三方包和公共库放在我们 SVN 的另一个版本库里进行管理,因此在构建的时候导致很多程序集找不到引用。
关于问题 1: 上面已经提过,只需要找到对应版本即可
而问题 2: 一开始找了很多资料也没有找到解决方案,后来还是从源代码管理上找到了方案。
方案 1:
借鉴 Nuget 的思想,使用 Nuget 服务器管理我们自己开发的一些公共依赖库。关于 Nuget 管理依赖的文章在另一篇博客里。
方案 2:
就是上面提到的 SVN 外部引用,当时也是走投无路,于是疯狂翻译 Jenkins 的这些英文解释,在翻译到 SVN 插件的 Ignore externals 时,找到了这种方案,就是 SVN 可以设置外部引用,这样在更新版本库的时候就可以把依赖的版本库也更新下来,然后 Jenkins SVN 插件把这个 Ignore externals 选项去掉,然后在 Additional Credentials 选项里填上所依赖版本库的 SVN 配置,就能够把这些依赖也更新到 SVN 工作空间内。
以上两个问题解决后,基本没有遇到太难的问题。由此可见我们的源代码管理的科学、规范是多么的重要。
几十次的构建失败,一堆乱七八糟的引用是多么痛的领悟!
五、通过 Ftp 发布至应用服务器
构建成功后,Test.pubxml 会指定发布的包的路径 (最好是放到工作空间下),按照思路,接下来就是要想办法把发布包 Copy 到应用服务器的根目录下。由于我们的应用服务器都是 windows 系统,因此不能像 linux 系统一样通过 ssh 远程 Copy 过去,当时能想到的就是使用 Ftp 直接上传到应用服务器。
1. 安装插件与环境
Jenkins 安装插件 Publish Over FTP, 应用服务器上需开启 Ftp。
#### 2. 全局配置
系统管理 -> 系统配置下找到 Publish over FTP 配置项
- Name: 起个名字,后面项目配置里会用的到
- HostName:Ftp 主机名 (端口号默认 21,在高级里面可以改)
- Username:Ftp 用户名
- Password:Ftp 密码
3. 项目配置
打开我们之前建的项目,找到构建后操作 -> 增加构建后操作步骤 ->Send build artifacts over FTP
- Name: 选择全局配置里的
- Source files: 选择你的发布包路径 (这里是相对于工作空间的路径)
- Remote directory:放到远程的哪个路径里 (这里是相对于 Ftp 根目录的路径)
配置完成后,点击保存,构建即可!
六、结束语
如上,就基本实现了我们的自动化发布的需求,这期间从早晨六点开始,差不多中午就完成了,当然也并不像上面介绍的那么简单,期间也遇到了许多问题,构建了大概一百多次,才最终成功了第一次。本文主要介绍实现自动化部署的一种基本的思路,当然还有很多方案可以实现我们的需求,甚至不仅仅局限于 Jenkins。而这种方案其中也有许多细节的地方在文章中没有提到,如:如何实现自动化的 Nunit 单元测试,如何定时构建......,因为当时我在完成之后也给我的团队成员提供了一个非常详细的配置文档,并且培训了很多次,但事实证明,讲的越详细越会限制他们自己的主动思考与动手的能力。这也导致了后来我去做其他工作的时候,我们将近一年的时间还是停留在我这半天的研究结果的层面上,而生产环境更是迟迟没有使用。其实思路才是最重要的,有了思路我们就可以通过各种方式来解决我们的问题,还是建议大家注重解决问题的思路,多动手,自己实践,才能学得更透!关于.NET 平台下 Jenkins 实现持续集成与自动化部署的落地与实现的问题与讨论,可以在文章下留言。
Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(一):Jenkins安装
2019/1/31更新,经过我一段时间的使用 建议大家的jenkins还是不要使用docker方式安装 建议大家的jenkins还是不要使用docker方式安装 建议大家的jenkins还是不要使用docker方式安装
非docker方式安装,请参考linux centos 安装Jenkins(非docker方式)
以下是原文内容
写在前面
其实园子里很多大佬都写过,我也是一个搬运工很多东西不是原创的,不过还是想把自己安装的过程,记录下来如果能帮到大家的忙,也是一件功德无量的事;
运行环境
centos:7.2 cpu:1核 2G内存 1M带宽 其实用的腾讯云
安装jenkins
这里的jenkins就不从docker hub里面直接pull镜像安装了,为什么呢,我这里引用大佬的原话:
首先不直接从Docker Store上直接Pull Jenkins 的 Image 文件,因为待会需要进行dotnet core 的 Docker自动部署,需要对宿主机上的Docker进行直接操作,那么需要挂载 Docker 给 Jenkins Image,所以现在需要自己动手编写 Dockerfile 构建自定义的Jenkins。
https://www.cnblogs.com/LongJiangXie/p/7517909.html
1、构建自定义的Dockerfile
# touch Dockerfile
# vim Dockerfile
输入以下内容:
FROM jenkins
USER root
#清除了基础镜像设置的源,切换成腾讯云的jessie源
#使用非腾讯云环境的需要将 tencentyun 改为 aliyun
RUN echo '''' > /etc/apt/sources.list.d/jessie-backports.list \
&& echo "deb http://mirrors.tencentyun.com/debian jessie main contrib non-free" > /etc/apt/sources.list \
&& echo "deb http://mirrors.tencentyun.com/debian jessie-updates main contrib non-free" >> /etc/apt/sources.list \
&& echo "deb http://mirrors.tencentyun.com/debian-security jessie/updates main contrib non-free" >> /etc/apt/sources.list
#更新源并安装缺少的包
RUN apt-get update && apt-get install -y libltdl7 && apt-get update
ARG dockerGid=999
RUN echo "docker:x:${dockerGid}:jenkins" >> /etc/group
# 安装 docker-compose 因为等下构建环境的需要
RUN curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose
2、build镜像
docker build . -t auto-jenkins
看到Successfully 莫名的心情愉悦。这就代表构建成功了;
3、创建jenkins项目文件的挂载目录
mkdir -p /var/jenkins_home
4、修改目录权限
这一步必不可少!会导致权限不足报错
chown -R 1000 /var/jenkins_home
5、run我们自定义jenkins镜像 auto-jenkins
这里我用7080作为对外的jenkins ip(因为我的8080被占用了)
docker run --name jenkins -p 7080:8080 -p 50000:50000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/bin/docker \
-v /var/jenkins_home:/var/jenkins_home \
-d auto-jenkins
run之后使用docker ps
查看运行中的容器,如看到如下图,表示jenkins已正常启动:
6、完成jenkins安装
访问 http://你的服务器ip:7080
这里需要安装密码,证明这是你的服务器,进入容器:
docker exec -it jenkins /bin/bash
cat /var/jenkins_home/secrets/initialAdminPassword
复制密码填好,点击继续;
如图,点击Install suggested plugins,安装jenkins常用插件
安装完毕后:
来到这里,其实安装结束了,填写完管理员信息后,开始你的自动化部署之旅吧!
接下来,请继续看我的另一篇文章 Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(二):部署
[参考]
https://www.cnblogs.com/LongJiangXie/p/7517909.html
原文出处:https://www.cnblogs.com/xiaxiaolu/p/10041788.html
Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(四):发布与回滚
写在前面
我们以前windows跑.net Framework程序的时候,发布,自己乖乖的替换程序;备份,也是自己一个一个的重命名备份;回滚,发布遇到问题的回滚更是不用说了;运维很是怕我们 这些用windows的啊;
那全面拥抱linux的一一.net core 时代 ,是如何处理这些个问题的呢?
噔噔蹬蹬~请往下看。
运行环境
centos:7.2
cpu:1核 2G内存 1M带宽
Jenkins ver. 2.150.1
一台安装jenkins的机器。
(本文例子不一定要安装jenkins,但实际项目是要用jenkins的)
背景
我们目前的应用部署环境是这样划分的(暂定):
开发环境
环境变量:Development
开发环境就是我们平时的开发用的机器,错误、异常尽可能多的报出来这种。css、js、页面文件等各种静态资源也不做压缩处理,连接测试库;
开发环境的部署:开发人员按自己习惯自己部署;
测试环境
环境变量:Staging
测试环境也就是测试同学测试用的环境,为了贴合生产环境的多机器部署,我们测试机器也有多台,目前我们搭建了jenkins可由测试同学自己部署;错误信息已做捕捉处理,静态文件同样不压缩,连接测试库;
测试环境的部署:docker+docker-compose部署,我们在项目里面编写好了Staging.Dockerfile、docker-compose.yml还有对应的测试环境发布的shell脚本,借助jenkins来进行参数化的构建。参数包括程序运行的端口、绑定的ip,consul配置等等。哦对了,我们目前的构建步骤大概是:
去gitlab拉取最新程序代码;
执行单元测试和集成测试,只有通过单元测试和集成测试才能继续步骤3,否则部署失败终止:
dotnet restore->build->publish,将生成产品打包成一个镜像;
使用docker-compose down 停止、移除上次的构建;
使用docker-compose up 这个强大的命令,构建新的镜像、启动容器;
清除临时镜像,构建完成;
单元测试用dotnet test 命令;
这里我们还可以看到,配置文件也一并被打包到镜像里面了,修改配置文件也需要重新构建的;
预生产环境
环境变量:Staging
预生产环境是相对于测试环境来说,无论数据、配置还是架构都是更加接近生产环境的存在了。一般还是连接的数据库是预生产环境的数据库(同步了生产环境的数据的),甚至有的使用会直接连接生产环境的库(一般不练、只读账号等控制);不过我们公司还是连接的测试库
然后静态文件压缩啊、什么的这些,生产环境怎么处理,这里也怎么处理;
通过测试环境测试的程序才可以部署到这里,这里测试通过后,才可以部署到生产环境;
预生产环境的部署:由项目负责人或者运维部署,需要比较大权限才可以;
生产环境
环境变量:Production
生产环境一般应配置为最大限度地提高安全性、性能和应用可靠性,包括但不限于以下举措:
- 全面启用分布式缓存
- 客户端资源被捆绑和缩小,并可能从 CDN (网络分发)提供。
- 必须禁用诊断错误页。
- 启用友好错误页、一致的错误响应。
- 启用生产记录和监视。
生产环境的部署:运维部署,我们开发没有权限了;
部署的背景我们的条件等等大概讲完了,下面我们说说生产环境我们怎么设计容器的。
生产环境的容器设计
由于生产环境经常需要修改配置、保留日志信息、需考虑程序的备份与回滚等等,我们不能像上面的测试环境一样,把整个发布的产品打包成一个镜像了,我们需要做特殊的处理;
熟悉docker的同学,肯定会想到:挂载
对的,我们就这么处理,我们用docker -v 处理这头痛的问题;
程序的目录结构
我们程序的目录结构是这样的:
backs:放历史版本的程序文件,按备份日期压缩命名;
logs:程序的运行日志文件;
program:当前运行的程序;
logs 和 program 目录,使用 docker -v 挂载;
backs目录截图:
发布
发布步骤
同步通过测试的预生产环境的程序文件;
压缩、备份上一版本的程序文件;
通过更改文件夹名称的方式,当前运行程序替换为最新的;
重启程序;
心跳检测:通过输出部署成功,未通过执行回滚操作。
发布脚本(Production.Publish.sh)
#!/bin/bash function success() { echo -e "\033[32m $1 \033[0m" } function error() { echo -e "\033[31m\033[01m $1 \033[0m" } echo "publish beging。。。。。。" remotePath=$1 healthCheckUrl=$2 defaulPaht= $3; bashPath=${defaulPaht:=`pwd`} if [ ! $remotePath ]; then echo "warn:remotePath should't be empty!" exit fi if [ ! $bashPath ]; then error "error:bashPath should't be empty!" exit fi echo "bashpath is ${bashPath}" programPath="${bashPath}/program" logPath="${bashPath}/logs" backPath="${bashPath}/backs" publistemp="${bashPath}/publistemp" mkdir -p $programPath mkdir -p $logPath mkdir -p $backPath mkdir -p $publistemp #remote git or scp #这里同步预生产环境的程序文件,这里写死了ip只是示例,scp也只是示例 #大家可以采用更安全,更有效率的同步文件方式 scp -r [email protected]:${remotePath}"/.*" ${publistemp} if [ $? ]; then echo "info:copy successful!" #压缩、备份当前运行程序到backs文件夹 backFileName=`date +%Y%m%d%H%M%s`".tar.gz" `cd ${programPath} && tar -zcPf ${backPath}/${backFileName} *` #replace #替换程序 if [ $? ]; then mv $programPath ${programPath}"Old" mv $publistemp ${programPath} rm -r ${programPath}"Old" #publis fail ,then Production.Rollback if [ $healthCheckUrl ]; then curl $healthCheckUrl if [ $? -ne 0 ]; then error "error:public Failed!" #心跳检测失败,执行回滚 if [ -f "Production.Rollback.sh" ];then echo "************************************ exec Rollbacking...... ************************************" ./Production.Rollback.sh ${backPath} else error "error:Production.Rollback.sh is not existing!"; fi exit fi fi success "publish Successful!" else error "error:file tar Failed!" fi else error "error:remote files copy Failed,Maybe you should checkout your ssh auth!" fi
Dockerfile
Dockerfile比较简单
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base workdir /app ARG RUN_PORT=${RUN_PORT:-""} ARG CONSUL_TO_NETCOREHOST=${CONSUL_TO_NETCOREHOST:-""} ARG ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-""} ENV RUN_PORT=${RUN_PORT} CONSUL_TO_NETCOREHOST=${CONSUL_TO_NETCOREHOST} ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT} ENTRYPOINT ["dotnet","Member.WebApi.dll"]
docker-compose
version: '3.4' services: member.webapi: image: memberwebapi${RUN_PORT} build: context: . dockerfile: ${ASPNETCORE_ENVIRONMENT}.Dockerfile network_mode: "host" restart: always environment: - RUN_PORT=${RUN_PORT} - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT} - CONSUL_TO_NETCOREHOST=${CONSUL_TO_NETCOREHOST} command: - "--port" - "${RUN_PORT}" #就是这里挂载 volumes: - ../program/:/app/ - ../logs/:/app/logs
回滚
回滚其实就是发布的逆操作;
发布是:同步最新程序->备份当前运行程序->替换;
回滚是->找到上一次的备份->删掉的当前运行程序->替换;
Production.Rollback.sh
#!/bin/bash echo "rollback beging。。。。。。" defaulPaht= $1; bashPath=${defaulPaht:=`pwd`} programPath="${bashPath}/program" backPath="${bashPath}/backs" lastFile=`cd ${backPath} &&ls -t |head -n1|awk '{print $0}'` if [ ! $lastFile ];then echo "error:none backup program!" fi lastFilePath="${backPath}/${lastFile}" echo $lastFilePath if [ -f $lastFilePath ];then echo "rollback program:${lastFilePath}" programOldpath="${programPath}Old" mkdir -p ${programOldpath} tar zxvf ${lastFilePath} -C ${programOldpath} #replace if [ $? ]; then rm -r ${programPath} mv ${programOldpath} ${programPath} echo "rollback Successful!" else echo "error:backup program is not existing!" fi else echo "error:backup program is not existing!" fi
最后贴一个运行截图:
总结
毫不夸张地说,Jenkins + Dockor 让.net 完全从一个刀耕火种的原始人一下子穿越到了全自动化的现代;
文章的思路可以借鉴,脚本改改也可以用,但需理解思路;
有的同学可能会问,为什么生产环境的部署,不能像测试环境一样直接拉取master的代码构建,我这里的回答是涉及到配置的权限问题、devops的学习到位问题。历史原因等,我们暂定这样,后面实践,我乐于分享;
本文的实践都有很大的局限性,比如有现成的工具、有更强大的插件等等可以更简单的去解决这个问题之类的,我可能还不知道;比如我的shell写的一塌糊涂等等。。欢迎沟通,不理赐教。
晚安~
关于docker+jenkins 实现 spring boot 项目持续集成自动化部署和jenkins和docker实现自动化构建部署的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于.NET 持续集成与自动化部署之路第一篇 - 半天搭建你的 Jenkins 持续集成与自动化部署系统、.NET 持续集成与自动化部署之路第一篇 —— 半天搭建你的 Jenkins 持续集成与自动化部署系统、Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(一):Jenkins安装、Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(四):发布与回滚的相关信息,请在本站寻找。
本文标签: