轻量级 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

相关推荐
孟祥_成都2 小时前
别被营销号误导了!你以为真的 Bun 和 Deno 比 Node.js 快很多吗?
前端·node.js
哟哟耶耶4 小时前
git-git cherry-pick(从分支挑选特定提交-哈希值)更改应用到当前分支
git
无限进步_5 小时前
C语言动态内存管理:掌握malloc、calloc、realloc和free的实战应用
c语言·开发语言·c++·git·算法·github·visual studio
labixiong7 小时前
理解pnpm的本质,如何通过高效管理提升项目效率
前端·javascript·node.js
青靴8 小时前
轻量级 CI/CD 实战(四):本地开发钉钉告警 → 自动部署云服务器 Kafka 消费者容器
ci/cd·docker·钉钉
程序员馨馨10 小时前
git常用命令学习以及冲突解决
git·功能测试·学习
奔跑吧邓邓子10 小时前
Jenkins自动化持续集成:从入门到实战
ci/cd·自动化·实战·jenkins·自动化持续集成
良木林17 小时前
Node.js基础:模块化与包
开发语言·前端·node.js
1***815317 小时前
Git游戏开发案例
git