Ubuntu Node.js项目持续集成与持续部署(CI/CD)实践指南
在开始配置前,需完成以下基础环境准备:
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt install -y nodejs
sudo npm install -g pm2
package.json(定义依赖与脚本)、ecosystem.config.js(PM2配置文件,可选)等必要文件。持续集成的核心是通过自动化流程验证代码的正确性,避免“集成地狱”。以GitHub Actions(与GitHub深度集成、开箱即用)为例,配置步骤如下:
在项目根目录下创建.github/workflows/ci.yml文件,定义CI流程。以下是一个基础配置示例:
name: Node.js CI
on:
push: # 当代码推送到以下分支时触发
branches: [ main, dev ]
pull_request: # 当提交Pull Request到以下分支时触发
branches: [ main, dev ]
jobs:
build-and-test:
runs-on: ubuntu-latest # 使用Ubuntu环境运行
strategy:
matrix:
node-version: [16.x] # 指定Node.js版本(可扩展为多个版本测试兼容性)
steps:
- name: Checkout code # 拉取代码
uses: actions/checkout@v3
- name: Set up Node.js # 安装指定版本的Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Cache node_modules # 缓存node_modules,加速后续构建
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies # 安装依赖(使用--prefer-offline优先使用缓存)
run: npm ci --prefer-offline
- name: Run tests # 执行测试(需项目已配置测试框架,如Jest、Mocha)
run: npm test
关键说明:
on字段定义了触发条件(代码推送或Pull Request);jobs.build-and-test包含构建与测试的具体步骤;actions/cache用于缓存依赖,减少重复下载时间(提升CI效率)。持续部署是CI的延伸,将通过测试的代码自动发布到生产环境。以下是两种常见方案的配置:
通过SSH连接到Ubuntu服务器,拉取最新代码并使用PM2重启应用,实现自动化部署。
ssh-keygen -t rsa -b 4096 -C "github_actions"
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 将公钥添加到authorized_keys
chmod 600 ~/.ssh/authorized_keys # 设置权限(防止权限过高导致连接失败)
cat ~/.ssh/id_rsa.pub)到GitHub仓库的Settings → Secrets → Actions中,命名为SSH_PRIVATE_KEY;SERVER_IP:服务器公网IP;DEPLOY_PATH:项目部署路径(如/var/www/node-app)。在.github/workflows/deploy.yml中添加部署流程:
name: Node.js CD
on:
push:
branches: [ main ] # 仅main分支触发部署(避免dev分支误触发)
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # 关联production环境(需在GitHub仓库中创建)
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: SSH Deploy # 使用appleboy/ssh-action插件执行远程命令
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_IP }}
username: root # 服务器用户名(如ubuntu、root)
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd ${{ secrets.DEPLOY_PATH }} # 进入部署目录
git pull origin main # 拉取最新代码
npm install --production # 安装生产依赖(忽略devDependencies)
pm2 reload ecosystem.config.js --env production # 重启PM2进程(加载新代码)
pm2 save # 保存当前进程列表(防止重启后丢失)
关键说明:
appleboy/ssh-action是GitHub Actions的SSH插件,用于执行远程命令;pm2 reload实现零停机重启(保持应用可用性);environment: production关联环境,便于后续权限管理与审计。通过Docker将应用打包为镜像,推送到Docker Hub或私有仓库,再部署到服务器(需服务器安装Docker)。
在项目根目录下创建Dockerfile:
FROM node:16-alpine # 使用轻量级Node.js镜像
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production # 仅安装生产依赖
COPY . .
EXPOSE 3000 # 暴露应用端口
CMD ["node", "app.js"] # 启动应用(根据实际入口文件调整)
在.github/workflows/ci-cd.yml中添加构建与推送步骤:
name: Node.js CI/CD with Docker
on:
push:
branches: [ main ]
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Build Docker image # 构建Docker镜像
run: docker build -t your-dockerhub-username/node-app:${{ github.sha }} .
- name: Login to Docker Hub # 登录Docker Hub(需配置secrets)
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push Docker image # 推送镜像到Docker Hub
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: your-dockerhub-username/node-app:${{ github.sha }}
deploy:
needs: build-and-push # 依赖构建步骤完成
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: SSH Deploy Docker # 使用SSH执行远程Docker命令
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_IP }}
username: root
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
docker pull your-dockerhub-username/node-app:${{ github.sha }} # 拉取最新镜像
docker stop node-app || true # 停止旧容器(若存在)
docker rm node-app || true
docker run -d --name node-app -p 3000:3000 your-dockerhub-username/node-app:${{ github.sha }} # 启动新容器
关键说明:
Dockerfile定义了应用的运行环境,确保开发与生产环境一致;docker/login-action用于登录Docker Hub(需在GitHub Secrets中配置DOCKER_USERNAME和DOCKER_PASSWORD);sudo apt install -y docker.io)。actions/cache,缓存node_modules和npm缓存,减少构建时间(提升30%-50%);environment字段区分开发、测试、生产环境,便于审计与权限控制;pm2 reload或Docker滚动更新,确保应用持续可用;pm2 monit(实时监控)、pm2 logs(查看日志)或第三方工具(如Prometheus+Grafana),及时发现并解决问题。通过以上配置,Ubuntu Node.js项目可实现从代码提交到测试、构建、部署的全自动化流程,提升开发效率与应用可靠性。