Skip to content

宇擎后端单体部署指南

项目信息

  • 项目名称: RuoYi Office 后端服务
  • 技术栈: Spring Boot 3.5.9 + MyBatis Plus + Redis + MySQL
  • Java 版本: JDK 17+(Docker 镜像使用 Eclipse Temurin 21)
  • 构建工具: Maven 3.8+
  • 服务端口: 48080

部署架构

Jenkins服务器(192.168.30.140)           目标服务器(192.168.30.130)
┌─────────────────────┐                ┌──────────────────────────┐
│  Jenkins容器         │                │  Docker                  │
│  - 拉取代码          │  SSH传输JAR    │  ┌────────────────────┐  │
│  - Maven 构建        │ ─────────────> │  │  MySQL 8.0         │  │
│  - 生成 JAR          │                │  │  - 端口: 3306      │  │
│                     │                │  │  - 数据库: ruoyi-  │  │
└─────────────────────┘                │  │    office          │  │
                                       │  └────────────────────┘  │
                                       │  ┌────────────────────┐  │
                                       │  │  Redis 7.x         │  │
                                       │  │  - 端口: 6379      │  │
                                       │  └────────────────────┘  │
                                       │  ┌────────────────────┐  │
                                       │  │  yudao-server      │  │
                                       │  │  - 端口: 48080     │  │
                                       │  └────────────────────┘  │
                                       └──────────────────────────┘

前置条件

  • Jenkins 服务器(140)已部署并运行
  • 目标服务器(130)已安装 Docker
  • 两台服务器之间网络互通
  • Jenkins 可以访问 Git 仓库

部署步骤

步骤1: 配置 SSH 免密登录

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

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

# 生成 SSH 密钥(如果已有密钥可跳过)
# 方式1: 使用默认名称 id_rsa
ssh-keygen -t rsa -b 4096 -C "jenkins@140" -f ~/.ssh/id_rsa -N ""

# 方式2: 使用自定义名称(如 jenkins_rsa)
# ssh-keygen -t rsa -b 4096 -C "jenkins@140" -f ~/.ssh/jenkins_rsa -N ""

# 将公钥复制到目标服务器
# 如果使用默认名称 id_rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.30.130

# 如果使用自定义名称 jenkins_rsa
# ssh-copy-id -i ~/.ssh/jenkins_rsa.pub root@192.168.30.130

# 测试连接
# 如果使用默认私钥
ssh root@192.168.30.130 'echo "SSH连接成功"'

# 如果使用指定私钥
#ssh -i ~/.ssh/jenkins_rsa root@192.168.30.130 'echo "SSH连接成功"'

# 退出容器
exit

说明: ssh-copy-id 会将公钥添加到目标服务器的 /root/.ssh/authorized_keys 文件中。

如果 ssh-copy-id 执行后仍然需要输入密码,请按以下步骤排查:

1.1 检查公钥是否已复制

bash
# 在 Jenkins 容器中查看公钥内容
cat ~/.ssh/id_rsa.pub

# 在目标服务器(130)上检查 authorized_keys
ssh root@192.168.30.130 "cat ~/.ssh/authorized_keys"

如果 authorized_keys 文件不存在或为空,手动复制公钥:

bash
# 方式1: 使用 ssh-copy-id(推荐,会自动处理权限)
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.30.130

# 方式2: 手动复制(如果方式1失败)
# 在 Jenkins 容器中执行
cat ~/.ssh/id_rsa.pub | ssh root@192.168.30.130 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

1.2 检查目标服务器权限

在目标服务器(130)上执行:

bash
# 检查 .ssh 目录权限(必须是 700)
ls -ld ~/.ssh
chmod 700 ~/.ssh

# 检查 authorized_keys 文件权限(必须是 600)
ls -l ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

# 检查文件所有者(必须是 root)
ls -l ~/.ssh/authorized_keys
chown root:root ~/.ssh/authorized_keys

1.3 检查 SSH 服务配置

在目标服务器(130)上检查 SSH 配置:

bash
# 检查 SSH 配置
grep -E "PubkeyAuthentication|AuthorizedKeysFile|PasswordAuthentication" /etc/ssh/sshd_config

# 应该看到:
# PubkeyAuthentication yes
# AuthorizedKeysFile .ssh/authorized_keys
# PasswordAuthentication yes(可选,建议保留作为备用)

# 如果配置被禁用,修改后重启 SSH 服务
sed -i 's/#PubkeyAuthentication no/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sed -i 's/PubkeyAuthentication no/PubkeyAuthentication yes/' /etc/ssh/sshd_config
systemctl restart sshd

1.4 使用详细模式测试连接

在 Jenkins 容器中执行:

bash
# 使用 -v 参数查看详细连接信息
ssh -v root@192.168.30.130 'echo "SSH连接成功"'

# 查看具体失败原因,常见问题:
# - Permission denied (publickey) - 公钥未正确配置
# - Host key verification failed - 需要添加 -o StrictHostKeyChecking=no

1.5 验证免密登录

成功配置后,应该不需要输入密码:

bash
# 测试连接(应该直接成功,不需要输入密码)
ssh -o StrictHostKeyChecking=no root@192.168.30.130 'echo "SSH免密登录成功"'

