前端自动部署实践——Jenkins的安装与配置

说起来,Jenkins其实和Linux自带的crontab有点像,都是满足特定条件后执行脚本。但是Jenkins触发任务的形式更加灵活,并不局限于定时,所以还是很有用的。

安装

按照惯例,遇到Linux的问题先说环境:系统是Ubuntu16.04,已经提前安装了JDK 1.8,没有用docker,并且已经打开了防火墙。有时候安装好了但访问不了,就是因为防火墙没打开。

其实安装流程很简单,按照官网的流程走一遍就行:

wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

如果这么安装能成功,那最好了。但是往往会遇到各种问题。我遇到的报错信息是这样:

Aug 06 22:33:57 iZuf699cacb5hvp8me6ft6Z systemd[1]: Starting LSB: Start Jenkins at boot time...
Aug 06 22:33:57 iZuf699cacb5hvp8me6ft6Z jenkins[24569]: ERROR: No Java executable found in current PATH: /bin:/usr/bin:/sbin:/usr/sbin
Aug 06 22:33:57 iZuf699cacb5hvp8me6ft6Z jenkins[24569]: If you actually have java installed on the system make sure the executable is in the aforementioned path and that 'type -p java' re
Aug 06 22:33:57 iZuf699cacb5hvp8me6ft6Z systemd[1]: jenkins.service: Control process exited, code=exited status=1
Aug 06 22:33:57 iZuf699cacb5hvp8me6ft6Z systemd[1]: Failed to start LSB: Start Jenkins at boot time.
Aug 06 22:33:57 iZuf699cacb5hvp8me6ft6Z systemd[1]: jenkins.service: Unit entered failed state.
Aug 06 22:33:57 iZuf699cacb5hvp8me6ft6Z systemd[1]: jenkins.service: Failed with result 'exit-code'.

一开始我看到Start Jenkins at boot time,以为是端口冲突,因为这个报错是网络问题,而且Jenkins的默认端口是8080,和服务器上已经有的Tomcat冲突了。所以修改Jenkins的配置文件,把端口改成8085:

# /etc/default/jenkins
HTTP_PORT=8085
# /etc/init.d/jenkins
check_tcp_port "http" "$HTTP_PORT" "8085" "$HTTP_HOST" "0.0.0.0" || return 2

虽然看网上说只需要修改前一个,但最好两个文件都改了,因为只修改其中一个还是有可能报错。

解决了端口问题之后再次启动,仍然报错。这次是提示No Java executable found in current PATH,但是我已经安装了Java……按照他给的提示,输入type -p java进行检查。如果是配置不正确,输出应该为空;但是JDK的路径好好地躺在那呢。而且Tomcat就在8080跑得好好的,说明不是这个问题。建立软链接:

ln -s /usr/local/jdk1.8/bin/java /usr/bin/java

但是还是报错。事实上,不应该在/usr/bin里建立链接,而应该在/bin里建立链接。也就是说,命令应该长这样:

ln -s /usr/local/jdk1.8/bin/java /bin/java

至于原因,因为我是在root用户下操作的,/usr目录属于其他用户,自然没用。同样的,对于其他用户,软链接放在/bin也不一定有用。比如下文会提到的,Jenkins属于其他用户,如果放在/bin里会遇到问题。但是这里只是启动服务,而且启动服务(作为系统服务,开机自动启动)确实需要root权限,所以放在/bin里是合适的。

如果不出问题,Jenkins应该可以访问了,地址是[服务器IP]:[之前设置的Jenkins端口],比如192.168.0.1:8085。

然后就是初始化设置,这里不再赘述,按照引导输入解锁密码后,选择安装推荐的插件(一般来说推荐的就足够了),一路往下就行。
在这里插入图片描述一般来说,安装完并且设置完用户后,页面会自动跳转。当看到这个界面的时候,就可以开始下一步的配置了:
在这里插入图片描述
这里可能遇到白屏的问题。如果Jenkins安装完之后一直白屏,也就是一直卡在SetupWizard [Jenkins] 这个页面,首先试试刷新页面,如果刷新页面之后仍然没有反应,到服务器上重启Jenkins服务(systemctl restart jenkins)一般就能解决。

