首先声明一下,我们公司的开发流程比较严(fan)谨(suo),真实环境并没有像本文这样自动部署的做法。
我们要达到的效果是:我们本地开发好的代码,推送到服务器后,服务器自动部署最新版本的代码。
这里介绍两种方式:
- 裸仓库方式
- 非裸仓库方式
裸仓库方式
这也是比较推荐的方式,不太有副作用,尤其需要多人共享时。
那什么是裸仓库呢?
就是没有工作目录的仓库, 不能执行有关git的任何命令,只记录历史提交信息,只能通过clone它的仓库对它进行push操作对它进行更新。裸仓库一般用来做多人代码交换的中转站,它只有这么些目录:branches config description HEAD hooks info objects refs
接下来,仅以一个简单的node服务为例,演示整个过程。
ps: 本地和服务器都要安装git和node,否则没法玩~
1.本地创建仓库并开发
终端cd到你喜欢的一个新目录(这里以githook-test为例),然后:
创建index.js,使用你喜欢的编辑器,输入以下代码(摘自node官网,改了下host):
本地跑一下试试看:
然后用浏览器访问http://locaohost:3000/
,看到了Hello World
。
嗯,很好。
提交代码:
2.创建远程裸仓库
ssh登陆到服务器,cd到你喜欢的目录(比如~/git_projects
),创建一个新仓库目录:
裸仓库一般都命名为xxx.git,然后初始化git:
注意,这里的bare参数很重要,就是创建裸仓库的意思
3.推送代码到服务器
配置本地仓库的remote,比如你的服务器host为vps.xx.com,登陆用户为git,刚刚创建的远程仓库路径为~/git_projects/githook-test.git,那么就在本地仓库执行:
最好配置服务器免密登陆,把你的公钥塞到服务器的~/.ssh/authorized_keys文件中即可。
第一次推送:
如果提示信息的最后两行是:
就说明推送成功了。
4.创建远程非裸仓库
由于裸仓库没有工作目录,没法执行真正的代码,所以需要另一个目录(非裸仓库)拉取实际代码,通过clone的方式拉取即可,cd到你喜欢的目录,比如~/www
,执行:
5.在服务器上启动服务
由于服务器的服务进程需要在后台执行,我们借助pm2这个神器帮我们管理node服务.首先全局安装pm2:
然后cd到真正运行服务的仓库:
启动服务:
name参数用来给当前的服务起一个名字标识,用于后续给指定的服务执行操作,比如重启,停止等.
打开浏览器,访问这个服务,比如,你的服务器host是vps.xx.com,那么就访问http://vps.xx.com:3000
.
如果也看到了Hello World
,就说明服务器上的服务已经跑起来了~
6.配置git钩子
这里才是重点~
git钩子可以理解为一个触发器,当仓库发生指定事件,可以触发执行指定的shell脚本。我们这里需要的是post-receive钩子。
在服务器的仓库中创建钩子文件:
粘贴如下脚本:
保存并退出
其中,unset GIT_DIR
是必须的,和Makefile一样,在每一行,目录都是固定的,需要解除环境变量GIT_DIR环境变量才能自由移动当前位置,这东西坑了我好一会儿~
感谢https://argcv.com/articles/2078.c 这篇文章~
现在这个钩子只是个普通文件,需要给它加上可执行权限:
7.测试自动部署
修改本地的index.js,比如把res.end('Hello World\n');
这句改成res.end('Hello World. I Love Git!\n');
然后提交,并推送:
你会在本地终端看到类似如下的信息:
然后,再次打开浏览器访问服务器上的服务,如果能看到Hello World. I Love Git!
说明自动部署已经成功了!
非裸仓库方式
这种方式,不需要创建裸仓库,只需创建非裸仓库,感觉会节省点磁盘空间~
具体操与裸仓库方式大体一致:
裸仓库方式中的 2.创建远程裸仓库
步骤,更改为:
由于默认情况下,git不允许push代码到非裸仓库,我们需要对这个非裸仓库进行一些设置:
3.推送代码到服务器
步骤中,由于不存在裸仓库了,我们直接push代码到非裸仓库,我们本地仓库的远程仓库地址也要修改一下:
如果远程仓库不执行git config receive.denyCurrentBranch ignore
的话,直接推送会看到如下错误信息:
跳过4.创建远程非裸仓库
步骤.
即使可以向远程非裸仓库push,远程仓库的工作目录也不会随之改变,需要通过钩子,将工作目录更新,所以6.配置git钩子
步骤中,钩子的脚本也要改一下:
再次测试,发现也可以自动部署啦!
从git的默认行为来看,非裸仓库的方式,并不推荐,尤其是生产环境,一定要慎用。
在一些不重要的小应用里使用还是不错的~