从宿主机获取私钥(用于 Jenkins 凭据配置):

bash
# Jenkins 容器挂载了 /opt/jenkins_home:/var/jenkins_home
# 在宿主机上查看私钥(根据实际密钥名称选择)

# 如果使用默认名称 id_rsa
cat /opt/jenkins_home/.ssh/id_rsa

# 如果使用自定义名称 jenkins_rsa
cat /opt/jenkins_home/.ssh/jenkins_rsa

# 或者从容器内查看
docker exec jenkins cat ~/.ssh/jenkins_rsa

步骤2: 在目标服务器部署 MySQL

在目标服务器(192.168.30.130)上执行:

注意: 如果目标服务器上还没有 MySQL Docker 镜像,需要先拉取镜像。docker run 命令会自动拉取镜像,但建议先手动拉取以验证网络连接。

2.1 创建数据目录和配置

bash
# 创建 MySQL 数据目录
mkdir -p /data/mysql/data
mkdir -p /data/mysql/conf
mkdir -p /data/mysql/init

# 创建 MySQL 配置文件
cat > /data/mysql/conf/my.cnf << 'EOF'
[mysqld]
# 基础配置
port=3306
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
pid-file=/var/run/mysqld/mysqld.pid

# 字符集配置
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

# 认证方式(兼容旧客户端)
default-authentication-plugin=mysql_native_password

# 大小写不敏感
lower_case_table_names=1

# 时间配置
explicit_defaults_for_timestamp=true

# 连接配置
max_connections=500
max_connect_errors=1000

# 缓存配置
innodb_buffer_pool_size=512M
innodb_log_file_size=256M

# 日志配置
slow_query_log=1
slow_query_log_file=/var/lib/mysql/slow.log
long_query_time=2

[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4
EOF

2.2 配置 Docker 镜像加速器(推荐)

如果无法从 Docker Hub 拉取镜像,建议先配置国内镜像加速器:

在目标服务器(192.168.30.130)上执行:

bash
# 创建或编辑 Docker daemon 配置文件
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}
EOF

# 重新加载 Docker 配置
systemctl daemon-reload
systemctl restart docker

# 验证配置是否生效
docker info | grep -A 10 "Registry Mirrors"

说明:

  • 配置镜像加速器后,docker pull 命令会自动使用加速器
  • 如果某个镜像源不可用,Docker 会自动尝试下一个
  • 配置后需要重启 Docker 服务

2.3 拉取 MySQL 镜像

在目标服务器(192.168.30.130)上执行:

方式1: 使用镜像加速器拉取(推荐)

bash
# 配置镜像加速器后,直接拉取官方镜像
docker pull mysql:8.0.33

# 验证镜像是否拉取成功
docker images | grep mysql

方式2: 使用国内镜像源(如果方式1失败)

bash
# 使用华为云镜像源
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/mysql:8.0.33
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/mysql:8.0.33 mysql:8.0.33

# 使用阿里云镜像源(需要先登录,或使用公开镜像)
docker pull registry.cn-hangzhou.aliyuncs.com/library/mysql:8.0.33
docker tag registry.cn-hangzhou.aliyuncs.com/library/mysql:8.0.33 mysql:8.0.33

# 或使用网易镜像源
docker pull hub.c.163.com/library/mysql:8.0.33
docker tag hub.c.163.com/library/mysql:8.0.33 mysql:8.0.33

# 或使用腾讯云镜像源
docker pull ccr.ccs.tencentyun.com/library/mysql:8.0.33
docker tag ccr.ccs.tencentyun.com/library/mysql:8.0.33 mysql:8.0.33

方式3: 手动下载镜像文件(如果网络完全不通)

bash
# 在有网络的机器上下载镜像并导出
# docker pull mysql:8.0.33
# docker save mysql:8.0.33 -o mysql-8.0.33.tar

# 传输到目标服务器后导入
# scp mysql-8.0.33.tar root@192.168.30.130:/tmp/
# docker load -i /tmp/mysql-8.0.33.tar

说明:

  • 如果本地已有 MySQL 镜像,可以跳过此步骤
  • docker run 命令执行时,如果本地没有镜像会自动拉取,但先拉取可以提前验证网络连接
  • 镜像大小约 500MB,根据网络速度可能需要几分钟

2.4 启动 MySQL 容器

bash
docker run -d \
  --name mysql \
  --restart always \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD='Admin$123!' \
  -e MYSQL_DATABASE=ruoyi-office \
  -v /data/mysql/data:/var/lib/mysql \
  -v /data/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf \
  -v /data/mysql/init:/docker-entrypoint-initdb.d \
  mysql:8.0.33

重要: 请将 Admin$123! 替换为您的强密码。

说明:

  • 如果本地没有 MySQL 镜像,docker run 会自动拉取,但可能需要较长时间
  • 建议先执行 docker pull 确保镜像下载成功

2.5 验证 MySQL 启动

bash
# 等待容器启动(约 30 秒)
sleep 30

# 检查容器状态
docker ps | grep mysql

