服务端代码自动部署GIT方式
目录
前言
记得第一次负责服务端开发及部署线上服务器时,对于服务器项目代码的更新很是疑惑,如何增量更新代码成为一个不小的难题,特别是对于花钱买服务的客户来说,他们不容许你在白天出那么一小会的一丁点的问题。
见过项目复杂到配置需要手动配置,导致代码更新需要开发与测试写成更新计划:哪个文件要替换,哪个文件第几行需要换成什么参数如此之类的;
也见过负责更新服务端代码的哥们因为太累看错了参数,参数复制错了服务器;
也见过简单点的部署方式是服务器直接从svn或git上直接拉代码下来,再进行手动修改相关配置等,但这样需要一个公共的svn或git帐号而且需要在服务器上操作更新,对服务端操作不熟练的负责人,使得服务器安全没有足够的保证。
Git客户端推送更新方式
服务器的代码由客户端推送到正式服务器,git服务自动强制更新代码,并由git自带hooks执行相应脚本操作文件增\删\改\链接等配置操作;不需要连接服务器,不需要手动更改代码相关配置,对服务器更安全,操作者更简单便捷。
远程服务端配置
注:以下工作在root下操作:
-
确保安装了git服务:
ubuntu:
> apt-get install git
centos:
> yum install git-core
-
配置部署代码的属组、属主:
> useradd -m user_9
> passwd password_9
-
新建一个目录作为要部署代码的根目录,如:
> mkdir /www/999/
-
授权属主和属组
> chown user_9.user_9 /www/999/
-
切换到部署代码的属主
> su user_9
-
进入项目目录,初始化git仓库
> cd /www/999
> git init
在当前目录下生成文件目录:/www/9ong/.git
-
允许仓库接受提交到主分支
> git config receive.denyCurrentBranch ignore
到这里git仓库就在服务器上创建好了,
仓库的地址为:
ssh://user_9@xx.xx.xx.xx:/www/999/.git
本地客户端检出与推送
命令行方式
-
从项目代码托管的git服务商(比如github)仓库上将代码获取到本地;
> git clone
> git pull origin master
-
将新建的自有远程仓库添加到本地远程仓库列表,使用名字来区分不同的仓库地址,如999-server;
> git remote add 999-server ssh://user_9@xx.xx.xx.xx:/www/999/.git
-
将本地代码提交到自有远程服务器仓库
> git push 999-server master
注:如果不确定分支是否master,一定要写实际要推送的分支名称;
TortoiseGit客户端方式
假设本地客户端已有项目代码。
-
修改代码并commit到本地
-
推送代码到自有远程服务器(不是托管代码的git服务器比如github gitlab等)
-
推送输入自有服务器指定部署属主(如user_9)的密码
-
推送成功,自有远程服务器更新代码
服务端代码更新操作(第一次)
-
进入项目目录:
> cd /www/999
> git update-server-info
> git checkout master
* 如果有分支的注意:git checkout 分支名称
-
设置服务端更新钩子 post-update
> cd .git/hooks
* 目录下的hooks文件默认以sample结尾是不会被执行的,只有去掉sample后才会被git调用;
如新建 post-update 或将 post-update.sample 重命名为 post-update;
写入:
#!/bin/sh
#post-update:git 在push操作后将自动执行checkout检出最新代码
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".
#exec git update-server-info
unset GIT_DIR
cd ..
#pwd >> /tmp/pwd.log
git checkout -f
服务端代码更新(后续)
-
项目托管服务git有更新时,pull 更新本地部署仓库
-
从本地客户端push 到线上服务器进行测试(专门的测试地址或测试服务器)
-
测试通过之后 push 到正式服务器进行正式远程服务器
代码回滚
服务器上回滚
-
通过git log 或git reflog查看要回滚到的版本
> Git log
-
我们尝试回滚到版本
5d92da49449748e83098992a342f35510a47218f
> sudo git reset --hard 5d92da49449748e83098992a342f35510a47218f
结果:HEAD is now at 5d92da4 ssss
-
是否可以再回滚到push时的版本?
通过git reflog 可以看到(git log查看不到删除的commit)
5d92da49449748e83098992a342f35510a47218f
我们回滚最新的代码就是最后一次push的版本78649bd:
> Git reset --hard 78649bd
-
回滚版本后是否可以继续push代码并自动更新?
可以的。
仍然是正常的push到服务器上,并执行hooks。(检出时注意检出的分支)
疑问 & 其他:
-
在push的时候可能会有小伙伴碰到以下的问题:
问题 : git-receive-pack not found
解决:ln -s /usr/local/git/bin/git-receive-pack /usr/bin/git-receive-pack
附:hooks shell 范例
1、 post-checkout:第一次checkout时自动做配置目录或文件的软链接
#!/bin/sh
#post-checkout:第一次checkout时自动做配置目录或文件的软链接
unset GIT_DIR
#cd ..
pwd >>/tmp/pwd.log
config_dir='./config/'
if [ ! -d "$config_dir" ]; then
pwd "$config_dir">> /tmp/config.dir.log
whoami >>/tmp/whoami.log
ln -s ./config_testing ./config
fi
2、push后服务器自动检出最新代码
#!/bin/sh
#post-update:push后服务器自动检出最新代码
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".
#exec git update-server-info
unset GIT_DIR
cd ..
pwd >> /tmp/pwd.log
git checkout -f