这事断断续续折腾我大概两周时间,这就把我经历的事分享给大家。
为了实现在本地提交这个blog项目能不用手动到线上更新而努力着,刚开始在找解决办法时以为就那么简单,结果却折腾在docker、linux权限和如何写shell的几个关键知识里面。
流程
这里先简单介绍一下部署流程:
1 | 本地--[推送代码]-->git服务器--[触发]-->`post-receive`钩子--[拉取代码]-->部署目录 |
目前情况
以下是我目前的情况:
- git服务和网站服务在同一个服务器上
- 项目不存在构建,只把生成的内容放到固定分支
- git服务用的是gogs
- 用ssh方式拉取代码
处理办法
好了,具体怎么做?
- 进入gogs打开你的[仓库设置]->[管理Git钩子]
- 编辑
post-receive
然后把下面代码添加进去:
1 |
|
接下来得说说关键部分的部署代码,根据我目前的情况,在部署代码之前需要做两件事情:
移除GIT_DIR
环境变量
这里由于GIT_DIR
默认为’.’,会导致访问地址不对并给出下面提示:
“fatal: Not a git repository: ‘.’”
处理办法:
1 | unset GIT_DIR |
生成密钥
为满足使用ssh方式拉取代码就会需要密钥,我gogs是跑在docker容器下,第一步先进入容器然后生成密钥:
1 | ssh-keygen -t rsa -C "your name or email" |
如何生成密钥这里就不详细说明,各位到网上自查攻略吧!
再来到gogs的[仓库设置]->[管理部署密钥]->[添加部署密钥]把公钥添加进去就能用了。
自定义ssh请求
为满足ssh指定加载特定密钥,需要在git执行前自定义ssh的操作:
1 | GIT_SSH_COMMAND="ssh -i /git/.ssh/id_rsa" git fetch |
GIT_SSH_COMMAND
只适用于 git version 大于 2.6 的版本
执行后会出现一堆提示而且不会执行git的具体操作:
1 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
发送ssh请求会询问是否把相关信息记录至known_hosts
,但是由于是脚本处理所以并没得到处理,最后会给出上面的提示。
解决办法有三种:
- 删除提示信息中,对应的行数,例如上例,需要删除/git/.ssh/known_hosts文件的第7行。
- 删除整份/git/.ssh/known_hosts文件。
上面两种并不能从根本解决问题,这里推荐在ssh命令后添加下面两个参数的第三种解决办法:
-o StrictHostKeyChecking=no
不检查公钥-o UserKnownHostsFile=/dev/null
不更新known_hosts
1 | GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /git/.ssh/id_rsa" git fetch |
写成这样就能带上给定的ssh密钥,到这里基本把需要解决的问题都解决了,下面给上完整代码:
1 |
|
这里说几点需要注意的:
- 外部部署环境的目录权限尽量和容器里面生成目录的权限保持一致(能解决大部分的权限问题)
- 搞清楚shell当前的权限所属再写shell(少走弯路,特别是你不太清醒的时候)
- 应用只全局的变量一定要
export
,export
,export
(重要的事情说三次,这个害我花了不少时间)
如果你的环境没那么复杂是真的不用考虑那么多,自己撸起可能会比我少走很多弯路,希望大家处理权限的时候记住:linux权限规则还是linux的权限规则,不要给docker给迷惑了!