搭建jenkins配合gitee实现自动部署
在上一篇文章里我讲到了自己最近日子里与自动部署这件事的爱恨情仇,最后由于github太卡,但又抵抗不了墙的存在,最后更改了自己项目分享和部署的方案。
在之前的日子里,我的全部项目都在github里,需要分享的就设置为public,只是部署使用的就用private。变更方案后,github只用作代码分享,因为它毕竟是一个社交网站。用作部署的代码转移到码云。再在自己的服务器上搭建一个jenkins用于自动部署。
jenkins是一个开源的ci/cd工具,可以用于项目的自动部署。它还有很多其他作用,但我没用上。
jenkins的中文文档是:Jenkins 用户手册 。
环境准备
由于是在自己的服务器上搭建,所以下面一切的描述均基于CentOS7操作系统,运行于阿里云的ECS T5云主机。
参考jenkins用户指南,我们知道jenkins需要
- 机器要求:
- 256 MB 内存,建议大于 512 MB
- 10 GB 的硬盘空间(用于 Jenkins 和 Docker 镜像)
- 需要安装以下软件:
- Java 8 ( JRE 或者 JDK 都可以)
- Docker (导航到网站顶部的Get Docker链接以访问适合您平台的Docker下载)
安装Java8
这部分参考Linux下通过yum命令安装jdk8。
查看已安装/卸载
先查看有没有已经安装java8。
# rpm -qa | grep java
javapackages-tools-3.4.1-11.el7.noarch
python-javapackages-3.4.1-11.el7.noarch
java-1.8.0-openjdk-headless-1.8.0.242.b08-0.el7_7.x86_64
tzdata-java-2019c-1.el7.noarch
java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64
由于我已经安装,所以会显示一系列名字里带有java的包。如果已经安装其他版本的java jdk,使用
# rpm -e --allmatches --nodeps java-1.6.0-openjdk-1.6.0.38-1.13.10.4.el6.x86_64
卸载。
查找jdk8包
# yum search jdk
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
* epel: mirrors.yun-idc.com
* webtatic: uk.repo.webtatic.com
======================================================== N/S matched: jdk ========================================================
copy-jdk-configs.noarch : JDKs configuration files copier
java-1.6.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.6.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.6.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.6.0-openjdk-javadoc.x86_64 : OpenJDK API Documentation
java-1.6.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.7.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.7.0-openjdk-accessibility.x86_64 : OpenJDK accessibility connector
java-1.7.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.7.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.7.0-openjdk-headless.x86_64 : The OpenJDK runtime environment without audio and video support
java-1.7.0-openjdk-javadoc.noarch : OpenJDK API Documentation
java-1.7.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.8.0-openjdk.i686 : OpenJDK Runtime Environment 8
java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment 8
java-1.8.0-openjdk-accessibility.i686 : OpenJDK accessibility connector
java-1.8.0-openjdk-accessibility.x86_64 : OpenJDK accessibility connector
java-1.8.0-openjdk-accessibility-debug.i686 : OpenJDK 8 accessibility connector for packages with debug on
java-1.8.0-openjdk-accessibility-debug.x86_64 : OpenJDK 8 accessibility connector for packages with debug on
java-1.8.0-openjdk-debug.i686 : OpenJDK Runtime Environment 8 with full debug on
java-1.8.0-openjdk-debug.x86_64 : OpenJDK Runtime Environment 8 with full debug on
java-1.8.0-openjdk-demo.i686 : OpenJDK Demos 8
java-1.8.0-openjdk-demo.x86_64 : OpenJDK Demos 8
java-1.8.0-openjdk-demo-debug.i686 : OpenJDK Demos 8 with full debug on
java-1.8.0-openjdk-demo-debug.x86_64 : OpenJDK Demos 8 with full debug on
java-1.8.0-openjdk-devel.i686 : OpenJDK Development Environment 8
java-1.8.0-openjdk-devel.x86_64 : OpenJDK Development Environment 8
java-1.8.0-openjdk-devel-debug.i686 : OpenJDK Development Environment 8 with full debug on
java-1.8.0-openjdk-devel-debug.x86_64 : OpenJDK Development Environment 8 with full debug on
java-1.8.0-openjdk-headless.i686 : OpenJDK Headless Runtime Environment 8
java-1.8.0-openjdk-headless.x86_64 : OpenJDK Headless Runtime Environment 8
java-1.8.0-openjdk-headless-debug.i686 : OpenJDK Runtime Environment with full debug on
java-1.8.0-openjdk-headless-debug.x86_64 : OpenJDK Runtime Environment with full debug on
java-1.8.0-openjdk-javadoc.noarch : OpenJDK 8 API documentation
java-1.8.0-openjdk-javadoc-debug.noarch : OpenJDK 8 API documentation for packages with debug on
java-1.8.0-openjdk-javadoc-zip.noarch : OpenJDK 8 API documentation compressed in a single archive
java-1.8.0-openjdk-javadoc-zip-debug.noarch : OpenJDK 8 API documentation compressed in a single archive for packages with debug
: on
java-1.8.0-openjdk-src.i686 : OpenJDK Source Bundle 8
java-1.8.0-openjdk-src.x86_64 : OpenJDK Source Bundle 8
java-1.8.0-openjdk-src-debug.i686 : OpenJDK Source Bundle 8 for packages with debug on
java-1.8.0-openjdk-src-debug.x86_64 : OpenJDK Source Bundle 8 for packages with debug on
...
名称和简介匹配 only,使用“search all”试试。
安装
在输出的包名中找到需要的java8安装包,执行命令
# yum install java-1.8.0-openjdk.x86_64
进行安装。
安装过程中会同时安装依赖项。
安装成功后,使用
# java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)
检测是否已经安装成功。
安装成功后,就可以在后面使用java
命令了。
安装docker
就没啥好解释的,直接
# yum install docker
安装就完事了。
下载jenkins
官方文档给的链接是http://mirrors.jenkins.io/war-stable/latest/jenkins.war,我们这里可以使用清华大学开源镜像站-jenkins,使用wget
下载最新的镜像。
# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.231/jenkins.war
启动jenkins
cd
到下载目录下,使用命令
# java -jar jenkins.war --httpPort=8080
来启动jenkins。
如果8080端口被占用了,可以使用任何其他未占用接口。如果安装了防火墙,则需要将端口加到防火墙白名单里。如果像我一样用了云主机,则需要在安全组配置允许此端口通行。
启动成功后,在浏览器访问http://ip:8080,按照引导进行安装。
启动jenkins安装程序的时候会在控制台显示一个密码,在第一步会用到。
如果控制台没有显示,可以使用cat
命令查看界面上显示的文件。
下一步选择插件。
选择第二个,然后搜索Chinese,安装一个中文插件就行。其他安装起来太慢,也没啥用。
下一步创建用户,完事就能进jenkins的界面了。
现在有一个问题,命令行那边还等着呢,我们关闭了控制台就没法用了啊。
使用守护进程方式启动jenkins
参考了这篇文章,首先使用yum安装daemonize。
# yum install daemonize
daemonize
的使用方法是
daemonize -E BUILD_ID=dontKillMe -o some.log -c /home/User/victor /home/User/victor/test.sh
-E BUILD_ID=dontKillMe
是这次运行的id,可以随便写一个。
-o some.log
是这次运行的日志文件。
-c /home/User/victor
是运行前要切换的目录。
/home/User/victor/test.sh
是要启动的脚本。
于是我们前往一个特殊目录cd /usr/local/bin && mkdir jenkins
,编写一个脚本,用来启动jenkins。
# vim jenkins_daemonize.sh
#!/bin/bash
java -jar /usr/local/bin/jenkins/jenkins.war --httpPort=8081
<esc>
:eq
再编写另一个脚本,使用daemonize
运行上一个脚本。
# vim jenkins_start.sh
#!/bin/bash
daemonize -E BUILD_ID=dontKillMe -o jenkins.log -c /usr/local/bin/jenkins "/usr/local/bin/jenkins/jenkins_daemonize.sh"
<esc>
:eq
为啥要写俩脚本呢,因为daemonize
最后一个参数接受的就是sh脚本啊。
再建立一个日志文件。
# touch jenkins.log
修改脚本文件和日志文件的权限。
# chmod +x jenkins_daemonize.sh
# chmod +x jenkins_start.sh
# chmod 777 jenkins.log
然后运行脚本jenkins_start.sh
,jenkins就以守护进程的方式启动了。
# ./jenkins_start.sh
我们可以使用ps
命令查看运行情况。
# ps -ef | grep jenkins
root 15735 13474 0 21:01 pts/0 00:00:00 grep --color=auto jenkins
root 30515 1 0 4月14 ? 00:00:00 /bin/bash /usr/local/bin/jenkins/jenkins_daemonize.sh
root 30516 30515 0 4月14 ? 00:03:58 java -jar /usr/local/bin/jenkins/jenkins.war --httpPort=8081
配置nginx反向代理
用daemonize
启动成功后,服务启动在http://127.0.0.1:8081上,这时候我们需要配置nginx代理,从而可以使用域名访问。
server {
listen 80;
server_name jenkins.xtzero.me;
location / {
proxy_pass http://127.0.0.1:8081;
}
}
保存后重新载入nginx配置。
# nginx -s reload
在浏览器中访问http://jenkins.xtzero.me,即可看到启动好的jenkins。
jenkins与gitee联动
先将代码传到gitee,同一个项目下的不同子项目使用分支实现,例如我的博客分为life、tech、api,在仓库里新建三个分支。
联动的思路是,在jenkins里配置好构建脚本,gitee push成功时告诉jenkins仓库名和分支名,jenkins分别进行构建。构建的过程就是在服务器上拉取代码,执行安装、构建,再将生成好的资源复制到网页目录。
下面将用我的blog项目进行说明。
需要解释的是,jenkins有gitee插件,可以像runner那样来进行自动部署。由于我的需求特殊,也有更省事(或许是我更能理解的方式)来解决,所以我决定走自己的路线。
配置jenkins 流水线
点击jenkins首页的新建item,任务名称为“仓库名_分支名”,任务类型选择criswu擅长的freestyle。
进入任务配置,勾选触发远程构建
在最下方选择增加构建步骤,选择shell方式
添加脚本进去
rm -rf blog_tech
git clone -b tech git@gitee.com:xtzero/blog.git blog_tech
cd blog_tech
yarn install
hexo g
rm -rf /data/www/blog/tech
cp -R ../blog_tech /data/www/blog/tech
我的博客是用hexo搭建的,所以会进行上面的步骤。
jenkins的原理是,在~/.jenkins/workspace
目录下会为每一个项目建立一个单独的目录。为了避免重复,在git clone的时候我们依然使用“仓库名_分支名”的形式。
clone项目后,执行安装、构建。构建出静态资源后,删除网站目录的旧版文件,把构建好的静态资源复制进去。一次流水线结束。
由于勾选了远程构建,所以我们需要在gitee push成功的时候发送消息到jenkins。这时候就需要服务器上有一个接口脚本来接受push消息,再请求jenkins的远程构建接口。
脚本使用php编写。
<?php
require_once 'curl.php';
$avaliableRepoBranch = [
'blog_tech',
'blog_life',
'blog_api',
'xtCBook_master',
'brown-and-cony_master'
];
$postData = file_get_contents('php://input');
$d = json_decode($postData, true);
$refArr = explode('/', $d['ref']);
$branchName = $refArr[count($refArr) - 1];
$repoName = $d['repository']['name'];
$repoAndBranch = implode('_', [$repoName, $branchName]);
if (in_array($repoAndBranch, $avaliableRepoBranch)) {
echo '访问了http://jenkins.xtzero.me/job/'.$repoAndBranch.'/build?token=jenkins';
echo curlGet('http://jenkins.xtzero.me/job/'.$repoAndBranch.'/build?token=jenkins');
} else {
echo '不在数组里,构建直接他妈结束';
}
编写好脚本后,配置nginx解析。
server {
listen 80;
server_name webhook.jenkins.xtzero.me;
location ~ \.php$ {
root /data/www/forJenkins;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
jenkins远程构建地址的特点是http://jenkins地址/job/任务名称/build?token=TOKEN
,由于我们的任务名称是仓库名和分支名决定的,所以只要在push信息里获取到仓库名和分支名,就可以请求到对应的jenkins地址了。
前往gitee项目页面,点击右上角管理,选择WebHooks,将上一步配置的接口地址填上。
一旦执行了push动作,就会在WebHooks页面看到请求结果。
前往jenkins页面,可以看到构建已经开始了。
点进去具体一个构建,点击左侧控制台输出,可以看到详细的控制台输出信息。
访问对应的网站地址,可以看到确实已经构建成功。
配置更多项目
每一个项目的构建流程都不尽相同,所以需要对每一个项目配置不同的构建脚本。但是思路都大致相同,都是clone项目、安装、构建、复制到网站目录。
依次配置好需要构建的项目,就可以开始快乐写代码了。
完事
就完事了。今天一日三更,不知道下一次是哪年更新了。