草庐IT

Jenkins自动化部署实例讲解

阿杆. 2024-02-27 原文

文章目录

前言

你平常在做自己的项目时,是否有过部署项目太麻烦的想法?如果你是单体项目,可能没什么感触,但如果你是微服务项目,相信你应该是有过这种感触的。

这种情况下,我一般会劝你了解一下Jenkins这个玩意。怎么了解呢?我会建议你阅读本文🤡。

本文分为一个简单的Jenkins自动化构建部署实例讲解,如果你还没有安装这个玩意,可以先阅读我的另一篇文章:Linux下的Jenkins安装教程_阿杆.,它会教你如何在Linux上安装Jenkins。


实例讲解

接下来,我会拿出我的用户微服务构建任务的实际配置来向你进行解读,当你了解了Jenkins自动化构建部署的工作原理后,你便可以很快的上手这个玩意,因为你会发现它是如此的简单。

此实例是基于我的开源项目校园博客的Jenkins部分进行讲解的,开源地址:stick-i/scblogs: 🎉校园博客,基于微服务架构且前后端分离的博客社区系统。项目后端技术栈:SpringBoot + SpringCloud + Mybatis-Plus + Nacos + MySQL + Redis + MQ + ElasticSearch + Docker。前端主要是基于Vue2和ElementUI进行开发的。 (github.com)

基本环境

在此之前,我需要介绍一下我的基本环境:

  • 我的操作环境为Windows,但是我要把微服务部署到一台Linux服务器上去,包括Jenkins也是安装在这个上面的。

  • 服务器上安装了Jenkins、Git、Docker、JDK、Maven、NodeJs,都是些拿来构建的东西,都是单独安装的,而不是跑在Docker上。

  • 而项目服务都是跑在Docker上的,还有Redis这种轻量的中间件也跑在Docker上。

  • 我的项目已经在Git仓库里放好了,放github或者gitee或者gitlab都行。

全局工具配置

在Jenkins上,我已经配置好了这些构建工具的路径,以便于Jenkins可以直接调用到他们,在系统管理 -> 全局工具配置 这个页面下,这张图有点长:

在这张图上,你可以看到其中有一部分的配置是有路径的,还有一部分配置是没有路径的,这是因为我把他们的命令路径加到了系统路径上,即使不添加完整路径,Jenkins也可以调用到它们。

创建任务

好,现在我们已经准备好环境了,可以创建一个任务来试试水了,输入任务名称,然后选择构建一个自由风格的软件项目

别问我在哪新建任务,请你返回首页好好看看:

任务配置

源码管理

现在我们已经进入到任务配置界面了,往下划到源码管理的地方,选择Git,然后填写仓库地址等信息:

添加Credentials的时候,如果你会使用SSH密钥的话,建议还是用这个,但你得在机器上进行格外的配置,这里我就不多说了,不会的话直接用账号密码也是可以的:

构建步骤(Build Steps)

第一步:调用Maven

点击增加构建步骤,由于我们是Maven管理的项目,需要先使用Maven构建,所以第一步就用调用顶层Maven目标

选择maven版本,然后target根据项目的实际情况编写,我的命令是这样的:

  1. 先构建jar包,执行install的过程中会先执行package的,所以我直接install。我的项目中单元测试是没怎么梳理的,所以我使用参数-Dmaven.test.skip=true跳过单元测试。
  2. 然后我得打包成docker镜像,我使用的是dockerfile-maven-plugin这个Maven插件,所以打包docker镜像的步骤就也放在maven里面了,构建docker镜像的信息都在项目的pom文件里面。
install -Dmaven.test.skip=true
dockerfile:build -f user-service/user-server/pom.xml

构建完镜像了,接下来我们直接使用这个镜像创建容器然后运行就完事了。

第二步:执行shell启动容器

再添加一个构建步骤,正常情况下我们调用docker通过命令行调用就可以了,所以我们现在也添加一个执行shell的步骤即可。

具体的命令也很简单,就这么几步:

  1. 清理之前的旧镜像。由于我们刚刚构建了一个新的镜像,新镜像和旧镜像的名称和版本我们是没有改的,所以旧的镜像就会自动变成<none>,使用命令docker image prune -f 就可以清理掉这部分镜像。
  2. 停止旧容器运行并删除旧容器。当然我们得先判断一下是否存在旧容器,使用容器名称来进行判断,这部分指令涉及到shelldocker的命令知识,看不懂没关系,可以直接cv,注意修改容器名称就好。
  3. 调用docker启动容器,根据项目实际情况来设定不同的参数,我这里设置了网络模式为host,并且映射了一个容器卷,用于读取nacos的地址,再指定容器名称为user-service,最后指定使用的镜像名称。

大功告成!完整命令如下:

 # 清理镜像
docker image prune -f 

# 清理容器
if [ -n  "$(docker ps -a -f  name=user-service  --format '{{.ID}}' )" ] then
 #停止容器运行
 docker stop $(docker ps -a -f  name=user-service  --format '{{.ID}}' )
 #删除之前的容器
 docker rm $(docker ps -a -f  name=user-service  --format '{{.ID}}' )
fi

# 启动容器
docker run -d  --net=host  -v scblogs-config:/config -e PARAMS="$params"  --name  user-service  scblogs/user-server

最后别忘了点击保存!


后记

经过上面这些步骤,我们完成了一个基本的自动化构建脚本,这个脚本会调用maven把我的项目打包,然后构建成一个docker镜像,再通过一段shell命令去启动这个程序。

如果你想尝试启动这个构建任务的话,你可以回到主页点击右边的绿色符号。

当然,你大概率是会构建失败的😯。因为我的这份实例讲解并没有完全的讲清楚,甚至里面有很多步骤你都看不懂,是不是?

其实我并没有想写一份手把手的Jenkins使用教程,因为这要写的内容实在是太多了!

还记得我在实例讲解的最开始写的吗?写这个构建案例的目的是让你了解Jenkins自动化构建的原理,如果你看到这里已经发现了,这自动化构建,其实就跟我们手动构建部署差不多!只不过是把手动操作的东西设定成了脚本,那你就已经有能力去自己摸索它了。

用用插件、写写脚本,就可以搞定自己项目的自动化部署啦。

实际情况是,我有一台服务器专门用于Jenkins自动化部署,还有一台服务器专门用于生产环境,这两台服务器都可以连接到外网,也可以互相访问到彼此。这是由于Jenkins构建时是会比较吃CPU的,为了不影响生产环境,所以我把它们分开了。当然,这种情况下,脚本也会稍微复杂一点,具体流程大概是下面这样的:

如果你对我的项目感兴趣,欢迎访问项目的GitHub地址:stick-i/scblogs: 🎉校园博客,基于微服务架构且前后端分离的博客社区系统。项目后端技术栈:SpringBoot + SpringCloud + Mybatis-Plus + Nacos + MySQL + Redis + MQ + ElasticSearch + Docker。前端主要是基于Vue2和ElementUI进行开发的。 (github.com)


都看到这里了,各位靓仔、靓妹,请帮我点一个赞吧!

有关Jenkins自动化部署实例讲解的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  3. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  6. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  7. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  10. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

随机推荐