原文链接

前言

我的博客之前一直是手动更新的,需要自己打包,然后上传到网站。但是项目已经托管在github了,所以何不搞个自动部署呢?

想象一下,网站有修改之后,git push之后等几分钟,网站就自动完成了拉取、打包这些工作,自己更新了,多爽!

其实很久之前就有想做自动部署的想法了,一直在拖,最近最近两天效率比较高(不怎么懒),于是花了两天时间搞好了自动部署。

A: 什么! 弄个自动部署花了两天? 太菜了吧!
嗯。是的,其实一小时左右就可以搞完,但是由于刚开始没看到shell报错信息,没定位到问题,后来又因为权限问题,所以这么久。

Webhook

GitHub的webhook可以提供一个push动作的钩子,每当你push成功的时候,会请求一个你指定的URL。

所以自动部署主要实现方式就是:

- 修改代码 push
- github发送请求给你的网站服务器
- 网站服务器收到更新请求,执行自动部署脚本
- 自动部署脚本执行代码拉取,打包,移动文件等动作完成网站的更新部署

大概就是下图这个流程:

webhook

拆分步骤

分析实现方式,其实就需要做下面几步:

  1. 在服务器中安装git并配置密钥,github中添加密钥
  2. 在服务器中克隆仓库
  3. 添加项目钩子 (我这里是.php)
  4. 编辑Shell脚本
  5. 设置仓库的webhook

1. 安装github

在CentOS中,安装git

yum –y install git

之后配置密钥,并在github中绑定密钥,具体操作可以看我的Github基础使用教程:从今天开始使用git 系列一

2. 克隆仓库

我决定将仓库放在/home/www/

git clone T-Blog.git

这样我的仓库就在/home/www/T-blog/中了。

这里插一句,有的程序是不需要打包这个环节的,所以一般将本地仓库放在网站目录,而我需要打包,所以我决定将仓库和网站目录分开使用。

3. 添加项目钩子

这里的钩子就是被请求的URL,我这里是PHP的,其他语言也可以参考这个。

我将钩子部署在/CI.go这个地址上,在go方法中,设置最大过期时间为3分钟,然后执行:
- 转到仓库目录
- 拉取最新版本
- 执行Shell脚本CI.sh

在本文最开始我说过我浪费时间其一就是在用php执行shell命令的时候使用了shell_exec()函数,但是该函数在出错的时候得不到友好的返回(其实经过实测exec/system/passthru均得不到友好的错误返回),所以没有定位好错误。之后找到了一个方法,也就是下面代码中的doShell方法,建议使用该方法执行shell命令。

PS: 我这里设置最大过期时间是为了友好返回,其实也可以更短,网页先结束也行,shell会继续执行的