至于无法访问,一般是配置问题,最好去检查一下之前的端口设置,以及Java环境是否配置正确。

配置

首先需要强调的是,Jenkins运行时是没有root权限的。因为我们从/etc/passwd文件里可以看到:

jenkins:x:110:119:Jenkins,,,:/var/lib/jenkins:/bin/bash

Jenkins就是一个普通用户,所以与它相关的设置要在/usr/bin目录下(比如软链接),进行操作的时候也需要用到sudo命令。这一点非常重要,可以避免很多不必要的麻烦。

因为我们操作一般是在root用户下操作的,但是Jenkins执行的时候没有root权限,如果不注意这些,很有可能出现找不到命令或者Permission denied之类的bug。


因为是前端的部署(项目源码在Github上,但不部署到Github page,不然为什么不用Travis呢?),肯定需要在服务器上build,所以需要Node环境,也就是node + npm(一般来说,新版本的node都自带npm)。

安装的过程其实很简单,就是在官网上下载Linux的压缩包,解压后将/bin目录添加到环境变量里(或者软链接,下面会提到)。安装的教程网上有很多,就不赘述了。不过有三点需要注意:

  1. 最好去英文网站下,中文网上的Linux压缩包是32位的,而现在大部分服务器已经是64位了,尤其是云服务器。虽然一般来说64位能兼容32位,但是最好还是用64位的,以免增加不必要的麻烦。

  2. 不要用apt之类的包管理工具直接安装。以我这次的Vue项目为例,官方明确表示需要8.9+的node:

    Vue CLI 需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。

    而通过apt下载的node基本上是4左右的老版本,还需要手动设置和升级。至于下载解压后配置环境变量和通过apt安装后升级哪个更好,就见仁见智吧。

  3. 如果只需要用到node和npm两个命令,通过软链接放进/usr/bin里是可以的;但是如果某些依赖需要npx,以及为了避免一些可能存在的麻烦,可以选择添加环境变量。但是如果添加环境变量,一定要添加到对应用户(一般是jenkins吧……应该没人无聊到去改?)的环境变量里,不然Jenkins会无法识别node命令,在执行脚本的时候报错/usr/bin/env: ‘node’: No such file or directory

安装好了之后,记得用node -vnpm -v确认一下。

然后就是配置SSH。因为需要和Github仓库关联,所以SSH是必要的。获取SSH秘钥的方法跟Git一样,就不再赘述了,基本上就是通过ssh-keygen -t rsa,然后进行设置;而且基本上支持SSH服务的服务器上自带ssh-keygen,也不需要什么额外的配置。然后/root/.ssh/id_rsa是私钥,/root/.ssh/id_rsa.pub是公钥,后面会用到。

生成SSH秘钥并且添加到Github里之后,记得clone一次试试,看看能否正常运作。

然后去Jenkins的“凭据”里添加一个全局的凭据,位置在这里:
在这里插入图片描述
类型选SSH私钥,然后输入从/root/.ssh/id_rsa里获得的私钥并保存就行:
在这里插入图片描述
接下来还需要配置一下Github的webhook服务。到系统管理 > 系统设置里找到Github,然后点击高级,选择“为 Github 指定另外一个 Hook URL”:
在这里插入图片描述
在这里插入图片描述
然后把这里的hook URL复制到对应仓库的webhook里即可:
在这里插入图片描述
添加之后Github会发送一些测试数据来测试连通性。通了之后就可以继续了。关于这一步的必要性,虽然有些人说可以不用,但实测直接用Jenkins的地址无法连通。

然后就是添加一个项目。新建任务的时候最好选freestyle,后面也是基于freestyle的操作。
在这里插入图片描述
源码管理选择Git,然后把仓库的Git地址写进去,然后credentials选之前设置的那个凭据(我直接用了默认名称jenkins):
在这里插入图片描述
填写完成之后可能还会显示Please enter Git repository,稍微等一下就行,感觉Jenkins反应稍微有点迟缓……

