内容简介:这事断断续续折腾我大概两周时间,这就把我经历的事分享给大家。为了实现在本地提交这个blog项目能不用手动到线上更新而努力着,刚开始在找解决办法时以为就那么简单,结果却折腾在docker、linux权限和如何写shell的几个关键知识里面。这里先简单介绍一下部署流程:
这事断断续续折腾我大概两周时间,这就把我经历的事分享给大家。
为了实现在本地提交这个blog项目能不用手动到线上更新而努力着,刚开始在找解决办法时以为就那么简单,结果却折腾在 docker 、 linux 权限和如何写 shell 的几个关键知识里面。
流程
这里先简单介绍一下部署流程:
本地--[推送代码]-->git服务器--[触发]-->`post-receive`钩子--[拉取代码]-->部署目录
目前情况
以下是我目前的情况:
- git服务和网站服务在同一个服务器上
- 项目不存在构建,只把生成的内容放到固定分支
- git服务用的是gogs
- 用ssh方式拉取代码
处理办法
好了,具体怎么做?
post-receive
然后把下面代码添加进去:
#!/bin/bash while read oldrev newrev refname do branch=$(git rev-parse --symbolic --abbrev-ref $refname) if [ "gh-pages" == "$branch" ]; then # 在这添加你需要做的部署行为 fi done
接下来得说说关键部分的部署代码,根据我目前的情况,在部署代码之前需要做两件事情:
移除 GIT_DIR
环境变量
这里由于 GIT_DIR
默认为’.’,会导致访问地址不对并给出下面提示:
“fatal: Not a git repository: ‘.’”
处理办法:
unset GIT_DIR
生成密钥
为满足使用ssh方式拉取代码就会需要密钥,我gogs是跑在docker容器下,第一步先进入容器然后生成密钥:
ssh-keygen -t rsa -C "your name or email"
如何生成密钥这里就不详细说明,各位到网上自查攻略吧!
再来到gogs的[仓库设置]->[管理部署密钥]->[添加部署密钥]把公钥添加进去就能用了。
自定义ssh请求
为满足ssh指定加载特定密钥,需要在git执行前自定义ssh的操作:
GIT_SSH_COMMAND="ssh -i /git/.ssh/id_rsa" git fetch
GIT_SSH_COMMAND
只适用于 git version 大于 2.6 的版本
执行后会出现一堆提示而且不会执行git的具体操作:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that the RSA host key has just been changed. The fingerprint for the RSA key sent by the remote host is 50:e6:cb:58:bc:b7:a3:f6:e8:8f:46:a7:c1:5f:c2:df. Please contact your system administrator. Add correct host key in /git/.ssh/known_hosts to get rid of this message. Offending key in /git/.ssh/known_hosts:7 RSA host key for 192.168.0.4 has changed and you have requested strict checking. Host key verification failed.
发送ssh请求会询问是否把相关信息记录至 known_hosts
,但是由于是脚本处理所以并没得到处理,最后会给出上面的提示。
解决办法有三种:
- 删除提示信息中,对应的行数,例如上例,需要删除/git/.ssh/known_hosts文件的第7行。
- 删除整份/git/.ssh/known_hosts文件。
上面两种并不能从根本解决问题,这里推荐在ssh命令后添加下面两个参数的第三种解决办法:
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /git/.ssh/id_rsa" git fetch
写成这样就能带上给定的ssh密钥,到这里基本把需要解决的问题都解决了,下面给上完整代码:
#!/bin/bash while read oldrev newrev refname do branch=$(git rev-parse --symbolic --abbrev-ref $refname) if [ "gh-pages" == "$branch" ]; then printf "branch:$branch\n" PROJECT_ROOT=/www PROJECT_PATH="$PROJECT_ROOT/[目录地址]" REPO_PATH="[git地址]" REPO_BRANCH="$branch" # GIT_DIR默认为'.',会导致访问地址不对,故需要移除GIT_DIR环境变量 # > https://alfred-long.iteye.com/blog/1836347 unset GIT_DIR # `-o StrictHostKeyChecking=no` 不检查公钥 # `-o UserKnownHostsFile=/dev/null` 不更新known_hosts # `-i /git/.ssh/uxfeel` 指定密钥 # > https://www.cnblogs.com/zhengah/p/4959682.html GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /git/.ssh/uxfeel" export GIT_SSH_COMMAND if [ ! -d "$PROJECT_PATH" ]; then printf "git clone -b$REPO_BRANCH$REPO_PATH\n" cd "$PROJECT_ROOT" git clone -b "$REPO_BRANCH" "$REPO_PATH" printf "git clone finish.\n\n" else cd "$PROJECT_PATH" printf "git fetch \n" git fetch printf "git fetch finish.\n\n" printf "git pull \n" git pull printf "git pull finish." fi fi done
这里说几点需要注意的:
- 外部部署环境的目录权限尽量和容器里面生成目录的权限保持一致(能解决大部分的权限问题)
- 搞清楚shell当前的权限所属再写shell(少走弯路,特别是你不太清醒的时候)
-
应用只全局的变量一定要
export
,export
,export
(重要的事情说三次,这个害我花了不少时间)
如果你的环境没那么复杂是真的不用考虑那么多,自己撸起可能会比我少走很多弯路,希望大家处理权限的时候记住:linux权限规则还是linux的权限规则,不要给docker给迷惑了!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- redission-tomcat 快速实现从单机部署到多机部署
- 手摸手,带你实现代码自动部署
- php + Laravel 实现部署自动化
- iOS如何实现API环境自动部署
- 部署Apache网站服务以及访问控制的实现
- 企业私有npm部署和实现npm发布
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。