欢迎光临
我们一直在努力

Jenkins 配置 Publish over SSH 自动部署项目

一、前提条件

  • 环境准备:
    • Jenkins 已安装 Publish Over SSH 插件(进入 Manage Jenkins → Plugins → 搜索并安装 Publish Over SSH)。
    • 目标部署服务器(需部署项目的服务器)已开启 SSH 服务(默认端口 22,若为其他端口需单独配置)。
    • Jenkins 服务器(或容器)与目标服务器网络互通(可通过 ping 或 telnet <目标IP> 22 验证)。
  • 二、配置 Jenkins 与目标服务器的 SSH 免密登录

    1. 在 Jenkins 容器内生成 SSH 密钥对

    由于 Jenkins 通常通过 Docker 容器运行,需进入容器内生成密钥(确保密钥由 Jenkins 服务用户持有):

    # 进入 Jenkins 容器(替换容器名为实际容器名,如 "jenkins")
    docker exec -it -u root jenkins /bin/bash

    # 生成 RSA 密钥对(一路回车,可选设置密钥密码 Passphrase,生产环境建议设置)
    ssh-keygen -t rsa -b 2048 -C "jenkins-ssh-key"

    # 生成后密钥路径:私钥 /root/.ssh/id_rsa,公钥 /root/.ssh/id_rsa.pub

    2. 将公钥复制到目标部署服务器

    方式 1:使用 ssh-copy-id 自动复制(推荐,需目标服务器支持)

    # 首次连接目标服务器,需手动确认指纹(输入 "yes")并输入目标服务器密码
    ssh <目标服务器用户名>@<目标服务器IP> # 例如:ssh appuser@172.20.113.93

    # 复制公钥到目标服务器(替换用户名和IP)
    ssh-copy-id -i ~/.ssh/id_rsa.pub <目标服务器用户名>@<目标服务器IP>

    方式 2:手动复制公钥(若 ssh-copy-id 不可用)
  • 查看 Jenkins 容器内的公钥内容:

    cat /root/.ssh/id_rsa.pub

    复制输出的公钥文本(以 ssh-rsa 开头)。

  • 登录目标服务器,粘贴公钥到 authorized_keys:

    # 登录目标服务器
    ssh <目标服务器用户名>@<目标服务器IP>

    # 创建 .ssh 目录(若不存在)
    mkdir -p ~/.ssh && chmod 700 ~/.ssh

    # 编辑 authorized_keys 文件,粘贴 Jenkins 公钥
    vi ~/.ssh/authorized_keys # 粘贴公钥后保存退出

    # 设置权限(必须,否则 SSH 会拒绝免密登录)
    chmod 600 ~/.ssh/authorized_keys

  • 3. 验证 SSH 免密连接

    在 Jenkins 容器内执行以下命令,确认无需密码即可登录目标服务器:

    ssh <目标服务器用户名>@<目标服务器IP> # 若直接进入目标服务器终端,说明免密配置成功

    三、Jenkins 全局配置 Publish over SSH

    1. 进入配置页面

    Jenkins 首页 → Manage Jenkins → System(系统配置)→ 找到 Publish over SSH 模块。

    2. 配置 SSH 服务器(目标部署服务器)

    (1)配置 SSH 密钥
    字段填写说明
    Passphrase 若生成密钥时设置了“密钥密码”,则填写该密码;未设置则留空。
    Path to key 私钥在 Jenkins 容器内的绝对路径(如 /root/.ssh/id_rsa)。
    Key 直接粘贴私钥文件(id_rsa)的完整文本内容(若填写此项,Path to key 会被忽略)。

    推荐配置:直接粘贴私钥内容(避免容器路径变更导致失效):

    • 在 Jenkins 容器内执行 cat /root/.ssh/id_rsa,复制完整私钥文本(从 —–BEGIN RSA PRIVATE KEY—– 到 —–END RSA PRIVATE KEY—–)。
    • 粘贴到 Key 字段中。
    (2)添加目标服务器信息

    点击 SSH Servers → Add,配置目标部署服务器参数:

    字段填写说明
    Name 自定义服务器名称(如“deploy-server-172.20.113.93”,后续构建时选择)。
    Hostname 目标服务器 IP 或域名(如 172.20.113.93)。
    Username 目标服务器登录用户名(如 appuser)。
    Remote Directory (可选)默认远程目录(若构建后步骤中未指定,会使用此目录,一般留空)。
    Port SSH 端口(默认 22,若目标服务器 SSH 端口非 22,需填写实际端口,如 2222)。

    高级选项(按需配置):

    • 勾选 Use password authentication, or use a different key:若不使用全局密钥,可单独指定该服务器的密钥。
    • Timeout (ms):设置 SSH 连接超时时间(默认 30000 ms,网络差时可延长)。

    3. 测试 SSH 连接

    点击 Test Configuration,若显示 Success,说明目标服务器配置正确;否则检查密钥、用户名、IP 或端口是否错误。

    4. 保存配置

    点击页面底部 Save,完成 Publish over SSH 全局配置。

    四、在项目中添加构建后部署步骤(以 Spring Boot 项目为例)

    以之前的 Spring Boot 项目任务(如 project-springboot-admin)为例,添加“通过 SSH 发送构建产物并部署”的步骤。

    1. 进入项目配置页面

    项目任务页面 → Configure(配置)→ Post-build Actions(构建后操作)→ 点击 Add post-build action → 选择 Send build artifacts over SSH。

    2. 配置 SSH 部署参数

    (1)选择目标服务器
    • SSH Server:从下拉列表选择在全局配置中添加的目标服务器(如“deploy-server-172.20.113.93”)。
    (2)配置文件传输(Transfer Set)
    字段填写说明
    Source files 需传输到目标服务器的文件路径(相对于 Jenkins 项目工作区的相对路径)。示例:dsrm-server/target/dsrm-server.jar(Spring Boot 项目打包后的 JAR 包路径)。
    Remove prefix (可选)移除源文件路径的前缀(如填写 dsrm-server/target,则传输到目标服务器的文件名为 dsrm-server.jar,而非带路径的文件)。
    Remote directory 目标服务器接收文件的目录(绝对路径)。示例:/home/etc/xxxxxx/target(根据实际部署路径填写)。
    Exec command 文件传输完成后在目标服务器执行的部署命令(如备份旧版本、启动新服务)。
    (3)填写部署命令(Exec command)

    用户提供的示例命令(需根据实际路径调整):

    # 1. 备份旧版本 JAR 包(以当前时间戳命名,保留历史版本)
    mv /data/app/xxxxx.jar /data/app/xxxxx.jar-$(date +%Y%m%d%H%M%S)

    # 2. 将传输到目标服务器的新 JAR 包移动到部署目录
    mv /home/etc/xxxxxx/target/dsrm-server.jar /data/app/xxxx.jar

    # 3. 执行重启脚本(后台运行,避免 Jenkins 构建进程阻塞)
    sh -c "cd /data/app && ./restart.sh & disown"

    3. 保存项目配置

    点击 Save,完成构建后部署步骤配置。

    五、部署脚本(restart.sh)说明

    目标服务器 /data/app/restart.sh 脚本用于停止旧服务、启动新服务,内容如下(需提前创建并赋予执行权限):

    #!/bin/bash
    # 停止旧服务
    rm -f nohup.out # 清理旧日志
    app="xxxx.jar" # 替换为实际 JAR 包名称(如 dsrm-server.jar)
    pid=$(ps -ef | grep "$app" | grep -v grep | awk '{print $2}') # 获取进程 ID

    if [ -n "$pid" ]; then
    echo "Stopping old process: $pid"
    kill -9 "$pid" # 强制停止进程
    fi

    # 启动新服务(使用指定 JDK 路径,后台运行并输出日志)
    jdk11_path="/data/software/jdk-17/bin/java" # 替换为目标服务器 JDK 实际路径
    nohup setsid "$jdk11_path" -jar "$app" > nohup.out 2>&1 < /dev/null &
    echo "New process started successfully"

    脚本权限设置(目标服务器执行):

    chmod +x /data/app/restart.sh # 赋予执行权限

    六、验证自动部署

    1. 手动触发构建

    进入项目任务页面 → Build Now,等待构建完成。

    2. 查看部署日志

    • Jenkins 构建日志:构建后点击 Console Output,搜索 SSH: Transferred 1 file(s)(文件传输成功)和 Exec command complete(部署命令执行完成)。
    • 目标服务器日志:登录目标服务器,查看 /data/app/nohup.out,确认新服务启动日志(如 Started XxxApplication in x.x seconds)。

    七、常见问题排查

    1. SSH 连接失败(日志显示 Connection refused 或 Authentication failed)

    • 原因:目标服务器 SSH 端口错误、公钥未正确复制、Jenkins 私钥配置错误。
    • 解决:
      • 确认目标服务器 SSH 端口(默认 22),全局配置中 Port 字段是否正确。
      • 重新执行公钥复制步骤,确保目标服务器 ~/.ssh/authorized_keys 包含 Jenkins 公钥,且权限为 700(.ssh 目录)和 600(authorized_keys)。
      • 检查 Jenkins 全局配置的私钥是否完整(无多余空格或换行)。

    2. 文件传输失败(日志显示 No such file)

    • 原因:Source files 路径错误(相对于 Jenkins 项目工作区)。
    • 解决:在 Jenkins 项目工作区(如 /var/jenkins_home/workspace/project-springboot-admin)确认 JAR 包实际路径,调整 Source files(如 dsrm-server/target/dsrm-server.jar)。

    3. 部署命令执行失败(日志显示 mv: cannot stat …)

    • 原因:Remote directory 路径错误或目标服务器目录权限不足。
    • 解决:
      • 登录目标服务器,确认 Remote directory(如 /home/etc/xxxxxx/target)是否存在,若不存在则创建:mkdir -p /home/etc/xxxxxx/target。
      • 确保 Jenkins 登录用户(如 appuser)对目标目录有读写权限:chown -R appuser:appuser /home/etc/xxxxxx/target。

    4. 服务启动失败(nohup.out 日志报错)

    • 原因:JDK 路径错误、JAR 包损坏或配置文件缺失。
    • 解决:
      • 检查 restart.sh 中的 jdk11_path 是否指向目标服务器实际 JDK 路径(执行 which java 确认)。
      • 手动在目标服务器执行 java -jar /data/app/xxxx.jar,查看启动错误(如依赖缺失、端口占用)。

    八、总结

    通过以上步骤,Jenkins 可在构建完成后自动将 Spring Boot 项目的 JAR 包通过 SSH 传输到目标服务器,并执行部署脚本完成服务重启。该流程可扩展到多服务器部署(添加多个 SSH Server)或其他项目(如 Vue 项目传输前端包到 Nginx 目录),实现全自动化部署。
    在这里插入图片描述

    赞(0)
    未经允许不得转载:171主机测评 » Jenkins 配置 Publish over SSH 自动部署项目
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址