public function go() {set_time_limit(3 * 60); //最大过期时间3分钟$shellPath = "/home/www/T-Blog";$cmd = "cd $shellPath && sudo git pull && sudo /bin/bash CI.sh";$res = $this -> doShell($cmd);print_r($res); // 主要打印结果给github记录查看,自己测试时查看
}/** 执行shell命令*/
protected function doShell ($cmd, $cwd = null) {$descriptorspec = array(0 => array("pipe", "r"), // stdin1 => array("pipe", "w"), // stdout2 => array("pipe", "w"), // stderr);$proc = proc_open($cmd, $descriptorspec, $pipes, $cwd, null);// $proc为false,表明命令执行失败if ($proc == false) {return false;// do sth with HTTP responseprint_r("命令执行出错!");} else {$stdout = stream_get_contents($pipes[1]);fclose($pipes[1]);$stderr = stream_get_contents($pipes[2]);fclose($pipes[2]);$status = proc_close($proc); // 释放proc}$data = array('stdout' => $stdout, // 标准输出'stderr' => $stderr, // 错误输出'retval' => $status, // 返回值);return $data;
}

但是这样不够安全,为了能够只在有效github的请求进来时运行脚本,需要对githb传过来的东西签名认证一下,所以重新写一下go函数。

public function go() {// webhook上设置的secret$secret = "iimT";// 校验发送位置,正确的情况下自动拉取代码,实现自动部署$signature = $_SERVER['HTTP_X_HUB_SIGNATURE'];if ($signature) {$hash = "sha1=".hash_hmac('sha1', file_get_contents("php://input"), $secret);if (strcmp($signature, $hash) == 0) {// sign sucessset_time_limit(3 * 60); //最大过期时间3分钟$shellPath = "/home/www/T-Blog";$cmd = "cd $shellPath && sudo git pull && sudo /bin/bash CI.sh";$res = $this -> doShell($cmd);print_r($res); // 主要打印结果给github记录查看,自己测试时查看}}
}

这里的$secret变量是用来签名的,后面在GitHub上设置webhook的时候需要需要填写这个值。

其实php中执行的git pull命令可以写在CI.sh中,但是我的CI.sh是在仓库中的,为了让我更新CI之后,服务器能够先拉取最新的代码,然后在执行CI,所以我先拉取再执行了脚本。

4. 编辑Shell脚本

之前说过我的仓库与博客根目录不是同一个目录,所以我的脚本需要完成以下事情:

- 安装依赖 `nmp i`
- 打包 `npm run build`
- 移动dist文件夹中的文件到网站根目录

但是由于我是在root用户下操作,但是web下请求执行脚本是www用户,所以还需要对用户权限做一点处理。我也在这一点浪费了挺多时间。所以添加一点:

- 权限处理

最后脚本需求清单就是:

- 权限处理
- 安装依赖 `nmp i`
- 打包 `npm run build`
- 移动dist文件夹中的文件到网站根目录

开始编写脚本

我的仓库目录在:/home/www/T-Blog

网站根目录在/home/wwwroot/iimt_blog/domain/wwwiimt.me/web

最后脚本如下:

# 安装依赖
install_dependices () {echo "cnpm i" # >> $FILEoutput=`cnpm i`echo "${output}" # >> $FILE
}# 打包
build () {echo "cnpm run build" # >> $FILEoutput=`cnpm run build`echo "${output}" # >> $FILE
}# 更新博客程序
update_src () {# 删除echo "rm -rf ${deployPath}/index.html" # >> $FILEoutput=`rm -rf ${deployPath}/index.html`echo "${output}" # >> $FILE# 删除echo "rm -rf ${deployPath}/static" # >> $FILEoutput=`rm -rf ${deployPath}/static`echo "${output}" # >> $FILE# 更新echo "cp -r ./dist/* ${deployPath}/" # >> $FILEoutput=`cp -r ./dist/* ${deployPath}/`echo "${output}" # >> $FILE
}
echo_start () {echo "---------------    DEPLOY START @$datetime   --------------------------------------" # >> $FILEexport PATH=$PATH:/opt/nodejs/bin/echo $PATHecho "Deploying..."
}echo_end () {echo "Deploy Done, everythings is OK!"datetime=$(date '+%Y-%m-%d %H:%M:%S')echo "---------------    DEPLOY DONE @${datetime}   ----------------------------------------" # >> $FILE
}
# 提升权限
update_authorization () {echo "chown -R www:www ./ && chmod -R 777 ./" # >> $FILEchown -R www:www ./ && chmod -R 777 ./
}echo_start && update_authorization && install_dependices && build && update_src

我将上面需求清单的每一项都写成了函数,最后使用&&配合执行,防止前面没有执行成功触发后面动作。

保存,执行测试一下

./CI.sh

执行

成功完成上面动作,博客根目录文件也更新了。可以去设置github的webhook了。

5. 设置webhook

已经准备好了仓库,并且写好了钩子和脚本。

然后在GitHub上打开我的仓库T-Blog,在settings中找到webhook,添加webhook,填写好信息就OK了。

add webhook

添加之后你还可以在这个webhook的页面中查看之前github的请求,与返回情况,便于调试。

然后在自己电脑上随便做点更改,然后推送到github中,等待3分钟左右,网站就已经自动更新了~

作者:iimT
链接:https://www.jianshu.com/p/8ace5eb85261
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

github仓库项目自动部署到阿里云相关推荐

  1. hexo使用jenkins自动部署到阿里云

    hexo使用jenkins自动部署到阿里云 本地安装hexo npm install hexo-cli -g hexo init blog cd blog npm install hexo serve ...

  2. django项目如何部署到阿里云服务器

    django项目如何部署到阿里云服务器 阿里云服务器购买 在阿里云上搭建项目及安装数据库 使用Git bash将本地项目文件推送到github远程仓库 将github仓库导入阿里云 安装依赖 安装数据 ...

  3. 如何将nodejs项目程序部署到阿里云服务器上

    将nodejs项目程序部署到阿里云服务器上 一.概述 二.具体步骤 1.拥有自己的服务器 2.下载Xshell 3. oneinstack配置web环境 4. XShell连接远程主机 5.更新系统软 ...

  4. springboot项目打包部署到阿里云

    1.打包前准备 1.1. 打包前确认工程中指定的端口在服务器在未被占用. application.properties文件 server.port=8090 并确保改端口已经添加到你的阿里云安全组中, ...

  5. Hexo自动部署到阿里云(Ubantu16.04)【超详细踩坑记录】

    文章目录 前言 修改Apache端口号 思路 正文 1. 服务器创建git用户 2. 服务器打开RSA认证 2.1 开启认证配置 2.2 建立ssh信任关系 3.创建blog.git空仓库 4. he ...

  6. 【自用】VUE项目 宝塔部署 上线阿里云服务器CentOS7.6

    一.给VUE项目打包 1.开始打包 运行命令: npm run build 2.找到打包好的 dist 文件夹 要记住这个dist文件放在了哪儿,记住哦! 二.服务器端安装宝塔面板 1.进入root用 ...

  7. Vue项目自动部署【精简版】NuxtJS + GitHub Actions + Linux 自动部署学习(包含阿里云Linux ECS购买过程、传统部署流程、pm2、Github Actions)

    购买阿里云Linux服务器 如果已有服务器请直接跳转到[传统部署方式] 登录阿里云,访问 云服务器 ECS 购买地址:https://ecs-buy.aliyun.com/ 也可从首页导航菜单进入. ...

  8. 王者荣耀全栈项目部署到阿里云服务器笔记

    王者荣耀全栈项目部署到阿里云服务器笔记 原创Charles_GX 最后发布于2020-03-27 01:27:00 阅读数 177  收藏 展开 王者荣耀全栈项目部署到阿里云服务器笔记 学习的项目来自 ...

  9. Flask框架项目部署:阿里云CentOS操作系统

    Flask框架部署:阿里云CentOS操作系统 写在前面 一. 部署前的准备 1. 一个已在开发环境中完成的Flask项目 1)关于依赖包 2)关于环境变量 2. 阿里云CentOS操作系统云服务器 ...

