如何在EC2和DigitalOcean服务器实现类似Heroku的git push自动部署功能
核心逻辑是在服务器端创建裸Git仓库,配置post-receive钩子自动执行代码拉取、依赖安装、服务重启操作,完全模拟Heroku的推送部署体验,具体步骤如下:
1. 服务器端初始化裸Git仓库
使用pem文件登录服务器:ssh -i your-key.pem ubuntu@*你的服务器公网IP*
依次执行以下命令创建裸仓库(专门用于接收Git推送,无工作目录):
- 新建仓库存储目录:
sudo mkdir -p /var/repo/blog.git - 初始化裸仓库:
cd /var/repo/blog.git && sudo git init --bare
2. 配置自动部署钩子
post-receive钩子会在仓库收到推送后自动执行,是实现一键部署的核心:
- 进入钩子目录:
cd /var/repo/blog.git/hooks - 新建钩子文件:
sudo nano post-receive - 写入以下脚本,注意替换脚本中标粗的内容为你自己的配置:
#!/bin/bash GIT_DIR=/var/repo/blog.git WORK_TREE=/*你的Express项目部署路径* # 例:/var/www/my-blog # 拉取最新代码到部署目录 git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout -f main # 若你的默认分支是master则替换为master # 进入项目目录执行部署动作 cd $WORK_TREE npm install --production # 安装生产依赖,跳过开发依赖 pm2 restart *你的Express服务进程名* # 例:blog-app,若用其他进程管理工具替换为对应重启命令即可
- 给钩子添加执行权限:
sudo chmod +x post-receive - 确保部署目录权限和你登录服务器的用户一致,避免写入失败:
sudo chown -R ubuntu:ubuntu /*你的Express项目部署路径*
提示:如果还没有安装PM2管理Node进程,可在服务器执行
npm install -g pm2安装,首次启动项目执行pm2 start app.js --name 你的进程名即可,支持开机自启、异常自动重启。
3. 本地Git配置远程仓库
回到本地的Express项目根目录,添加服务器端的Git远程地址:git remote add live ssh://ubuntu@*你的服务器公网IP*/var/repo/blog.git
为了避免每次推送都指定pem文件,可在本地~/.ssh/config文件中添加以下配置:
Host *你的服务器公网IP* IdentityFile /*你的pem文件本地存储路径* User ubuntu
4. 测试部署
本地修改代码提交后,直接执行git push live main(默认分支为master则执行git push live master),即可自动完成全流程部署,体验和Heroku完全一致。
多服务器部署适配
你同时部署了EC2和DigitalOcean两个实例的话,只需要给两个实例都按上述步骤配置,本地分别添加两个远程仓库(比如命名为ec2和do),需要部署到哪个实例就推送到对应远程即可,也可以写本地bash脚本一次性推送两个实例。
内容的提问来源于stack exchange,提问作者sachu

