Skip to content

@ruoyi-office-doc 这是一个vitepress前端项目,我需要通过jenkins服务部署,将其到另一台服务器上。 1、jenkins服务是140 2、nginx服务器是127.0.0.1 3、当前项目git地址是,git@codeup.aliyun.com:676b69e335730943ed494c52/ruoyi-office/ruoyi-office-doc.gitjenkins服务器已经可以拉取 4、140服务器jenkins部署命令:docker run --restart always --network jenkins --name jenkins -d -p 8080:8080 -p 50000:50000 -v /opt/jenkins_home:/var/jenkins_home jenkins/jenkins 5、nginx服务器nginx部署命令: docker run -d --name nginx -p 80:80 -p 443:443 --restart=always -v /data/nginx/conf/nginx.conf:/ etc/nginx/nginx.conf -v /data/nginx/conf/conf.d:/etc/nginx/conf.d -v /data/nginx/html:/usr/share/nginx/html -v /data/nginx/ logs:/var/log/nginx nginx:latest

VitePress文档站点Jenkins自动化部署指南 ​

部署架构 ​

Jenkins服务器(140)                    Nginx服务器(127.0.0.1)
┌─────────────────┐                  ┌──────────────────────┐
│  Jenkins容器     │                  │  Nginx容器            │
│  - 拉取代码      │  SSH/rsync       │  - 静态文件服务       │
│  - 构建VitePress │ ───────────────> │  - /data/nginx/html/  │
│  - 部署文件      │                  │    ruoyi-office-doc/  │
└─────────────────┘                  └──────────────────────┘

前置条件 ​

  • Jenkins服务器(140)已部署并运行
  • Nginx服务器(127.0.0.1)已部署并运行
  • Jenkins服务器可以访问Git仓库
  • 两台服务器之间网络互通

部署步骤 ​

步骤1: 配置SSH免密登录 ​

在Jenkins服务器(140)上执行:

bash
# 方式1: 使用提供的脚本(推荐)
chmod +x setup-ssh.sh
./setup-ssh.sh

# 方式2: 手动执行
ssh-keygen -t rsa -b 4096 -C "jenkins@140" -f ~/.ssh/jenkins_rsa
ssh-copy-id -i ~/.ssh/jenkins_rsa.pub root@127.0.0.1
ssh -i ~/.ssh/jenkins_rsa root@127.0.0.1 "echo 'SSH连接成功!'"

说明: ssh-copy-id 命令会将公钥内容追加到Nginx服务器(127.0.0.1)的 /root/.ssh/authorized_keys 文件中。如果该文件不存在,命令会自动创建 ~/.ssh 目录和 authorized_keys 文件。

注意: 如果Jenkins运行在Docker容器中,需要在容器内执行,或者将密钥挂载到容器中。

从Jenkins容器获取私钥:

如果SSH密钥在Jenkins容器内,可以使用以下方法获取:

方法1: 从容器内直接获取(如果密钥在容器内)

bash
# 进入容器查看
docker exec jenkins cat ~/.ssh/jenkins_rsa | grep -v '^$'

# 或者查找密钥位置
docker exec jenkins find ~ -name "jenkins_rsa"

方法2: 从宿主机挂载目录获取(推荐)

bash
# Jenkins容器挂载了 /opt/jenkins_home:/var/jenkins_home
# 在宿主机上查找
find /opt/jenkins_home -name "jenkins_rsa"

# 如果找到,直接查看(过滤空行)
cat /opt/jenkins_home/.ssh/jenkins_rsa | grep -v '^$'

方法3: 使用提供的脚本(最简单)

bash
# 在Jenkins服务器上执行
chmod +x get-jenkins-ssh-key.sh
./get-jenkins-ssh-key.sh

脚本会自动查找密钥位置并显示正确格式的私钥内容。