最新文章

  1. UITableView学习笔记
  2. linux 在终端修改文件,linux命令行学习(42):修改.bashrc文件
  3. 使用docker镜像搭建svn+Apache环境
  4. 使用postman和SAP C4C OData服务创建销售订单
  5. maxcompute 2.0复杂数据类型之array
  6. 比尔盖茨 27 年婚姻破裂,8000 亿财产咋分配?
  7. 关于滚动相关的属性【转】
  8. go语言中输入的方式,获取用户的输入信息
  9. 查看oracle空间使用情况,Oracle 查看数据库空间使用情况
  10. ubuntu14.04安装skype4.3
  11. STM32实现薄膜压力传感器数据采集(标准库和HAL库实现)
  12. html5css重复径向渐变,CSS3怎么实现重复径向渐变效果
  13. android属性动画作用范围,Android属性动画的使用(上)
  14. Uboot pmic调试
  15. IceSword1.22冰刃驱动枚举网络端口逆向分析
  16. Linux用户管理安全宝典:密码防破解与帐号文件保护
  17. C++ 并发指南<future>(2)std::packaged_task
  18. HTML+CSS 基础 之页签
  19. mesos papers
  20. 58 mysql 军规_58到家MySQL军规升级版(转)

热门文章

  1. 10大Web漏洞扫描工具
  2. 买手机,三星E598
  3. #乐#苏东坡说的人生赏心十六件乐事
  4. 电视盒子与机顶盒哪个好?当贝MAX 1才是最值得买的电视盒子
  5. OpenCV类VideoCapture构造函数中参数apiPreference的可选值及意义
  6. Leetcode 1522. Diameter of N-Ary Tree [Python]
  7. bootstrap之navbar样式
  8. 基于浏览器的在线代码编辑器
  9. 澎湃S2始终不见踪影,小米自主芯片之路已经凉凉?
  10. 计算机毕业设计JAVA病房管理系统mybatis+源码+调试部署+系统+数据库+lw