是时候使用自动部署了

身为一个后端程序员,对于部署自己开发服务肯定是很开心的,因为经过迭代开发,服务终于可以交给用户(或者自己)使用了,然而你发现了吗?在部署的时候却总在做着重复的,容易出错的事情,比如配置文件的更换,上传jar包(SpringBoot)到服务器,感觉这些事情做了一遍又一遍的,这些名命令行敲了一次又一次,是不是开始感觉有一点无聊了呢?如果是的话,那么是时候来试试自动部署了。

先交代一下环境

之前的一段时间我用python脚本简化了发布的流程,但是给我的感觉很不好,虽然也可以达到一键发布的效果,但感觉还是不舒服,所以才想上Jenkins。下面说一下我大概的环境。

  1. Ubuntu 18 LTS,一台用来发布服务(发布服务的环境后面会主动介绍),一台用来部署服务(上面有一个nginx运行在80和443端口上,会反向代理从发布服务器部署上来的SpringBoot服务,意味着发布的时候我只要运行这个jar就好了)
  2. SpringBoot的一个博客项目,比较简单
  3. jdk用的是OpenJDK11,SpringBoot支持jdk11后就切换过来了,主要是Oracle的JDK太难下载了现在
  4. 构建工具用的是Gradle,也没啥,就图个新鲜把
  5. 没有部署其他的服务,比如mysql等等,因为他们在我的另一台数据机器上

说一下流程

我这边把一个Spring Boot的项目一键自动部署到服务器上。其中简单的涉及到了配置文件的替换,gradle构建,上传jar包,运行jar包。

  1. 先是在ubuntu这台发布服务器上安装好Jenkins,然后同时安装好构建的环境,比如Gradle和Openjdk11
  2. 对Jenkins进行这些工具的配置
  3. 在Jenkins上创建一个自动部署的项目,部署的全过程都在这里
  4. build now,一键部署,查看日志排除,并查看服务是否运行

安装Jenkins

在发布服务器上安装Jenkins,安装的教程还是挺多的,如果是Ubutnu的话,我这边就简单的贴一下命令行命令吧,也很快。

wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -

sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

sudo apt-get update

sudo apt-get install jenkins

然后相关文件的位置:

  1. 配置文件在: /etc/default/jenkins
  2. 日志文件(可以查看到Jenkins的初始密码,后面需要用到)在: /var/log/jenkins/jenkins.log

其他的事项:

  1. 如果不更改默认配置的话,那么Jenkins默认运行在8080端口上,访问192.168.0.107:8080(视环境而定)即可
  2. 一进去会要你输入默认的密码,在上面说到的日志文件里(独立的长串字符,我安装的很早了,没有图片了),在Jenkins的日志上可以看到密码,复制输入
  3. 然后是选择插件,这里除了默认勾上的外,我还做了这些:
    • 取消勾选ant和svn
    • 勾选了Gradle Plugin,Publish Over SSH,SSH Plugin
  4. 然后等待插件的安装,最后设置一个用户进入即可看到如下页面(我这个页面是构建过一个项目的,会有点差异,不过进来了就说明配置好了) Jenkins的首页

使用docker来安装Jenkins

上述内容在使用docker部署之后,有少数不同:

  1. 端口使用容器映射,我使用了7000端口
  2. 默认的密码需要去容器内查看
  3. 所有的环境都让jenkins去安装(后面的本地环境都换成jenkins默认的)

准备好构建环境

到这里你应该已经安装好了Jenkins,接下来就是把发布服务器上的构建环境给搭建好了,我这里准备好了OpenJDK11和Gradle,JDK11的话用的Ubuntu的apt命令安装,Gradle是先去安装了SDKMAN,然后用SDKMAN安装的sdk命令安装好了gradle。

还有就是我的项目是放在github上的,随意需要下载git,同样使用的apt直接装一个就好了

配置Jenkins

配置工具

Manage Jenkins->Global Tool Configuration

  1. 配置Gradle

    • 可以选择让Jenkins自动下载,勾上Install automatically就好了
    • 我选择用我自己的,也就配一个目录就好了
    • Jenkins_install_gradle
  2. 配置git

    • 这里我就默认了
    • jenkins_install_git

