轻量级 CI/CD:Git Hooks 自动部署 Node.js 应用(CICD-demo)

从零实现一个轻量级 CI/CD:Git Hooks 自动部署 Node.js 应用(含 Nginx + systemd 生产级配置)

作者:粟本偲
项目地址:https://gitcode.com/SUBENCAI/myapp-cicd-demo
适用场景:CentOS 7 / Node.js / 运维开发学习 /

本文记录了我如何仅用 Shell 脚本 + Git Hooks 实现一套轻量级 CI/CD 系统,并完成 Node.js 应用的 生产级部署(Nginx 反向代理 + systemd 托管)。全程无需 Jenkins/GitLab CI,适合学习原理与面试展示。

一、为什么不用 Jenkins?—— 我们要理解 CI/CD 的本质

  • CI/CD 的核心是:代码变更 → 自动构建 → 自动部署
  • 大多数人只会点图形界面,但不知道背后是 Shell 脚本在执行
  • 本文通过 post-receive 钩子,亲手实现这一流程

二、环境准备

  • 操作系统:CentOS 7(阿里云 ECS)
  • 已安装软件:Git、Nginx、Node.js(通过 EPEL + 阿里源)
  • 用户权限:root 或 sudo 权限
node -v  # ≥ v14
nginx -v
git --version

三、创建裸仓库(Bare Repository)

  • 在服务器创建 /var/git/myapp.git
  • 初始化为 bare 仓库:git init --bare
  • 设置目录权限,确保部署用户可写
在服务器上创建接收推送的裸仓库:
mkdir -p /var/repo/myapp.git
cd /var/repo/myapp.git
git init --bare

[root@python myapp]# mkdir -p /var/repo/myapp.git
[root@python myapp]# cd /var/repo/myapp.git
[root@python myapp.git]# git init --bare
初始化空的 Git 版本库于 /var/repo/myapp.git/


四、编写 post-receive 钩子脚本

  • 路径:/var/git/myapp.git/hooks/post-receive
  • 功能:
    • 拉取最新代码到 /var/www/myapp/releases/v{timestamp}
    • 创建软链接 /var/www/myapp/current 指向最新版本
    • 自动清理超过 3 个历史版本
    • 重启 systemd 服务
  • 关键技巧:使用 flock 避免并发冲突
#!/bin/bash
GIT_WORK_TREE=/root/myapp git --git-dir=/var/repo/myapp.git checkout -f
systemctl restart myapp
echo "$(date): Deployed" >> /var/log/myapp-deploy.log

五、Node.js 应用示例(app.js)

  • 简单 HTTP 服务,返回 “Hello from CI/CD!”
  • 包含 package.json(定义 start 脚本)
  • 日志输出到 stdout(便于 systemd 收集)
const http = require('http');
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello from CI/CD!\n');
});
server.listen(3000, '0.0.0.0', () => {
  console.log('Server running at http://0.0.0.0:3000/');
});

六、配置 systemd 托管服务

  • 创建 /etc/systemd/system/myapp.service
  • 设置 User、WorkingDirectory、ExecStart
  • 启用开机自启:systemctl enable myapp
  • 查看日志:journalctl -u myapp -f
/etc/systemd/system/myapp.service
[Unit]
Description=MyApp Node.js Service
After=network.target

[Service]
ExecStart=/usr/bin/node /root/myapp/app.js
WorkingDirectory=/root/myapp
Restart=always
User=root
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target





启用服务:
systemctl daemon-reload
systemctl start myapp
systemctl enable myapp

七、Nginx 反向代理配置

  • 配置文件:/etc/nginx/conf.d/myapp.conf
  • 将 80 端口请求代理到 http://127.0.0.1:3000
  • 添加健康检查路径 /healthz
  • 重载 Nginx:nginx -s reload
/etc/nginx/conf.d/myapp.conf

server {
    listen 80;
    server_name _;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

八、本地开发与推送测试

  • 本地添加远程仓库:git remote add prod root@server:/var/git/myapp.git
  • 推送触发部署:git push prod main
  • 验证:curl http://192.168.126.50
# 初始化本地仓库
git init
git add .
git commit -m "First deploy"

# 添加远程仓库
git remote add prod root@192.168.126.50:/var/repo/myapp.git

# 推送触发自动部署
git push prod master

九、效果展示与性能对比

  • 部署耗时:<5 秒
  • 回滚操作:手动切换软链接即可
  • 对比 Jenkins:资源占用更低,逻辑透明可控

十、总结与延伸思考

优势
轻量:仅依赖系统自带工具
可控:无隐藏逻辑,适合调试
教学友好:清晰展示 CI/CD 本质

不足
无 Web UI
无并行流水线
无权限管理

下一步优化方向
增加版本回滚(软链接切换)
集成健康检查(/healthz)
添加邮件/企业微信告警
使用非 root 用户部署(安全加固)

💡 项目已开源,欢迎 Star:https://gitcode.com/SUBENCAI/myapp-cicd-demo
技术栈:Shell / Git / Node.js / Nginx / systemd / CentOS

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值