# 测试连接(密码包含特殊字符时使用单引号)
docker exec -it mysql mysql -uroot -p'YourStrongPassword123!' -e "SELECT VERSION();"

# 查看数据库
docker exec -it mysql mysql -uroot -p'YourStrongPassword123!' -e "SHOW DATABASES;"

步骤3: 在目标服务器部署 Redis

在目标服务器(192.168.30.130)上执行:

注意: 如果目标服务器上还没有 Redis Docker 镜像,需要先拉取镜像。docker run 命令会自动拉取镜像,但建议先手动拉取以验证网络连接。

3.1 创建 Redis 数据目录和配置

bash
# 创建 Redis 数据目录
mkdir -p /data/redis/data
mkdir -p /data/redis/conf

# 创建 Redis 配置文件
cat > /data/redis/conf/redis.conf << 'EOF'
# 绑定地址(允许所有IP访问,生产环境建议限制)
bind 0.0.0.0

# 端口
port 6379

# 密码(生产环境强烈建议设置)
# requirepass YourRedisPassword123!

# 持久化配置
appendonly yes
appendfsync everysec

# 内存限制(根据服务器内存调整)
maxmemory 512mb
maxmemory-policy allkeys-lru

# 日志级别
loglevel notice

# 数据目录
dir /data

# 后台运行(Docker 中不需要)
daemonize no

# 超时配置
timeout 300
tcp-keepalive 300
EOF

3.2 拉取 Redis 镜像

在目标服务器(192.168.30.130)上执行:

注意: 如果已在步骤 2.2 配置了 Docker 镜像加速器,可以直接使用方式1。如果未配置或方式1失败,请使用方式2。

方式1: 使用镜像加速器拉取(推荐)

bash
# 如果已配置镜像加速器,直接拉取官方镜像
docker pull redis:7.2
docker pull swr.cn-south-1.myhuaweicloud.com/library/redis:latest
docker tag swr.cn-south-1.myhuaweicloud.com/library/redis:latest redis:latest


# 验证镜像是否拉取成功
docker images | grep redis

方式2: 使用国内镜像源(如果方式1失败)

bash
# 使用阿里云镜像源
docker pull registry.cn-hangzhou.aliyuncs.com/library/redis:7.2
docker tag registry.cn-hangzhou.aliyuncs.com/library/redis:7.2 redis:7.2

# 或使用网易镜像源
docker pull hub.c.163.com/library/redis:7.2
docker tag hub.c.163.com/library/redis:7.2 redis:7.2

# 或使用腾讯云镜像源
docker pull ccr.ccs.tencentyun.com/library/redis:7.2
docker tag ccr.ccs.tencentyun.com/library/redis:7.2 redis:7.2

方式3: 手动下载镜像文件(如果网络完全不通)

bash
# 在有网络的机器上下载镜像并导出
# docker pull redis:7.2
# docker save redis:7.2 -o redis-7.2.tar

# 传输到目标服务器后导入
# scp redis-7.2.tar root@192.168.30.130:/tmp/
# docker load -i /tmp/redis-7.2.tar

说明:

  • 如果本地已有 Redis 镜像,可以跳过此步骤
  • docker run 命令执行时,如果本地没有镜像会自动拉取,但先拉取可以提前验证网络连接
  • 镜像大小约 100MB,根据网络速度可能需要几分钟

3.3 启动 Redis 容器

bash
docker run -d \
  --name redis \
  --restart always \
  -p 6379:6379 \
  -v /data/redis/data:/data \
  -v /data/redis/conf/redis.conf:/etc/redis/redis.conf \
  redis:latest \
  redis-server /etc/redis/redis.conf

说明:

  • 如果本地没有 Redis 镜像,docker run 会自动拉取,但可能需要较长时间
  • 建议先执行 docker pull 确保镜像下载成功

3.4 验证 Redis 启动

bash
# 检查容器状态
docker ps | grep redis

# 测试连接
docker exec -it redis redis-cli ping
# 应该返回 PONG

# 测试读写
docker exec -it redis redis-cli SET test "Hello Redis"
docker exec -it redis redis-cli GET test

步骤4: 初始化数据库

4.1 上传 SQL 脚本

将项目中的 SQL 脚本上传到目标服务器:

bash
# 在本地执行(将 SQL 文件上传到目标服务器)
scp ruoyi-office/sql/mysql/ruoyi-vue-pro.sql root@192.168.30.130:/data/mysql/init/
scp ruoyi-office/sql/mysql/quartz.sql root@192.168.30.130:/data/mysql/init/

# 如果有其他业务 SQL,也需要上传
# scp ruoyi-office/sql/mysql/*.sql root@192.168.30.130:/data/mysql/init/

4.2 执行 SQL 脚本

bash
# 在目标服务器上执行
# 导入主数据库脚本(密码包含特殊字符时使用单引号)
docker exec -i mysql mysql -uroot -p'Admin$123!' ruoyi-office < /data/mysql/init/dump-ruoyi-office-202601221629.sql
docker exec -i mysql mysql -uroot -p'YourStrongPassword123!' ruoyi-office < /data/mysql/init/ruoyi-vue-pro.sql

