最近帮忙前端把一个静态的项目(挂在coding.net的仓库里)挂上自己的生产服务器 ,但是由于前端不会使用SSH登录服务器自行pull+checkout,因此我想了几种能让前端接受的方法把这个静态项目自动部署到服务器上。
这种方法比较简单粗暴,用node搭一个简单的服务器监听某一个端口,当前端访问这个端口的时候执行命令行脚本自动更新项目。
分别使用了node的http模块以及child_process模块:
var http = require("http");
var exec = require("child_process").exec;
http.createServer(function(request, response){
exec("cd /path/to/project");
exec("git pull origin branch-name");
exec("git checkout HEAD");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("OK");
response.end();
}).listen(9999);
由于项目存储在coding.net上,如果采取传统的HTTPS认证,则每次认证都需要输入用户名和密码,这样的话以上脚本执行就不成功了。
因此可以选择将服务器的公钥添加到coding.net的项目公钥上,项目公钥只有读的权限,没有写的权限,因此很适合部署在服务器上面。
最后,在git clone的时候如果使用的是HTTPS的clone链接,可以通过以下命令改成使用SSH协议的链接。
git remote set-url [alias] [url]
在这里我不会展开对Git Hook的深入分析,有兴趣的参考Git关于钩子的官方文档 。
钩子分为客户端的钩子以及服务端的钩子,参考Git自定义钩子。
简单的把钩子看成是事件的回调函数,当触发某一个动作(如push,commit)的时候,就会调用这个钩子,这个钩子通常在.git目录下的hooks里,里面提供了各种常用钩子的例子,不过后缀名都是sample,如果你希望使用其中的钩子,则必须去掉sample的后缀名。
值得注意的是,钩子不一定是shell scripts,也可以是Python,只要在第一行注释里面声明清楚就可以。
在简单的了解钩子的作用以后,结合之前的使用场景,实现的目的很明确,前端在提交(push)到远程主机的时候运行git hook里面更新静态项目的脚本,也就是编写push事情触发时的钩子。
git的仓库是分为正常的仓库和裸(bare)仓库的,正常的仓库里面你可以进行任何正常的git操作,但在bare仓库里面不能进行类似git add以及git commit这样的操作,因为bare仓库是没有work-tree的。
说到这里,大概也明白了bare仓库其实就是类似于远程主机上的公共代码库(git对bare仓库默认的后缀名为.git),git clone这个公共代码库的链接就能得到一个正常的仓库。
这是从github上拿到的jquery的链接:
https://github.com/jquery/jquery.git
也就是说,在github的服务器上面放着这样一个jquery的bare仓库。
以下是参考的stack overflow链接:
What is the difference between “git init” and “git init –bare”?
How do you use “git –bare init” repository?
cd ~
git init --bare project.git
因此,如果通过SSH访问我们服务器的git仓库,那么链接就是:
ssh://user@domian:/root/project.git
git remote add server ssh://user@domian:/root/project.git
git push server branch-name
如果使用了git remote -v命令查看所有的主机,会发现同一个远程主机有两条链接,分别是用于fetch和push的两条链接,这是为了读和写都能够使用不同的协议。
git clone /root/project.git
#!/bin/sh
unset GIT_DIR
echo "远程更新"
DeployPath='/root/project'
cd ${DeployPath}
git pull origin branch-name
git checkout HEAD
值得注意的是,你还要更改post-receive权限,因为你当前用户可能没有执行权限。
chmod 755 ./post-receive
OK,此时只要在本地的开发机里面推送到server这台远程主机就能自动更新外界访问的静态项目了。
当然,以上所有操作的顺利进行都是基于本地的开发机的公钥已经放在服务器上面了。
在coding中开启项目Pages的服务,部署上去以后,当请求自己的服务器的时候proxy_pass到对应的coding的url。
server {
resolver 8.8.8.8;
listen 80 default_server;
server_name _;
index index.html;
location / {
proxy_pass http://{user_name}.coding.me/{project_name}$request_uri;
}
}