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

相关推荐
Drift_Dream1 小时前
Node.js 第3课:Express.js框架入门
node.js
c***69304 小时前
node.js下载、安装、设置国内镜像源(永久)(Windows11)
node.js
全栈前端老曹4 小时前
【包管理】npm init 项目名后底层发生了什么的完整逻辑
前端·javascript·npm·node.js·json·包管理·底层原理
callJJ5 小时前
MCP配置与实战:深入理解现代开发工具链
javascript·node.js·vue·mcp·windsurf
程序员爱钓鱼6 小时前
Node.js 编程实战:测试与调试 —— 日志与监控方案
前端·后端·node.js
番茄灭世神6 小时前
Git入门使用学习
git·gitee·软件工程·计算机专业入门
雪域迷影7 小时前
Node.js中使用node-redis库连接redis服务端并存储数据
数据库·redis·node.js
南_山无梅落7 小时前
团队协作高频Git实用手册(项目实战版)
git·团队开发
fiveym8 小时前
持续交付与持续部署(CD)深度解析:定义差异、流程架构与交付模式对比
运维·ci/cd·架构
oMcLin8 小时前
如何在 CentOS 8 上部署并优化 Jenkins 2.x 流水线,提升 CI/CD 流程的自动化与高效性
ci/cd·centos·jenkins