# 导入 Quartz 调度表(如果使用定时任务)
docker exec -i mysql mysql -uroot -p'YourStrongPassword123!' ruoyi-office < /data/mysql/init/quartz.sql

4.3 验证数据库初始化

bash
# 查看表数量(密码包含特殊字符时使用单引号)
docker exec -it mysql mysql -uroot -p'Admin$123!' -e "USE ruoyi-office; SHOW TABLES;" | wc -l

# 查看系统用户表
docker exec -it mysql mysql -uroot -p'Admin$123!' -e "USE ruoyi-office; SELECT id, username FROM system_users LIMIT 5;"

步骤5: 配置 Jenkins

5.1 安装必要插件

进入 Jenkins管理 -> 插件管理 -> 可选插件,安装以下插件:

  1. Maven Integration Plugin - Maven 构建支持
  2. SSH Agent Plugin - SSH 连接支持
  3. Publish Over SSH - 文件传输(可选,推荐)

安装后重启 Jenkins:

bash
docker restart jenkins

5.2 配置 JDK 工具

方式1: 使用 Adoptium (Eclipse Temurin) - 推荐

如果 Jenkins 支持 Install from adoptium.net 选项:

  1. 进入 Jenkins管理 -> 全局工具配置
  2. 找到 JDK 部分,点击 新增JDK
  3. 配置:
    • 名称: jdk17
    • JAVA_HOME: 留空(自动安装)
    • 勾选 自动安装
    • 选择 Install from adoptium.net -> jdk-17.x

如果看不到 Install from adoptium.net 选项,请使用方式2或方式3。

方式2: 手动指定 JDK 路径(推荐,最可靠)

如果 Jenkins 不支持自动安装或只能选择到 JDK 9,可以手动安装 JDK 17 后指定路径:

步骤1: 在 Jenkins 容器中安装 JDK 17

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

# 下载并安装 OpenJDK 17(Adoptium)
cd /tmp

# 方式1: 使用清华大学镜像源(推荐,速度快)
wget https://mirrors.tuna.tsinghua.edu.cn/AdoptOpenJDK/17/jdk/x64/linux/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz

curl -O https://mirrors.tuna.tsinghua.edu.cn/Adoptium/17/jdk/x64/linux/OpenJDK17U-jdk_x64_linux_hotspot_17.0.17_10.tar.gz

# 方式2: 使用华为云镜像源(备选)
# wget https://mirrors.huaweicloud.com/java/jdk/17.0.13+11/jdk-17.0.13_linux-x64_bin.tar.gz

# 方式3: 使用腾讯云镜像源(备选)
# wget https://mirrors.cloud.tencent.com/AdoptOpenJDK/17/jdk/x64/linux/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz

# 方式4: 如果国内镜像源都不可用,使用官方源(较慢)
# wget https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.13%2B11/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz

# 如果 wget 不可用,使用 curl(替换上面的 wget 命令)
# curl -L -o OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz https://mirrors.tuna.tsinghua.edu.cn/AdoptOpenJDK/17/jdk/x64/linux/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz
# curl -L -o OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz https://mirrors.cloud.tencent.com/AdoptOpenJDK/17/jdk/x64/linux/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz



# 解压
tar -xzf OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz

# 移动到 /opt 目录
mv jdk-17.0.13+11 /opt/jdk17

# 没权限切换root mv
docker exec -u root -it jenkins bash


# 验证安装
/opt/jdk17/bin/java -version

# 退出容器
exit

步骤2: 在 Jenkins 中配置 JDK 路径

  1. 进入 Jenkins管理 -> 全局工具配置
  2. 找到 JDK 部分,点击 新增JDK
  3. 配置:
    • 名称: jdk17
    • JAVA_HOME: /opt/jdk17(手动输入路径)
    • 不要勾选 自动安装
  4. 点击 保存

方式3: 在宿主机安装 JDK 17,挂载到容器

如果不想在容器内安装,可以在宿主机安装后挂载:

步骤1: 在宿主机安装 JDK 17

bash
# 在 Jenkins 服务器(140)的宿主机上执行
cd /opt

# 使用清华大学镜像源(推荐)
wget https://mirrors.tuna.tsinghua.edu.cn/AdoptOpenJDK/17/jdk/x64/linux/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz

# 或使用华为云镜像源
# wget https://mirrors.huaweicloud.com/java/jdk/17.0.13+11/jdk-17.0.13_linux-x64_bin.tar.gz

# 或使用腾讯云镜像源
# wget https://mirrors.cloud.tencent.com/AdoptOpenJDK/17/jdk/x64/linux/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz

# 解压并安装
tar -xzf OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz
mv jdk-17.0.13+11 /opt/jdk17

# 验证安装
/opt/jdk17/bin/java -version

步骤2: 修改 Jenkins 容器启动命令,挂载 JDK

bash
# 停止并删除现有容器
docker stop jenkins
docker rm jenkins

# 使用新命令启动(添加 JDK 挂载)
docker run --restart always \
  --network jenkins \
  --name jenkins \
  -d -p 8080:8080 -p 50000:50000 \
  -v /opt/jenkins_home:/var/jenkins_home \
  -v /opt/jdk17:/opt/jdk17 \
  jenkins/jenkins