步骤2: 配置Jenkins SSH凭据 ​

  1. 登录Jenkins Web界面(http://140:8080)
  2. 进入 Jenkins管理 -> 凭据管理 -> 系统 -> 全局凭据 -> 添加凭据
  3. 配置如下:
    • 类型: SSH Username with private key
    • ID: prod-ssh(必须与Jenkinsfile中的SSH_CRED一致)
    • 描述: Nginx服务器SSH凭据
    • 用户名: root
    • 私钥: 选择 Enter directly,粘贴 ~/.ssh/jenkins_rsa 文件的内容
      • 重要: 确保私钥内容完整且格式正确:
        • 第一行:-----BEGIN RSA PRIVATE KEY----- 或 -----BEGIN OPENSSH PRIVATE KEY-----
        • 中间:密钥内容(多行连续的base64编码,每行之间不能有空行或空格)
        • 最后一行:-----END RSA PRIVATE KEY----- 或 -----END OPENSSH PRIVATE KEY-----
      • 关键要求:
        • ❌ 不要在行之间添加空行或空格
        • ❌ 不要包含额外的注释或说明文字
        • ✅ 每行应该紧密相连,没有空行
        • ✅ 首尾标记行必须完整
      • 正确示例:
        -----BEGIN OPENSSH PRIVATE KEY-----
        b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcnNh
        AAAwEAAQAAAgEA76sBh9hA2A9LzjNt5ZlWRCKDdIjHl3BVGpyl80o7rY8Q0u6tHb7D5gAsJ
        ...
        -----END OPENSSH PRIVATE KEY-----
      • 错误示例(行之间有空格):
        -----BEGIN OPENSSH PRIVATE KEY-----
        
        b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcnNh
        
        AAAwEAAQAAAgEA76sBh9hA2A9LzjNt5ZlWRCKDdIjHl3BVGpyl80o7rY8Q0u6tHb7D5gAsJ
        
        -----END OPENSSH PRIVATE KEY-----
  4. 点击 确定 保存

私钥格式说明:

  • 如果使用 sshagent 方法,建议使用传统PEM格式的私钥(-----BEGIN RSA PRIVATE KEY-----)
  • 如果使用 withCredentials 方法,支持所有格式(推荐,更稳定)
  • 如果遇到 error in libcrypto 错误,请检查私钥格式或使用 withCredentials 方法

步骤3: 配置Nginx服务器 ​

在Nginx服务器(127.0.0.1)上执行:

bash
# 方式1: 使用提供的脚本
chmod +x setup-nginx.sh
./setup-nginx.sh

# 方式2: 手动执行
# 创建部署目录
mkdir -p /data/nginx/html/ruoyi-office-doc
chmod 755 /data/nginx/html/ruoyi-office-doc

# 创建Nginx配置文件
cat > /data/nginx/conf/conf.d/ruoyi-office-doc.conf << 'EOF'
server {
    listen 80 default_server;  # 使用 default_server 确保这是默认虚拟主机
    server_name _;  # 替换为你的域名,如: doc.example.com
    
    root /usr/share/nginx/html/ruoyi-office-doc;
    index index.html;

    access_log /var/log/nginx/ruoyi-office-doc-access.log;
    error_log /var/log/nginx/ruoyi-office-doc-error.log;

    charset utf-8;

    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;

    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    location / {
        try_files $uri $uri/ $uri.html /index.html;
    }

    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}
EOF

# 验证Nginx配置
docker exec nginx nginx -t

# 检查配置文件是否被加载
docker exec nginx nginx -T | grep -A 20 "ruoyi-office-doc"

# 重启Nginx容器
docker restart nginx

重要提示: 如果访问 http://127.0.0.1 仍然显示默认页面,请按以下步骤排查:

  1. 检查配置文件是否存在:

    bash
    ls -la /data/nginx/conf/conf.d/ruoyi-office-doc.conf
    cat /data/nginx/conf/conf.d/ruoyi-office-doc.conf
  2. 检查Nginx主配置文件是否包含conf.d目录:

    bash
    docker exec nginx cat /etc/nginx/nginx.conf | grep -i "include.*conf.d"

    如果没有输出,需要在主配置文件中添加:

    bash
    # 查看主配置文件
    docker exec nginx cat /etc/nginx/nginx.conf

    确保 http 块中包含:

    nginx
    include /etc/nginx/conf.d/*.conf;
  3. 修改配置文件使用 default_server(确保优先级):

    bash
    # 编辑配置文件,将 listen 80; 改为 listen 80 default_server;
    sed -i 's/listen 80;/listen 80 default_server;/' /data/nginx/conf/conf.d/ruoyi-office-doc.conf
  4. 检查部署文件是否存在:

    bash
    docker exec nginx ls -la /usr/share/nginx/html/ruoyi-office-doc/
  5. 重新加载配置:

    bash
    docker exec nginx nginx -t  # 验证配置
    docker exec nginx nginx -s reload  # 重新加载(比restart更优雅)
  6. 查看Nginx错误日志:

    bash
    docker exec nginx tail -f /var/log/nginx/error.log

步骤4: 配置Jenkins Pipeline任务 ​

  1. 登录Jenkins Web界面
  2. 点击 新建任务
  3. 输入任务名称(如:ruoyi-office-doc-deploy)
  4. 选择 流水线 (Pipeline)
  5. 点击 确定
  6. 在配置页面:
    • Pipeline定义: 选择 Pipeline script from SCM
    • SCM: 选择 Git
    • Repository URL: git@codeup.aliyun.com:676b69e335730943ed494c52/ruoyi-office/ruoyi-office-doc.git
    • Credentials: 选择可以访问Git仓库的凭据(如已配置)
    • 分支: */main 或 */master(根据实际分支名)
    • 脚本路径: Jenkinsfile
  7. 点击 保存

步骤5: 安装必要插件 ​

5.0 安装 Publish Over SSH 插件(推荐,使部署更简单)

  1. 进入 Jenkins管理 -> 插件管理 -> 可选插件
  2. 搜索 Publish Over SSH
  3. 安装插件并重启 Jenkins(如需要)
  4. 详细配置请参考 JENKINS_PUBLISH_OVER_SSH.md 文档

优势:

  • 配置集中管理,多个任务可复用
  • Jenkinsfile 更简洁清晰
  • 自动显示文件传输进度
  • 支持多服务器部署

步骤6: 安装NodeJS插件并配置Node.js工具 ​

6.1 安装NodeJS插件(如果全局工具配置中没有NodeJS选项)

  1. 进入 Jenkins管理 -> 插件管理
  2. 点击 可选插件 标签页
  3. 在搜索框中输入 NodeJS
  4. 找到 NodeJS Plugin(作者:Jenkins project)
  5. 勾选该插件,点击 直接安装 或 下载待重启后安装
  6. 如果选择"下载待重启后安装",需要重启Jenkins容器:
    bash
    # 在Jenkins服务器(140)上执行
    docker restart jenkins
  7. 等待插件安装完成(安装完成后可能需要重启Jenkins)

6.2 配置Node.js工具

  1. 进入 Jenkins管理 -> 全局工具配置
  2. 找到 NodeJS 部分(如果已安装插件,应该能看到)
  3. 点击 新增NodeJS
  4. 配置:
    • 名称: node20(必须与Jenkinsfile中的名称一致)
    • 版本: 选择 Node.js 20.x 版本(如:20.18.0)
    • 勾选 自动安装
    • 全局npm包: 可以留空,或根据需要添加全局包(如:npm@latest)
  5. 点击 保存

注意: 如果Jenkins运行在Docker容器中,确保容器可以访问外网以下载Node.js。

步骤6: 执行首次部署 ​

  1. 在Jenkins任务页面,点击 立即构建
  2. 查看构建日志,确认:
    • ✅ Checkout阶段:代码拉取成功
    • ✅ Install阶段:npm依赖安装成功
    • ✅ Build阶段:VitePress构建成功
    • ✅ Deploy阶段:文件传输成功
  3. 如果构建失败,检查:
    • SSH连接是否正常
    • 远程目录权限是否正确
    • Nginx配置文件是否正确

步骤7: 验证部署 ​

  1. 检查文件是否传输成功:

    bash
    # 在Nginx服务器上执行
    ls -la /data/nginx/html/ruoyi-office-doc/
  2. 访问站点:

    • 浏览器访问: http://127.0.0.1
    • 或使用域名(如已配置): http://doc.example.com
  3. 检查Nginx日志:

    bash
    docker exec nginx tail -f /var/log/nginx/ruoyi-office-doc-access.log

后续维护 ​

自动触发部署 ​

可以配置Git Webhook,在代码推送时自动触发Jenkins构建:

  1. 在Git仓库设置中添加Webhook
  2. Webhook URL: http://140:8080/github-webhook/(根据实际Jenkins配置)
  3. 触发事件: Push events

手动触发部署 ​

在Jenkins任务页面点击 立即构建 即可。

查看部署历史 ​

在Jenkins任务页面可以查看所有构建历史和日志。

故障排查 ​

SSH连接失败 ​

bash
# 测试SSH连接
ssh -i ~/.ssh/jenkins_rsa root@127.0.0.1

# 检查SSH密钥权限
chmod 600 ~/.ssh/jenkins_rsa
chmod 644 ~/.ssh/jenkins_rsa.pub

rsync传输失败 ​

  • 检查远程目录是否存在: ssh root@127.0.0.1 "ls -la /data/nginx/html/ruoyi-office-doc"
  • 检查目录权限: ssh root@127.0.0.1 "chmod 755 /data/nginx/html/ruoyi-office-doc"

Nginx无法访问或显示默认页面 ​

问题: 访问 http://127.0.0.1 显示默认的 html/index.html 而不是文档站点

排查步骤:

  1. 检查配置文件是否存在且正确:

    bash
    ls -la /data/nginx/conf/conf.d/ruoyi-office-doc.conf
    cat /data/nginx/conf/conf.d/ruoyi-office-doc.conf
  2. 检查Nginx主配置文件是否包含conf.d:

    bash
    docker exec nginx cat /etc/nginx/nginx.conf | grep -i "include.*conf.d"

    如果没有输出,说明主配置文件没有加载conf.d目录,需要检查主配置文件。

  3. 检查配置是否被加载:

    bash
    docker exec nginx nginx -T | grep -A 20 "ruoyi-office-doc"

    如果没有任何输出,说明配置没有被加载。

  4. 确保使用 default_server:

    bash
    # 检查配置文件中是否有 default_server
    grep "default_server" /data/nginx/conf/conf.d/ruoyi-office-doc.conf
    
    # 如果没有,添加 default_server
    sed -i 's/listen 80;/listen 80 default_server;/' /data/nginx/conf/conf.d/ruoyi-office-doc.conf
  5. 检查部署文件是否存在:

    bash
    docker exec nginx ls -la /usr/share/nginx/html/ruoyi-office-doc/

    如果目录为空,说明文件还没有部署,需要先执行Jenkins构建。

  6. 检查是否有其他默认server块:

    bash
    docker exec nginx nginx -T | grep -B 5 -A 10 "listen 80"

    查看所有监听80端口的server块,确保只有一个使用 default_server。

  7. 重新加载配置:

    bash
    docker exec nginx nginx -t  # 验证配置语法
    docker exec nginx nginx -s reload  # 重新加载配置
  8. 查看Nginx错误日志:

    bash
    docker exec nginx tail -f /var/log/nginx/error.log
    docker exec nginx tail -f /var/log/nginx/ruoyi-office-doc-error.log

常见原因:

  • Nginx主配置文件没有包含 include /etc/nginx/conf.d/*.conf;
  • 配置文件没有使用 default_server,导致默认server块优先级更高
  • 部署文件还没有传输到服务器(需要先执行Jenkins构建)
  • 配置文件语法错误导致没有加载

构建失败 ​

问题: Jenkins构建失败,提示找不到Node.js工具

排查步骤:

  1. 检查NodeJS插件是否已安装:

    • 进入 Jenkins管理 -> 插件管理 -> 已安装
    • 搜索 NodeJS,确认 NodeJS Plugin 已安装
    • 如果未安装,参考步骤5.1安装插件
  2. 检查Node.js工具是否已配置:

    • 进入 Jenkins管理 -> 全局工具配置
    • 查看 NodeJS 部分,确认是否有名称为 node20 的配置
    • 如果不存在,参考步骤5.2配置Node.js工具
  3. 检查工具名称是否匹配:

    • Jenkinsfile中使用的工具名称是 node20
    • 全局工具配置中的名称必须完全一致(区分大小写)
  4. 检查Node.js版本:

    • 在构建日志中查看Node版本信息
    • 确保使用的是Node.js 20.x版本(VitePress要求Node.js ≥ 20.12.0)
  5. 检查npm依赖安装:

    • 查看Install阶段的错误信息
    • 如果网络问题,检查Jenkins容器是否可以访问外网
    • 如果权限问题,检查Jenkins用户权限
  6. 检查VitePress构建:

    • 查看Build阶段的错误信息
    • 检查 docs/.vitepress/config.mts 配置文件是否正确
    • 检查构建产物目录 docs/.vitepress/dist 是否生成

常见错误:

  • nodejs tool 'node20' not found: Node.js工具未配置或名称不匹配
  • npm: command not found: NodeJS插件未正确安装或配置
  • Error: Cannot find module: npm依赖安装失败,检查网络和权限
  • npm ci command can only install with an existing package-lock.json: package-lock.json 文件不存在
  • No such DSL method 'sshagent' found: SSH Agent Plugin 未安装

npm ci 失败问题:

如果遇到 npm ci 命令失败,提示缺少 package-lock.json 文件,可能的原因:

  1. package-lock.json 被 .gitignore 忽略(当前项目就是这种情况)

    • 解决方案A(推荐):将 package-lock.json 提交到仓库
      bash
      # 从 .gitignore 中移除 package-lock.json
      # 然后提交文件
      git add package-lock.json
      git commit -m "chore: add package-lock.json for consistent builds"
    • 解决方案B(临时):Jenkinsfile 已改为使用 npm install,可以正常工作但依赖版本可能不一致
  2. package-lock.json 文件损坏或格式错误

    • 删除后重新生成:rm package-lock.json && npm install
    • 然后提交新的 package-lock.json

建议: 为了确保构建的一致性和可重复性,强烈建议将 package-lock.json 提交到 Git 仓库,并将 Jenkinsfile 中的 npm install 改回 npm ci。

sshagent 方法不存在问题:

如果遇到 No such DSL method 'sshagent' found 错误,说明 Jenkins 没有安装 SSH Agent Plugin。

解决方案:

Jenkinsfile 已更新为使用 withCredentials 方法,这是 Jenkins 内置功能,无需安装额外插件。

如果仍想使用 sshagent(更简洁),可以安装 SSH Agent Plugin:

  1. 进入 Jenkins管理 -> 插件管理 -> 可选插件
  2. 搜索 SSH Agent Plugin
  3. 安装插件并重启 Jenkins
  4. 然后将 Jenkinsfile 中的 withCredentials 改回 sshagent:
groovy
stage('Deploy') {
  steps {
    sshagent(credentials: [env.SSH_CRED]) {
      sh """
        rsync -avz --delete ${env.DIST_DIR}/ ${env.REMOTE_HOST}:${env.REMOTE_PATH}/
      """
    }
  }
}

当前方案: Jenkinsfile 使用 withCredentials,无需安装插件即可工作。

rsync命令不存在问题:

如果遇到 rsync: not found 错误,说明Jenkins容器内没有安装rsync命令。

解决方案:

Jenkinsfile 已更新为使用 tar + ssh 方法,这是Jenkins容器的标准工具,无需安装额外软件。

工作原理:

  1. 使用 tar czf - 将文件打包并输出到标准输出
  2. 通过SSH管道传输到远程服务器
  3. 在远程服务器上使用 tar xzf - 解压文件
  4. 传输前先删除远程目录的旧文件

如果仍想使用rsync,可以在Jenkins容器内安装:

bash
# 进入Jenkins容器
docker exec -it jenkins bash

# 安装rsync(根据容器基础镜像选择命令)
# 如果是Debian/Ubuntu基础镜像
apt-get update && apt-get install -y rsync

# 如果是Alpine基础镜像
apk add --no-cache rsync

# 如果是CentOS/RHEL基础镜像
yum install -y rsync

注意: 如果容器重启,rsync会丢失,需要重新安装或使用自定义Docker镜像。

SSH Permission denied 问题:

如果遇到 Permission denied (publickey,...) 错误,可能的原因:

  1. SSH命令中缺少用户名:

    • 使用 sshagent 时,需要在SSH命令中明确指定用户名
    • 错误:ssh 127.0.0.1 ...
    • 正确:ssh root@127.0.0.1 ...
  2. 远程服务器未配置authorized_keys:

    • 确保公钥已正确添加到远程服务器的 /root/.ssh/authorized_keys
    • 检查方法:
      bash
      # 在Nginx服务器(127.0.0.1)上执行
      cat /root/.ssh/authorized_keys
    • 如果文件不存在或没有公钥,需要重新执行 ssh-copy-id
  3. SSH密钥权限问题:

    • 确保远程服务器的 .ssh 目录权限正确:
      bash
      # 在Nginx服务器上执行
      chmod 700 /root/.ssh
      chmod 600 /root/.ssh/authorized_keys
  4. 解决方案:

    方案A: 确保Jenkinsfile中SSH命令包含用户名

    groovy
    ssh root@${env.REMOTE_HOST} "command"

    方案B: 使用 withCredentials 方法(推荐,自动获取用户名)

    groovy
    withCredentials([sshUserPrivateKey(credentialsId: env.SSH_CRED, keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER')]) {
      sh "ssh -i ${SSH_KEY} ${SSH_USER}@${env.REMOTE_HOST} 'command'"
    }

    方案C: 重新配置SSH密钥

    bash
    # 在Jenkins服务器上执行
    ssh-copy-id -i ~/.ssh/jenkins_rsa.pub root@127.0.0.1

SSH私钥格式错误问题:

如果使用 sshagent 时遇到 Error loading key: error in libcrypto 错误,可能的原因:

  1. 私钥格式不兼容:

    • sshagent 对私钥格式要求较严格,可能不支持 OpenSSH 格式(-----BEGIN OPENSSH PRIVATE KEY-----)
    • 建议使用传统 PEM 格式(-----BEGIN RSA PRIVATE KEY-----)
  2. 私钥内容不完整:

    • 确保私钥文件完整,包括所有行
    • 检查是否有额外的空格或换行
    • 确保首尾标记行正确
  3. 解决方案:

    方案A(推荐): 继续使用 withCredentials 方法

    • Jenkinsfile 默认使用此方法
    • 兼容所有私钥格式
    • 更稳定可靠

    方案B: 转换私钥格式为传统PEM格式

    bash
    # 在Jenkins服务器上执行
    # 将OpenSSH格式转换为PEM格式
    ssh-keygen -p -m PEM -f ~/.ssh/jenkins_rsa
    
    # 然后重新复制私钥内容到Jenkins凭据
    cat ~/.ssh/jenkins_rsa

    方案C: 重新生成传统格式的密钥

    bash
    # 生成传统PEM格式的密钥
    ssh-keygen -t rsa -b 4096 -m PEM -C "jenkins@140" -f ~/.ssh/jenkins_rsa
    
    # 复制公钥到目标服务器
    ssh-copy-id -i ~/.ssh/jenkins_rsa.pub root@127.0.0.1
    
    # 更新Jenkins凭据中的私钥内容

配置文件说明 ​

  • Jenkinsfile: Jenkins Pipeline配置文件,定义了构建和部署流程
  • nginx/ruoyi-office-doc.conf: Nginx虚拟主机配置文件模板
  • setup-ssh.sh: SSH免密登录配置脚本
  • setup-nginx.sh: Nginx服务器环境配置脚本

注意事项 ​

  1. 安全性:

    • 建议使用非root用户部署
    • 建议配置HTTPS(需要SSL证书)
    • 定期更新SSH密钥
  2. 性能优化:

    • 已配置静态资源缓存(30天)
    • 已启用Gzip压缩
    • 可根据需要调整缓存策略
  3. 监控:

    • 建议配置Jenkins构建通知(邮件/企业微信等)
    • 建议配置Nginx访问监控
    • 建议配置站点健康检查
联系我们

获取报价、演示和二开方案

微信咨询二维码

微信咨询

17156169080

添加时备注「RuoYi Office」

在线体验商业版