🚀 Jenkins 自动部署 Node.js 项目操作文档

📁 项目名称

jenkins-api-test

🧰 技术栈

  • Node.js:v24.x(通过 NVM 管理)
  • 包管理器:npm
  • 进程管理器:pm2
  • 自动化工具:Jenkins
  • 测试框架:Jest
  • 远程服务器:10.1.19.208(用户:sh)

🧩 Git项目结构说明

jenkins-api-test/
├── Jenkinsfile              # Jenkins 自动化构建脚本
├── deploy.sh               # 远程部署脚本
├── package.json            # 项目依赖与脚本定义
├── index.js                # 应用入口文件
├── routes/                 # 路由模块
│   └── users.js            # 用户相关接口
├── tests/                  # 单元测试目录
│   └── users.test.js       # 用户接口测试
└── README.md               # 项目说明文档(可选)

🖥️ 远程服务器配置(10.1.19.208)

✅ 1. 创建部署用户

sudo adduser sh
sudo usermod -aG sudo sh

✅ 2. 配置 SSH 公钥登录

将 Jenkins 所用的 SSH 私钥对应的公钥添加到远程服务器:

mkdir -p /home/sh/.ssh
echo "你的公钥内容" >> /home/sh/.ssh/authorized_keys
chmod 700 /home/sh/.ssh
chmod 600 /home/sh/.ssh/authorized_keys
chown -R sh:sh /home/sh/.ssh

✅ 3. 安装 NVM 和 Node.js

# 安装 NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# 加载 NVM
export NVM_DIR="$HOME/.nvm"
source "$NVM_DIR/nvm.sh"

# 安装 Node.js
nvm install 24
nvm alias default 24

✅ 4. 安装 pm2(全局)

npm install -g pm2

✅ 5. 开放访问端口(如 3000)

sudo ufw allow 3000
sudo ufw enable

或使用云服务控制台开放端口。

🧩 Jenkinsfile(完整配置)

pipeline {
    agent any

    tools {
        nodejs 'node24'
    }

    environment {
        REMOTE_USER = 'sh'
        REMOTE_HOST = '10.1.19.208'
        REMOTE_DEPLOY_PATH = '/var/www/jenkins-api-test'
        DEPLOY_SCRIPT_REMOTE = '/tmp/deploy.sh'
    }

    stages {
        stage('拉取代码') {
            steps {
                git credentialsId: 'gitlab-token',
                    url: 'http://10.1.19.207/yj/jenkins-api-test.git',
                    branch: 'main'
            }
        }

        stage('安装依赖') {
            steps {
                sh 'npm install'
            }
        }

        stage('运行测试') {
            steps {
                sh 'npm test'
            }
        }

        stage('部署到远程服务器') {
            steps {
                sshagent(['remote-ssh-key']) {
                    sh '''
                        echo "📤 清理换行符..."
                        sed -i 's/\\r$//' deploy.sh

                        echo "📁 创建远程部署目录..."
                        ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "mkdir -p $REMOTE_DEPLOY_PATH"

                        echo "📦 上传项目文件..."
                        scp -r * $REMOTE_USER@$REMOTE_HOST:$REMOTE_DEPLOY_PATH

                        echo "📤 上传部署脚本..."
                        scp deploy.sh $REMOTE_USER@$REMOTE_HOST:$DEPLOY_SCRIPT_REMOTE

                        echo "🚀 执行远程部署脚本..."
                        ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "bash $DEPLOY_SCRIPT_REMOTE"
                    '''
                }
            }
        }
    }
}

📜 deploy.sh(部署脚本)

#!/bin/bash

set -e

DEPLOY_PATH="/var/www/jenkins-api-test"

echo "🚀 开始部署到远程服务器 $HOSTNAME"

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
nvm use default

command -v pm2 >/dev/null 2>&1 || npm install -g pm2

cd "$DEPLOY_PATH"
npm install
pm2 restart jenkins-api-test || pm2 start index.js --name jenkins-api-test

echo "🎉 部署完成!"

🧠 index.js(应用入口)

const express = require('express');
const app = express();
const usersRouter = require('./routes/users');

app.use(express.json());
app.use('/users', usersRouter);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

📦 routes/users.js(用户接口)

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
  res.json([
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' }
  ]);
});

module.exports = router;

🧪 tests/users.test.js(接口测试)

const request = require('supertest');
const express = require('express');
const usersRouter = require('../routes/users');

const app = express();
app.use('/users', usersRouter);

describe('GET /users', () => {
  it('应返回用户列表', async () => {
    const res = await request(app).get('/users');
    expect(res.statusCode).toBe(200);
    expect(Array.isArray(res.body)).toBe(true);
    expect(res.body.length).toBeGreaterThan(0);
  });
});

🔐 Jenkins 凭证配置

  • 类型:SSH Username with private key
  • 用户名:sh
  • 私钥:连接远程服务器的私钥
  • ID:remote-ssh-key

🌐 访问部署后的应用

默认监听端口为 3000

http://10.1.19.208:3000

🧯 常见问题排查

问题 原因 解决方案
npm install 报错 未上传项目文件 确保 scp -r * 正确执行
pm2 未找到 环境变量未加载 确保 deploy.sh 中加载了 NVM
ssh-agent 找不到凭证 Jenkins 凭证 ID 不匹配 确保 ID 为 remote-ssh-key
无法访问服务 端口未开放或服务未启动 检查防火墙、pm2 状态和监听端口
Copyright © https://yan-jian.com 2023 all right reserved更新时间: 2025-09-29 19:47:21

results matching ""

    No results matching ""