# 等待容器启动
sleep 10

步骤3: 在 Jenkins 中配置 JDK 路径

  1. 进入 Jenkins管理 -> 全局工具配置
  2. 找到 JDK 部分,点击 新增JDK
  3. 配置:
    • 名称: jdk17
    • JAVA_HOME: /opt/jdk17
    • 不要勾选 自动安装
  4. 点击 保存

方式4: 更新 Jenkins JDK Plugin(如果版本较旧)

如果 Jenkins 版本较旧,可能需要更新插件:

  1. 进入 Jenkins管理 -> 插件管理 -> 已安装
  2. 搜索 JDK Tool Plugin
  3. 如果有更新,点击更新
  4. 重启 Jenkins: docker restart jenkins
  5. 重新尝试方式1

推荐: 使用方式2(在容器内手动安装),最简单可靠。

5.3 配置 Maven 工具

  1. 全局工具配置 中找到 Maven 部分
  2. 点击 新增Maven
  3. 配置:
    • 名称: maven3
    • 勾选 自动安装
    • 选择版本 3.9.x 或更高

5.4 配置 SSH 凭据

  1. 进入 Jenkins管理 -> 凭据管理 -> 系统 -> 全局凭据
  2. 点击 添加凭据
  3. 配置:
    • 类型: SSH Username with private key
    • ID: server-130-ssh
    • 描述: 目标服务器130 SSH凭据
    • 用户名: root
    • 私钥: 选择 Enter directly,粘贴步骤1中获取的私钥内容

私钥格式要求

  • 必须包含完整的 -----BEGIN ... PRIVATE KEY----------END ... PRIVATE KEY-----
  • 行之间不能有空行
  • 建议使用 cat /opt/jenkins_home/.ssh/id_rsa | grep -v '^$' 获取无空行的私钥

5.5 配置 Publish Over SSH(推荐)

  1. 进入 Jenkins管理 -> 系统配置

  2. 找到 Publish over SSH 部分

  3. 点击 新增,配置:

    • Name: server-130
    • Hostname: 192.168.30.130
    • Username: root
    • Remote Directory: /data/app
    • Use password authentication, or use a different key: 勾选
    • Key: 粘贴私钥内容
  4. 点击 Test Configuration 验证连接

  5. 点击 保存

步骤6: 创建应用部署目录

在目标服务器(192.168.30.130)上执行:

bash
# 创建应用目录
mkdir -p /data/app/yudao-server
mkdir -p /data/app/logs

# 设置权限
chmod 755 /data/app/yudao-server
chmod 755 /data/app/logs

步骤7: 创建 Jenkins Pipeline 任务

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

步骤8: 执行首次部署

  1. 在 Jenkins 任务页面,点击 立即构建
  2. 查看构建日志,确认各阶段正常:
    • ✅ 拉取代码
    • ✅ Maven 构建
    • ✅ 传输 JAR 文件
    • ✅ 构建 Docker 镜像
    • ✅ 启动容器
    • ✅ 健康检查

步骤9: 验证部署

9.1 检查容器状态

bash
# 在目标服务器上执行
docker ps | grep yudao-server

# 查看容器日志
docker logs -f yudao-server --tail 100

9.2 访问 API 接口

bash
# 健康检查
curl http://192.168.30.130:48080/actuator/health

# 访问 Swagger 文档
# 浏览器打开: http://192.168.30.130:48080/swagger-ui/index.html

# 测试登录接口
curl -X POST http://192.168.30.130:48080/admin-api/system/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}'

9.3 检查日志

bash
# 查看应用日志
docker logs yudao-server --tail 200

# 查看持久化日志(如果配置了)
tail -f /data/app/logs/yudao-server.log

故障排查

SSH 免密登录失败

问题: 执行 ssh root@192.168.30.130 时仍然需要输入密码

原因: SSH 免密登录配置未成功,可能的原因:

  1. 公钥未正确复制到目标服务器
  2. 目标服务器文件权限不正确
  3. SSH 服务配置禁用了公钥认证
  4. 公钥格式错误

排查步骤:

步骤1: 检查公钥是否已复制

bash
# 在 Jenkins 容器中查看公钥
docker exec -it jenkins cat ~/.ssh/id_rsa.pub

# 在目标服务器上检查 authorized_keys
ssh root@192.168.30.130 "cat ~/.ssh/authorized_keys"

如果 authorized_keys 为空或不存在,手动复制:

bash
# 在 Jenkins 容器中执行
docker exec -it jenkins bash
cat ~/.ssh/id_rsa.pub | ssh root@192.168.30.130 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

步骤2: 检查目标服务器权限

在目标服务器(130)上执行:

bash
# 检查并修复权限
ls -ld ~/.ssh
chmod 700 ~/.ssh

ls -l ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chown root:root ~/.ssh/authorized_keys

正确的权限应该是:

drwx------  root root  .ssh
-rw-------  root root  .ssh/authorized_keys

步骤3: 检查 SSH 服务配置

在目标服务器(130)上执行:

bash
# 检查 SSH 配置
grep -E "^PubkeyAuthentication|^AuthorizedKeysFile|^PasswordAuthentication" /etc/ssh/sshd_config