如果这一步出现HTTP ERROR 403:
在这里插入图片描述
刷新一下页面就行;我推测是因为网络波动或者网络环境有变化。

构建触发器选择Github hook trigger,因为Github有相应的webhook,不需要太多额外的配置。
在这里插入图片描述
构建一般选shell脚本吧……然后就是把自己的操作流程写成脚本放上去:
在这里插入图片描述
写Linux脚本并不是什么大问题,但还是有几点需要注意:

  1. 一般来说,Jenkins会自动识别服务器的脚本运行环境。但是如果执行不了,可能需要在最前面加上类似于#!/bin/bash的语句来帮助识别。

  2. 不要忘了Jenkins没有root权限,所以命令前面要加上sudo,不然会因为Permission denied导致构建失败。

  3. 如果在脚本里用到了git pull,有可能会报错Please tell me who you are,需要设置一下用户名和邮箱。如果已经设置了用户名和邮箱,但是还是报这个错:

    1. 首先检查是不是设置在root用户下的(这个很常见,相当于没设置);
    2. 然后,不要在脚本里使用类似于sudo git config --global user.email "you@example.com"的命令来进行设置,会报错。
    3. 此外,没必要在服务器上设置(而且可能还得切换到Jenkins这个用户上)。

    解决这个问题,用Jenkins自带的Git plugin就行了,这个插件在系统设置里:
    在这里插入图片描述

  4. 如果在移动文件的过程中遇到用了sudo还是显示Permission denied,或者Jenkins直接没有权限使用sudo的情况,可以试试chmod 777来给权限(一般来说,放在/usr里的文件Jenkins是有权限的),或者直接修改/etc/sudoers给Jenkins权限:

    jenkins ALL=(ALL) NOPASSWD: ALL
    

    在/etc/sudoers的最后一行添加上面的语句即可。如果对Jenkins不放心,可以把后面的ALL改成需要执行的命令。

  5. 如果在执行脚本的过程中长时间卡住,甚至是直接无法访问Jenkins(包括其他服务也无法访问,比如SFTP,类似于死机),一般来说有两种情况:

    1. 服务器硬件不行,比如硬盘空间不足(这个有可能不是卡住,而是直接失败,看情况),或者是内存不足。这种情况,如果是硬盘空间不足,清理一下服务器;如果是内存不足,关掉后台运行的一些进程(比如jar包)或者直接重启试试。如果还不行,这边的建议是加钱(。

    2. 有可能脚本需要命令行交互,或者是启动了某个常驻命令行的服务。针对前一种,比如使用cp命令复制的时候,如果遇到覆盖,会要求确认;但Jenkins自己并不能响应,所以就会一直卡住。解决这个问题一般是加上-f来强制执行,比如把sudo cp -r换成sudo cp -rf。而后一种,比如我在build的时候用到了webpack bundle analyzer的打包分析插件,但是这个启动之后会一直占用8888端口,并且常驻命令行,导致Jenkins无法完成构建,一直卡在这里:

      Webpack Bundle Analyzer is started at http://127.0.0.1:8888
      Use Ctrl+C to close it
      

      解决这个问题也没什么好办法,只能说尽量避免使用这种服务吧……实在不行可以在服务器上手动杀死那个常驻的进程。

      # 找到8888端口对应进程的pid
      sudo lsof -i :8888
      # 用上一步找到的pid杀死进程
      sudo kill -9 xxxx
      

再往后?保存呗。然后可以点击左上角的立即构建,或者去对应的仓库里push一次来进行测试。收到通过Github的webhook传来的消息后,Jenkins会立刻开始执行脚本。执行脚本过程中遇到的一些常见问题上面已经提到了。

如果看到左下角的build history里变成了蓝色,说明构建成功了:
在这里插入图片描述
如果变成红色,说明构建失败。不要随便怀疑Jenkins,绝大多数情况下是自己的脚本写错了。

再然后?没有然后了。我们已经可以从手动部署中解脱出来了(笑)。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值