然后Ok即可(我习惯先apply然后ok)

配置系统设置

  1. 配置Publish over SSH,用来把打包好的文件上传到服务器,并且执行命令
    • 之前没仔细看,发现好像只能用ssh key来上传
    • Passphrase: ssh key的密码(如果有的话)
    • Path to key:ssh key的路径
    • Key:key的内容,和Path to key填一个就好了
    • SSH Servers
      • Name: 取一个好记的名字
      • Hostname: 主机名
      • Username: 用户名
      • Remote Directory: 全局的远程目录,在后面上传文件的时候会加上这个前缀
      • 再往下就是一些代理设置,我设置了一下,默认情况下是不用设置的(我的小鸡在日本,慢的一批)

Jenkins_config_ssh_server

同样ok即可,然后回到首页

配置项目的配置文件

因为我的项目在git上是公开库,所以一些正式环境的东西没有提交在上面,所以这边会把正式环境的配置放在Jenkins上,拉去git项目下来,把配置文件给替换就好了

依旧是Manage Jenkins->Managed files->Add a new Config->Custom file

Content里把配置文件的内容写好就好了

project_config

创建并配置项目

该配置的都配置好了,现在就可以开始创建一个自动部署的项目了 点击New Item然后输入项目名并先选择Freestyle project,然后OK即可 start_jenkins_project

进去后会进入到项目的配置界面,很多选项可以通过英文大概的看懂,所以我只说我这边会用到的。

  1. 首先是把源码给拉取下来,在Source Code Management选项卡勾选git,然后在Repository URL里输入项目的git地址就好了,我的是公开库所以不用认证就可以拉下来,如果是私有库,需要认证,点击Add那块跟着操作走就好了 jenkins_project_git_source

  2. 把之前设置的配置文件拷贝进项目里 setting_project_config

  3. 设置build里的Gradle

    • Add build step->Invoke Gradle script
    • 这里如果自己有配置Gradle就选自己的,也可以用Use Gradle Wrapper setting_gradle
  4. 设置build的push ssh server

    • Add build step->Send files or execute commands over SSH
    • 这里配置好让Jenkins自动上传打包好的文件,然后执行命令行去运行,name就是之前配置的Publish over SSH里填的名字,这里会先上传文件,然后运行Exec command
    • push_ssh_server
    • 这里有一个Remove prefix当时我理解了好一会,实际上就是在上传的时候Remote directory+Source files才是上传的目录,但我们服务器的目录肯定和本地不一样的。我们只是想要Remote directory+xxx.jar这样的形式。所以这个Remove prefix就是起这个作用,向我上面配置的可以把我上面本地目录的路径上的build/libs给清空掉,这样我的上传目录就是Remote directory+blog-service-4.0.0.jar了。
  5. 配置完了,点击ok保存,回到了当前项目的面板,左边有个Build Now,启动部署吧!!!

查看日志发现问题并解决

看起来一切都是很美好的,但是本来发布一个服务就不是一件轻松的事情,有很大的可能会build失败,我们去哪里看构建的进程日志呢。

在项目左下角有一个Build History,每一个历史都可以点进去看

build_history

进去后点击Console Output就可以看到部署的日志啦,根据报错不断调整重试,最终完成部署。

其他

下面是列一些进阶或者是需要考虑的地方

  1. 数据库的更改,需要运行SQL脚本
  2. 可能需要同时部署其他的服务或者依赖其他服务的服务(微服务这样的)
  3. webhooks
  4. docker

其实一路走下来,发现Jenkins就像是流水线,一步步的把任务完成,直到结束,任务的顺序可以任意调整,非常自由。

感觉Jenkins包含的东西很多,我也可以慢慢的摸索,想办法去实践,其实在公司环境有自动部署需求的话,那应该最容易学会了,因为有真实环境嘛。其实写了这么多,我感觉也没有写完,也很怕漏掉什么,不过慢慢发现吧,也欢迎大家提问纠错,一起讨论学习

更新

  • 2019-11-23: 使用docker部署jenkins,更加方便,且可备份