# 应该看到:
# PubkeyAuthentication yes
# AuthorizedKeysFile .ssh/authorized_keys

# 如果 PubkeyAuthentication 是 no,修改并重启
sed -i 's/^PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sed -i 's/^#PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
systemctl restart sshd

步骤4: 使用详细模式诊断

bash
# 在 Jenkins 容器中执行,查看详细连接信息
docker exec -it jenkins ssh -v root@192.168.30.130 'echo "test"'

# 查看关键信息:
# - debug1: Offering public key - 说明正在尝试使用公钥
# - debug1: Server accepts key - 说明服务器接受了公钥
# - Permission denied (publickey) - 说明公钥认证失败

步骤5: 验证免密登录

bash
# 在 Jenkins 容器中测试(应该不需要输入密码)
docker exec -it jenkins ssh -o StrictHostKeyChecking=no root@192.168.30.130 'echo "SSH免密登录成功"'

常见错误及解决方案:

错误信息原因解决方案
Permission denied (publickey)公钥未配置或权限错误检查 authorized_keys 和文件权限
Host key verification failed首次连接需要确认主机密钥使用 -o StrictHostKeyChecking=no
Could not resolve hostname网络不通或 DNS 问题检查网络连接和 hosts 文件
Connection refusedSSH 服务未运行检查 systemctl status sshd

Docker 镜像拉取失败

问题: 执行 docker pull 时出现网络错误,无法拉取镜像

常见错误:

  • read tcp: connection reset by peer - 网络连接被重置
  • manifest unknown - 镜像不存在或路径错误
  • Get "https://registry-1.docker.io/v2/": net/http: TLS handshake timeout - 网络超时

解决方案:

方案1: 配置 Docker 镜像加速器(推荐)

bash
# 创建或编辑 Docker daemon 配置文件
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}
EOF

# 重新加载并重启 Docker
systemctl daemon-reload
systemctl restart docker

# 验证配置
docker info | grep -A 10 "Registry Mirrors"

方案2: 使用国内镜像源直接拉取

bash
# MySQL 镜像
docker pull registry.cn-hangzhou.aliyuncs.com/library/mysql:8.0.33
docker tag registry.cn-hangzhou.aliyuncs.com/library/mysql:8.0.33 mysql:8.0.33

# Redis 镜像
docker pull registry.cn-hangzhou.aliyuncs.com/library/redis:7.2
docker tag registry.cn-hangzhou.aliyuncs.com/library/redis:7.2 redis:7.2

其他可用的镜像源:

镜像源MySQL 路径Redis 路径
阿里云registry.cn-hangzhou.aliyuncs.com/library/mysql:8.0.33registry.cn-hangzhou.aliyuncs.com/library/redis:7.2
网易hub.c.163.com/library/mysql:8.0.33hub.c.163.com/library/redis:7.2
腾讯云ccr.ccs.tencentyun.com/library/mysql:8.0.33ccr.ccs.tencentyun.com/library/redis:7.2
中科大docker.mirrors.ustc.edu.cn/library/mysql:8.0.33docker.mirrors.ustc.edu.cn/library/redis:7.2

方案3: 手动导入镜像(网络完全不通时)

bash
# 在有网络的机器上导出镜像
docker pull mysql:8.0.33
docker save mysql:8.0.33 -o mysql-8.0.33.tar

docker pull redis:7.2
docker save redis:7.2 -o redis-7.2.tar

# 传输到目标服务器
scp mysql-8.0.33.tar redis-7.2.tar root@192.168.30.130:/tmp/

# 在目标服务器上导入
docker load -i /tmp/mysql-8.0.33.tar
docker load -i /tmp/redis-7.2.tar

方案4: 检查网络和防火墙

bash
# 测试网络连接
ping registry-1.docker.io
ping docker.mirrors.ustc.edu.cn

# 检查防火墙规则
firewall-cmd --list-all
iptables -L -n

# 如果需要,临时关闭防火墙测试
systemctl stop firewalld
# 测试完成后记得重新开启
systemctl start firewalld

推荐顺序: 先尝试方案1(配置镜像加速器),如果失败再尝试方案2(直接使用国内镜像源)。

Docker 构建时基础镜像拉取失败

问题: 构建应用镜像时,无法拉取基础镜像 eclipse-temurin:21-jre

错误信息:

ERROR: failed to do request: Head "https://docker.mirrors.ustc.edu.cn/v2/library/eclipse-temurin/manifests/21-jre?ns=docker.io": 
dial tcp: lookup docker.mirrors.ustc.edu.cn on 114.114.114.114:53: no such host

原因:

  1. DNS 解析失败
  2. 镜像加速器配置问题
  3. 基础镜像不在镜像加速器的缓存中

解决方案:

方案1: 在目标服务器上手动拉取基础镜像(推荐)

在目标服务器(130)上执行:

使用不需要登录的公共镜像源(推荐):

bash
docker pull docker.xuanyuan.run/library/eclipse-temurin:21-jre

