
你改完一行代码,打开FTP,找到文件,上传,覆盖。一天重复几十次。改错了一个字母,再重复一次。
有没有想过:能不能我本地一提交,服务器就自动更新?
能。而且比你想象的简单。今天教你用Git钩子,搭一个自动部署流程。
先看一个数据
某开发者调研显示,一个程序员平均每天花15-30分钟在“部署”这件事上。手动上传文件、登录服务器重启服务、确认更新成功。
一年下来,将近100个小时。够你学一门新技术,或者读完十几本书。
自动部署就是把这100个小时还给你。
自动部署的原理
你本地有个Git仓库。服务器上也有一个Git仓库(裸仓库)。你本地git push到服务器,服务器上的Git钩子自动执行一段脚本,把代码复制到网站目录。
就这么简单。
流程图:
text
本地电脑(git push)→ 服务器裸仓库(接收代码)→ Git钩子触发 → 代码复制到网站目录 → 网站更新
反常识点:自动部署不需要Jenkins、不需要GitHub Actions、不需要任何第三方服务。Git本身就带这个功能。你可能每天都在用Git,但不知道它有这个能力。
准备工作
第一步:服务器安装Git
bash
apt install git -y # Ubuntu/Debian yum install git -y # CentOS
第二步:服务器创建裸仓库
裸仓库没有工作目录,只存Git数据,专门用来接收推送。
bash
mkdir -p /home/git/site.git cd /home/git/site.git git init --bare
--bare就是创建裸仓库。
第三步:配置SSH免密登录
如果你还没配过SSH密钥,参考之前的文章《告别密码登录:SSH密钥配置实战》。
确保你能从本地免密登录服务器:
bash
ssh root@你的服务器IP
不需要输密码,就对了。
核心步骤:配置Git钩子
钩子(hook)是Git的“触发器”。特定事件发生时,Git会自动执行钩子脚本。
我们用的是post-receive钩子——当服务器收到git push后,自动执行。
第一步:创建钩子脚本
bash
cd /home/git/site.git/hooks vim post-receive
第二步:写入脚本内容
bash
#!/bin/bash # 网站目录(改成你的) TARGET_DIR="/var/www/html" # 设置Git的一些环境变量 export GIT_WORK_TREE=$TARGET_DIR # 检出代码 git checkout -f echo "部署完成:$(date)"
解释:
TARGET_DIR是你的网站目录,比如Nginx的/var/www/htmlgit checkout -f强制检出最新代码到工作目录
第三步:给脚本执行权限
bash
chmod +x post-receive
第四步:确保网站目录存在
bash
mkdir -p /var/www/html
本地配置
第一步:添加远程仓库
在你的本地项目目录里:
bash
git remote add prod ssh://root@你的服务器IP/home/git/site.git
第二步:推送代码
bash
git push prod main
(如果你的默认分支是master,改成master)
第一次推送,服务器会收到代码,钩子自动执行,代码被复制到/var/www/html。
打开浏览器访问你的网站,应该能看到更新后的内容。
效果演示
以后你每次改代码:
bash
git add . git commit -m "修复了一个bug" git push prod main
等几秒钟,刷新网站,新代码已经上线了。
再也不用手动上传了。
进阶:支持多分支、多环境
如果你有开发环境、测试环境、生产环境,可以让不同分支部署到不同目录。
修改钩子脚本:
bash
#!/bin/bash
# 获取当前分支
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
case "$branch" in
"main")
TARGET_DIR="/var/www/prod"
;;
"dev")
TARGET_DIR="/var/www/dev"
;;
*)
echo "未知分支: $branch"
exit 1
;;
esac
export GIT_WORK_TREE=$TARGET_DIR
git checkout -f
echo "部署 $branch 到 $TARGET_DIR 完成"
这样:
git push prod main→ 部署到生产环境git push prod dev→ 部署到开发环境
常见问题
Q:推送后网站没更新?
A:检查钩子脚本有没有执行权限(chmod +x),检查网站目录权限(Web用户要能写入),检查Nginx配置的根目录对不对。
Q:权限问题,无法写入网站目录?
A:把网站目录的所有权给Web用户:
bash
chown -R www-data:www-data /var/www/html
Q:不想用root用户推送?
A:创建一个专用用户git,把网站目录权限给这个用户。
Q:推送时报“remote: Permission denied”?
A:检查SSH密钥有没有配好,以及服务器上/home/git/site.git目录的权限。
一个真实案例
有个朋友做外包开发,每天要更新好几个客户的网站。以前他都是:改完代码,打开FileZilla,找到对应客户的文件夹,上传覆盖。
后来我帮他配了自动部署。每个客户一个裸仓库,本地配置不同的remote。改完代码,git push client1,客户1的网站自动更新。
他说:“以前一天花1小时部署,现在10秒钟。省下的时间,多接了两个项目。”
最后一句
自动部署不是大公司的专利。Git本身就带这个能力,你只是不知道。
花20分钟配好,以后每次git push,网站自动更新。不用打开FTP,不用找文件,不用担心传错目录。
今天就去配。你值得每天多喝一杯咖啡的时间。




