@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)上执行:
# 方式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: 从容器内直接获取(如果密钥在容器内)
# 进入容器查看
docker exec jenkins cat ~/.ssh/jenkins_rsa | grep -v '^$'
# 或者查找密钥位置
docker exec jenkins find ~ -name "jenkins_rsa"方法2: 从宿主机挂载目录获取(推荐)
# Jenkins容器挂载了 /opt/jenkins_home:/var/jenkins_home
# 在宿主机上查找
find /opt/jenkins_home -name "jenkins_rsa"
# 如果找到,直接查看(过滤空行)
cat /opt/jenkins_home/.ssh/jenkins_rsa | grep -v '^$'方法3: 使用提供的脚本(最简单)
# 在Jenkins服务器上执行
chmod +x get-jenkins-ssh-key.sh
./get-jenkins-ssh-key.sh脚本会自动查找密钥位置并显示正确格式的私钥内容。
步骤2: 配置Jenkins SSH凭据
- 登录Jenkins Web界面(http://140:8080)
- 进入
Jenkins管理->凭据管理->系统->全局凭据->添加凭据 - 配置如下:
- 类型:
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-----
- 重要: 确保私钥内容完整且格式正确:
- 类型:
- 点击
确定保存
私钥格式说明:
- 如果使用
sshagent方法,建议使用传统PEM格式的私钥(-----BEGIN RSA PRIVATE KEY-----) - 如果使用
withCredentials方法,支持所有格式(推荐,更稳定) - 如果遇到
error in libcrypto错误,请检查私钥格式或使用withCredentials方法
步骤3: 配置Nginx服务器
在Nginx服务器(127.0.0.1)上执行:
# 方式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 仍然显示默认页面,请按以下步骤排查:
检查配置文件是否存在:
bashls -la /data/nginx/conf/conf.d/ruoyi-office-doc.conf cat /data/nginx/conf/conf.d/ruoyi-office-doc.conf检查Nginx主配置文件是否包含conf.d目录:
bashdocker exec nginx cat /etc/nginx/nginx.conf | grep -i "include.*conf.d"如果没有输出,需要在主配置文件中添加:
bash# 查看主配置文件 docker exec nginx cat /etc/nginx/nginx.conf确保
http块中包含:nginxinclude /etc/nginx/conf.d/*.conf;修改配置文件使用 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检查部署文件是否存在:
bashdocker exec nginx ls -la /usr/share/nginx/html/ruoyi-office-doc/重新加载配置:
bashdocker exec nginx nginx -t # 验证配置 docker exec nginx nginx -s reload # 重新加载(比restart更优雅)查看Nginx错误日志:
bashdocker exec nginx tail -f /var/log/nginx/error.log
步骤4: 配置Jenkins Pipeline任务
- 登录Jenkins Web界面
- 点击
新建任务 - 输入任务名称(如:
ruoyi-office-doc-deploy) - 选择
流水线(Pipeline) - 点击
确定 - 在配置页面:
- 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
- Pipeline定义: 选择
- 点击
保存
步骤5: 安装必要插件
5.0 安装 Publish Over SSH 插件(推荐,使部署更简单)
- 进入
Jenkins管理->插件管理->可选插件 - 搜索
Publish Over SSH - 安装插件并重启 Jenkins(如需要)
- 详细配置请参考
JENKINS_PUBLISH_OVER_SSH.md文档
优势:
- 配置集中管理,多个任务可复用
- Jenkinsfile 更简洁清晰
- 自动显示文件传输进度
- 支持多服务器部署
步骤6: 安装NodeJS插件并配置Node.js工具
6.1 安装NodeJS插件(如果全局工具配置中没有NodeJS选项)
- 进入
Jenkins管理->插件管理 - 点击
可选插件标签页 - 在搜索框中输入
NodeJS - 找到
NodeJS Plugin(作者:Jenkins project) - 勾选该插件,点击
直接安装或下载待重启后安装 - 如果选择"下载待重启后安装",需要重启Jenkins容器:bash
# 在Jenkins服务器(140)上执行 docker restart jenkins - 等待插件安装完成(安装完成后可能需要重启Jenkins)
6.2 配置Node.js工具
- 进入
Jenkins管理->全局工具配置 - 找到
NodeJS部分(如果已安装插件,应该能看到) - 点击
新增NodeJS - 配置:
- 名称:
node20(必须与Jenkinsfile中的名称一致) - 版本: 选择 Node.js 20.x 版本(如:20.18.0)
- 勾选
自动安装 - 全局npm包: 可以留空,或根据需要添加全局包(如:
npm@latest)
- 名称:
- 点击
保存
注意: 如果Jenkins运行在Docker容器中,确保容器可以访问外网以下载Node.js。
步骤6: 执行首次部署
- 在Jenkins任务页面,点击
立即构建 - 查看构建日志,确认:
- ✅ Checkout阶段:代码拉取成功
- ✅ Install阶段:npm依赖安装成功
- ✅ Build阶段:VitePress构建成功
- ✅ Deploy阶段:文件传输成功
- 如果构建失败,检查:
- SSH连接是否正常
- 远程目录权限是否正确
- Nginx配置文件是否正确
步骤7: 验证部署
检查文件是否传输成功:
bash# 在Nginx服务器上执行 ls -la /data/nginx/html/ruoyi-office-doc/访问站点:
- 浏览器访问:
http://127.0.0.1 - 或使用域名(如已配置):
http://doc.example.com
- 浏览器访问:
检查Nginx日志:
bashdocker exec nginx tail -f /var/log/nginx/ruoyi-office-doc-access.log
后续维护
自动触发部署
可以配置Git Webhook,在代码推送时自动触发Jenkins构建:
- 在Git仓库设置中添加Webhook
- Webhook URL:
http://140:8080/github-webhook/(根据实际Jenkins配置) - 触发事件:
Push events
手动触发部署
在Jenkins任务页面点击 立即构建 即可。
查看部署历史
在Jenkins任务页面可以查看所有构建历史和日志。
故障排查
SSH连接失败
# 测试SSH连接
ssh -i ~/.ssh/jenkins_rsa root@127.0.0.1
# 检查SSH密钥权限
chmod 600 ~/.ssh/jenkins_rsa
chmod 644 ~/.ssh/jenkins_rsa.pubrsync传输失败
- 检查远程目录是否存在:
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 而不是文档站点
排查步骤:
检查配置文件是否存在且正确:
bashls -la /data/nginx/conf/conf.d/ruoyi-office-doc.conf cat /data/nginx/conf/conf.d/ruoyi-office-doc.conf检查Nginx主配置文件是否包含conf.d:
bashdocker exec nginx cat /etc/nginx/nginx.conf | grep -i "include.*conf.d"如果没有输出,说明主配置文件没有加载conf.d目录,需要检查主配置文件。
检查配置是否被加载:
bashdocker exec nginx nginx -T | grep -A 20 "ruoyi-office-doc"如果没有任何输出,说明配置没有被加载。
确保使用 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检查部署文件是否存在:
bashdocker exec nginx ls -la /usr/share/nginx/html/ruoyi-office-doc/如果目录为空,说明文件还没有部署,需要先执行Jenkins构建。
检查是否有其他默认server块:
bashdocker exec nginx nginx -T | grep -B 5 -A 10 "listen 80"查看所有监听80端口的server块,确保只有一个使用
default_server。重新加载配置:
bashdocker exec nginx nginx -t # 验证配置语法 docker exec nginx nginx -s reload # 重新加载配置查看Nginx错误日志:
bashdocker 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工具
排查步骤:
检查NodeJS插件是否已安装:
- 进入
Jenkins管理->插件管理->已安装 - 搜索
NodeJS,确认NodeJS Plugin已安装 - 如果未安装,参考步骤5.1安装插件
- 进入
检查Node.js工具是否已配置:
- 进入
Jenkins管理->全局工具配置 - 查看
NodeJS部分,确认是否有名称为node20的配置 - 如果不存在,参考步骤5.2配置Node.js工具
- 进入
检查工具名称是否匹配:
- Jenkinsfile中使用的工具名称是
node20 - 全局工具配置中的名称必须完全一致(区分大小写)
- Jenkinsfile中使用的工具名称是
检查Node.js版本:
- 在构建日志中查看Node版本信息
- 确保使用的是Node.js 20.x版本(VitePress要求Node.js ≥ 20.12.0)
检查npm依赖安装:
- 查看Install阶段的错误信息
- 如果网络问题,检查Jenkins容器是否可以访问外网
- 如果权限问题,检查Jenkins用户权限
检查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 文件,可能的原因:
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,可以正常工作但依赖版本可能不一致
- 解决方案A(推荐):将
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:
- 进入
Jenkins管理->插件管理->可选插件 - 搜索
SSH Agent Plugin - 安装插件并重启 Jenkins
- 然后将 Jenkinsfile 中的
withCredentials改回sshagent:
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容器的标准工具,无需安装额外软件。
工作原理:
- 使用
tar czf -将文件打包并输出到标准输出 - 通过SSH管道传输到远程服务器
- 在远程服务器上使用
tar xzf -解压文件 - 传输前先删除远程目录的旧文件
如果仍想使用rsync,可以在Jenkins容器内安装:
# 进入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,...) 错误,可能的原因:
SSH命令中缺少用户名:
- 使用
sshagent时,需要在SSH命令中明确指定用户名 - 错误:
ssh 127.0.0.1 ... - 正确:
ssh root@127.0.0.1 ...
- 使用
远程服务器未配置authorized_keys:
- 确保公钥已正确添加到远程服务器的
/root/.ssh/authorized_keys - 检查方法:bash
# 在Nginx服务器(127.0.0.1)上执行 cat /root/.ssh/authorized_keys - 如果文件不存在或没有公钥,需要重新执行
ssh-copy-id
- 确保公钥已正确添加到远程服务器的
SSH密钥权限问题:
- 确保远程服务器的
.ssh目录权限正确:bash# 在Nginx服务器上执行 chmod 700 /root/.ssh chmod 600 /root/.ssh/authorized_keys
- 确保远程服务器的
解决方案:
方案A: 确保Jenkinsfile中SSH命令包含用户名
groovyssh root@${env.REMOTE_HOST} "command"方案B: 使用
withCredentials方法(推荐,自动获取用户名)groovywithCredentials([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 错误,可能的原因:
私钥格式不兼容:
sshagent对私钥格式要求较严格,可能不支持 OpenSSH 格式(-----BEGIN OPENSSH PRIVATE KEY-----)- 建议使用传统 PEM 格式(
-----BEGIN RSA PRIVATE KEY-----)
私钥内容不完整:
- 确保私钥文件完整,包括所有行
- 检查是否有额外的空格或换行
- 确保首尾标记行正确
解决方案:
方案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服务器环境配置脚本
注意事项
安全性:
- 建议使用非root用户部署
- 建议配置HTTPS(需要SSL证书)
- 定期更新SSH密钥
性能优化:
- 已配置静态资源缓存(30天)
- 已启用Gzip压缩
- 可根据需要调整缓存策略
监控:
- 建议配置Jenkins构建通知(邮件/企业微信等)
- 建议配置Nginx访问监控
- 建议配置站点健康检查