# 方式1: 使用中科大镜像源(推荐,不需要登录)
docker pull docker.mirrors.ustc.edu.cn/library/eclipse-temurin:21-jre
docker tag docker.mirrors.ustc.edu.cn/library/eclipse-temurin:21-jre eclipse-temurin:21-jre

# 方式2: 使用网易镜像源(备选)
docker pull hub.c.163.com/library/eclipse-temurin:21-jre
docker tag hub.c.163.com/library/eclipse-temurin:21-jre eclipse-temurin:21-jre

# 方式3: 使用腾讯云镜像源(备选)
docker pull ccr.ccs.tencentyun.com/library/eclipse-temurin:21-jre
docker tag ccr.ccs.tencentyun.com/library/eclipse-temurin:21-jre eclipse-temurin:21-jre

# 验证
docker images | grep eclipse-temurin

如果镜像源需要登录(如 xxx.xuanyuan.run):

bash
# 1. 先登录镜像仓库
docker login xxx.xuanyuan.run
# 输入用户名和密码

# 2. 拉取镜像
docker pull xxx.xuanyuan.run/library/eclipse-temurin:21-jre
docker tag xxx.xuanyuan.run/library/eclipse-temurin:21-jre eclipse-temurin:21-jre

# 3. 验证
docker images | grep eclipse-temurin

注意: 如果镜像源需要登录但您没有账号,建议使用不需要登录的公共镜像源(中科大、网易、腾讯云等)。

方案2: 修改 Dockerfile 使用国内镜像源(如果方案1失败)

修改 yudao-server/Dockerfile

dockerfile
# 使用国内镜像源的基础镜像
FROM docker.mirrors.ustc.edu.cn/library/eclipse-temurin:21-jre

# 或者使用网易镜像源
# FROM hub.c.163.com/library/eclipse-temurin:21-jre

注意: 这种方式需要修改代码,如果镜像源地址变更需要再次修改。

方案3: 检查并修复 DNS 配置

如果出现 no such host 错误,可能是 DNS 配置问题:

bash
# 检查 DNS 配置
cat /etc/resolv.conf

# 临时修改 DNS(如果当前 DNS 不可用)
echo "nameserver 8.8.8.8" > /etc/resolv.conf
echo "nameserver 114.114.114.114" >> /etc/resolv.conf

# 测试 DNS 解析
nslookup docker.mirrors.ustc.edu.cn
ping docker.mirrors.ustc.edu.cn

方案4: 使用 Jenkinsfile 自动拉取(已更新)

Jenkinsfile 已更新,会在构建镜像前自动拉取基础镜像。如果仍然失败,请先手动执行方案1。

推荐: 使用方案1,在目标服务器上手动拉取基础镜像,这是最可靠的方法。

密码包含特殊字符的处理

问题: 如果密码包含特殊字符(如 !$& 等),bash 可能会进行历史扩展或命令替换,导致命令执行失败。

解决方案:

  1. 在命令行中使用单引号包裹密码:

    bash
    # 错误示例(感叹号会被 bash 解释)
    docker exec -it mysql mysql -uroot -pYourStrongPassword123! -e "SELECT 1;"
    
    # 正确示例(使用单引号)
    docker exec -it mysql mysql -uroot -p'YourStrongPassword123!' -e "SELECT 1;"
  2. 在 Docker 环境变量中使用单引号:

    bash
    # 错误示例
    -e MYSQL_ROOT_PASSWORD=YourStrongPassword123!
    
    # 正确示例
    -e MYSQL_ROOT_PASSWORD='YourStrongPassword123!'
  3. 在 SSH 命令中使用单引号包裹整个命令:

    bash
    # 错误示例(感叹号会被 bash 解释)
    ssh root@192.168.30.130 "echo 'SSH连接成功!'"
    
    # 正确示例(使用单引号包裹整个命令)
    ssh root@192.168.30.130 'echo "SSH连接成功"'
  4. 或者使用 -p 参数后不跟密码(会提示输入):

    bash
    # 交互式输入密码(最安全)
    docker exec -it mysql mysql -uroot -p -e "SELECT 1;"

MySQL 连接失败

问题: 应用无法连接 MySQL

排查步骤:

bash
# 1. 检查 MySQL 容器状态
docker ps | grep mysql
docker logs mysql --tail 50

# 2. 检查网络连通性
docker exec yudao-server ping mysql -c 3

# 3. 检查数据库用户权限(密码包含特殊字符时使用单引号)
docker exec -it mysql mysql -uroot -p'YourStrongPassword123!' -e "SELECT user, host FROM mysql.user;"

# 4. 检查防火墙
firewall-cmd --list-ports

解决方案:

bash
# 如果需要允许远程连接(密码包含特殊字符时使用单引号)
docker exec -it mysql mysql -uroot -p'YourStrongPassword123!' -e "
CREATE USER 'root'@'%' IDENTIFIED BY 'YourStrongPassword123!';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
"

Redis 连接失败

问题: 应用无法连接 Redis

排查步骤:

bash
# 1. 检查 Redis 容器状态
docker ps | grep redis
docker logs redis --tail 50

# 2. 测试 Redis 连接
docker exec -it redis redis-cli ping

# 3. 检查 Redis 配置
docker exec -it redis cat /etc/redis/redis.conf | grep -E "bind|port|requirepass"

应用启动失败

问题: yudao-server 容器启动后立即退出

排查步骤:

bash
# 1. 查看容器日志
docker logs yudao-server

# 2. 检查 JVM 参数
docker inspect yudao-server | grep -A 10 "Env"

# 3. 检查内存
free -h
docker stats --no-stream

# 4. 尝试交互式启动排查
docker run -it --rm \
  -e "SPRING_PROFILES_ACTIVE=prod" \
  yudao-server:latest \
  java -jar app.jar

端口被占用

问题: 端口 48080 已被占用

解决方案:

bash
# 查看端口占用
netstat -tlnp | grep 48080
lsof -i :48080

# 停止占用端口的进程
kill -9 <PID>

# 或修改应用端口
docker run -d -p 48081:48080 ...

内存不足

问题: 应用因 OOM 被 Kill

解决方案:

bash
# 1. 检查服务器内存
free -h

# 2. 调整 JVM 参数(在 docker run 时)
docker run -d \
  -e "JAVA_OPTS=-Xms256m -Xmx512m" \
  ...

# 3. 调整 Docker 内存限制
docker run -d \
  --memory=1g \
  --memory-swap=2g \
  ...

后续维护

自动触发部署

配置 Git Webhook 实现代码推送自动部署:

  1. 在 Git 仓库设置中添加 Webhook
  2. Webhook URL: http://192.168.30.140:8080/job/ruoyi-office-backend-deploy/build
  3. 触发事件: Push events

手动触发部署

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

查看部署历史

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

数据库备份

bash
# 备份数据库(密码包含特殊字符时使用单引号)
docker exec mysql mysqldump -uroot -p'YourStrongPassword123!' ruoyi-office > /data/backup/ruoyi-office_$(date +%Y%m%d).sql

# 定时备份(添加到 crontab,密码使用单引号包裹)
0 2 * * * docker exec mysql mysqldump -uroot -p'YourStrongPassword123!' ruoyi-office > /data/backup/ruoyi-office_$(date +\%Y\%m\%d).sql

日志清理

bash
# 清理 30 天前的日志
find /data/app/logs -name "*.log" -mtime +30 -delete

# 清理 Docker 日志
docker system prune -f

配置文件说明

文件说明
yudao-server/JenkinsfileJenkins Pipeline 配置
yudao-server/DockerfileDocker 镜像构建配置
yudao-server/src/main/resources/application-prod.yaml生产环境配置
yudao-server/docker-compose.ymlDocker 编排配置(可选)

安全建议

  1. 数据库密码: 使用强密码,不要使用默认密码
  2. Redis 密码: 生产环境建议设置 Redis 密码
  3. 防火墙: 只开放必要端口(48080),数据库端口不对外开放
  4. HTTPS: 建议配置 HTTPS 访问
  5. 日志脱敏: 敏感信息不要打印到日志
  6. 定期更新: 定期更新 Docker 镜像和依赖

性能优化

JVM 参数优化

根据服务器内存调整:

服务器内存推荐 JVM 参数
2GB-Xms256m -Xmx512m
4GB-Xms512m -Xmx1024m
8GB-Xms1g -Xmx2g
16GB-Xms2g -Xmx4g

MySQL 优化

bash
# 根据服务器内存调整 innodb_buffer_pool_size
# 建议设置为总内存的 50-70%

Redis 优化

bash
# 根据数据量调整 maxmemory
# 建议设置为总内存的 10-20%

常见问题

Q: 如何回滚到上一个版本?

bash
# 1. 查看可用镜像
docker images | grep yudao-server

# 2. 停止当前容器
docker stop yudao-server
docker rm yudao-server

# 3. 使用上一个版本的镜像启动
docker run -d --name yudao-server ... yudao-server:previous_tag

Q: 如何查看应用配置?

bash
# 查看激活的配置文件
docker exec yudao-server env | grep SPRING_PROFILES_ACTIVE

# 查看 actuator 配置信息
curl http://192.168.30.130:48080/actuator/env

Q: 如何修改配置不重新构建?

bash
# 1. 挂载外部配置文件
docker run -d \
  -v /data/app/config/application-prod.yaml:/yudao-server/config/application-prod.yaml \
  ...

# 2. 使用环境变量覆盖
docker run -d \
  -e "SPRING_DATASOURCE_URL=jdbc:mysql://..." \
  ...

快速参考

常用命令

bash
# 查看所有容器
docker ps -a

# 重启应用
docker restart yudao-server

# 查看日志
docker logs -f yudao-server --tail 100

# 进入容器
docker exec -it yudao-server bash

# 查看资源使用
docker stats

服务地址

服务地址
后端 APIhttp://192.168.30.130:48080
Swagger 文档http://192.168.30.130:48080/swagger-ui/index.html
Druid 监控http://192.168.30.130:48080/druid
Actuatorhttp://192.168.30.130:48080/actuator

默认账号

账号密码说明
adminadmin123超级管理员
联系我们

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

微信咨询二维码

微信咨询

17156169080

添加时备注「RuoYi Office」

在线体验商业版