SpringBoot + Vue 项目生产环境部署完整指南

SpringBoot + Vue 项目生产环境部署完整指南

基于本次实际部署经验总结,适用于 Ubuntu 24.04 服务器


一、服务器环境准备

1.1 安装基础软件

bash 复制代码
# 更新包列表
sudo apt update

# 安装 JDK 17
sudo apt install openjdk-17-jdk -y
java -version  # 验证安装

# 安装 MySQL 8.0
sudo apt install mysql-server -y
sudo systemctl start mysql
sudo systemctl enable mysql

# 安装 Redis
sudo apt install redis-server -y
sudo systemctl start redis
sudo systemctl enable redis

# 安装 Nginx
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

1.2 创建项目目录结构

bash 复制代码
# 创建项目根目录
mkdir -p /opt/ipam

# 创建子目录
mkdir -p /opt/ipam/backend          # 后端 jar 包
mkdir -p /opt/ipam/frontend         # 前端 dist 文件
mkdir -p /opt/ipam/config           # 配置文件
mkdir -p /opt/ipam/logs             # 日志文件
mkdir -p /opt/ipam/uploadPath       # 文件上传目录(根据项目需要)
mkdir -p /opt/ipam/sql              # SQL 脚本

二、数据库部署

2.1 登录 MySQL

bash 复制代码
# 首次安装无密码,直接登录
sudo mysql

2.2 创建数据库和用户

sql 复制代码
-- 创建数据库(注意:带短横线的名称需要反引号)
CREATE DATABASE IF NOT EXISTS `zy-ipam` 
  CHARACTER SET utf8mb4 
  COLLATE utf8mb4_unicode_ci;

-- 创建用户(用户名用下划线,密码自定义)
CREATE USER 'zy_ipam'@'localhost' IDENTIFIED BY '123456';

-- 授权
GRANT ALL PRIVILEGES ON `zy-ipam`.* TO 'zy_ipam'@'localhost';

-- 刷新权限
FLUSH PRIVILEGES;

-- 退出
EXIT;

2.3 导入 SQL 数据

bash 复制代码
# 将 SQL 文件上传到 /opt/ipam/sql/ 后执行
cd /opt/ipam/sql
mysql -u zy_ipam -p123456 `zy-ipam` < zy-ipam.sql

2.4 验证数据库

bash 复制代码
mysql -u zy_ipam -p123456 -e "USE \`zy-ipam\`; SHOW TABLES;"

三、后端部署

3.1 上传 jar 包

bash 复制代码
# 将 jar 包上传到 /opt/ipam/backend/
# 示例文件:zy-admin.jar

3.2 创建配置文件 application-prod.yml

文件位置: /opt/ipam/config/application-prod.yml

yaml 复制代码
# 生产环境配置

# 服务器配置
server:
  port: 8080
  servlet:
    context-path: /
  tomcat:
    uri-encoding: UTF-8
    accept-count: 1000
    threads:
      max: 800
      min-spare: 100

# 日志配置
logging:
  level:
    com.zy: info
    org.springframework: warn

# 数据源配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      master:
        # 数据库名带短横线,URL 中直接写
        url: jdbc:mysql://localhost:3306/zy-ipam?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: zy_ipam
        password: 123456
      slave:
        enabled: false
      initialSize: 5
      minIdle: 10
      maxActive: 20
      maxWait: 60000
      connectTimeout: 30000
      socketTimeout: 60000
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      maxEvictableIdleTimeMillis: 900000
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        allow: 
        url-pattern: /druid/*
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true

  # Redis 配置
  data:
    redis:
      host: localhost
      port: 6379
      database: 0
      password:
      timeout: 10s
      lettuce:
        pool:
          min-idle: 0
          max-idle: 8
          max-active: 8
          max-wait: -1ms

# Token 配置
token:
  header: Authorization
  secret: abcdefghijklmnopqrstuvwxyz
  expireTime: 30

# MyBatis 配置
mybatis:
  typeAliasesPackage: com.zy.**.domain
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  configLocation: classpath:mybatis/mybatis-config.xml

# PageHelper 分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql

# 项目相关配置
ipam:
  name: zy-ipam
  version: 3.9.2
  copyrightYear: 2026
  profile: /opt/ipam/uploadPath   # 文件上传路径
  addressEnabled: false
  captchaType: math

3.3 后端启动脚本 start.sh

文件位置: /opt/ipam/backend/start.sh

bash 复制代码
#!/bin/bash

# 项目根目录
PROJECT_DIR="/opt/ipam"

# 进入后端目录
cd $PROJECT_DIR/backend

# 停止旧进程
pkill -f zy-admin.jar

# 清理旧日志(可选)
> $PROJECT_DIR/logs/backend.log

# 启动后端
nohup java -jar zy-admin.jar \
  --spring.profiles.active=prod \
  --spring.config.location=file:$PROJECT_DIR/config/ \
  > $PROJECT_DIR/logs/backend.log 2>&1 &

# 等待启动
sleep 3

# 检查进程
if ps aux | grep -v grep | grep zy-admin.jar > /dev/null; then
    echo "✅ 后端启动成功!PID: $(pgrep -f zy-admin.jar)"
    echo "📋 查看日志: tail -f $PROJECT_DIR/logs/backend.log"
else
    echo "❌ 后端启动失败,请查看日志"
    tail -20 $PROJECT_DIR/logs/backend.log
fi

3.4 添加执行权限并启动

bash 复制代码
chmod +x /opt/ipam/backend/start.sh
/opt/ipam/backend/start.sh

3.5 配置 Systemd 服务(开机自启)

文件位置: /etc/systemd/system/zy-ipam.service

ini 复制代码
[Unit]
Description=ZY IPAM Backend Service
After=network.target mysql.service redis.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/ipam/backend
ExecStart=/usr/bin/java -jar /opt/ipam/backend/zy-admin.jar --spring.profiles.active=prod --spring.config.location=file:/opt/ipam/config/
Restart=on-failure
RestartSec=10
StandardOutput=append:/opt/ipam/logs/backend.log
StandardError=append:/opt/ipam/logs/backend-error.log

[Install]
WantedBy=multi-user.target
bash 复制代码
# 启用服务
sudo systemctl daemon-reload
sudo systemctl enable zy-ipam
sudo systemctl start zy-ipam
sudo systemctl status zy-ipam

# 查看日志
sudo journalctl -u zy-ipam -f

3.6 检查后端状态

bash 复制代码
# 检查进程
ps aux | grep zy-admin.jar

# 检查端口
sudo netstat -tlnp | grep 8080

# 测试接口
curl http://localhost:8080

四、前端部署

4.1 打包前端

在本地执行:

bash 复制代码
# Vue 项目打包
npm run build:prod
# 或
yarn build:prod

# 打包后生成 dist 目录

4.2 上传前端文件

bash 复制代码
# 将 dist 目录内容上传到 /opt/ipam/frontend/
# 确保 index.html 在 /opt/ipam/frontend/ 根目录

4.3 设置文件权限

bash 复制代码
sudo chown -R www-data:www-data /opt/ipam/frontend
sudo chmod -R 755 /opt/ipam/frontend

五、Nginx 配置

5.1 创建 Nginx 配置文件

文件位置: /etc/nginx/sites-available/zy-ipam

nginx 复制代码
server {
    listen 80;
    server_name scycx.xyz www.scycx.xyz;  # 替换为你的域名
    
    # 前端静态文件
    location / {
        root /opt/ipam/frontend;
        index index.html;
        try_files $uri $uri/ /index.html;
        expires 1h;
        add_header Cache-Control "public, immutable";
    }
    
    # 后端 API 代理
    location /prod-api/ {
        rewrite ^/prod-api/(.*)$ /$1 break;
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 超时设置(重要!)
        proxy_connect_timeout 180s;
        proxy_send_timeout 180s;
        proxy_read_timeout 180s;
    }
    
    # 文件上传大小限制
    client_max_body_size 50M;
    
    # 静态资源缓存(可选)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        root /opt/ipam/frontend;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

5.2 启用配置

bash 复制代码
# 创建软链接
sudo ln -s /etc/nginx/sites-available/zy-ipam /etc/nginx/sites-enabled/

# 测试配置
sudo nginx -t

# 重载 Nginx
sudo systemctl reload nginx

5.3 检查 Nginx 状态

bash 复制代码
sudo systemctl status nginx
sudo netstat -tlnp | grep :80

六、最终启动顺序

bash 复制代码
# 1. 启动 MySQL
sudo systemctl start mysql

# 2. 启动 Redis
sudo systemctl start redis

# 3. 启动后端
cd /opt/ipam/backend && ./start.sh
# 或使用 systemd
sudo systemctl start zy-ipam

# 4. 重载 Nginx
sudo systemctl reload nginx

七、验证部署

7.1 本地测试

bash 复制代码
# 测试前端
curl http://localhost

# 测试后端
curl http://localhost:8080

# 测试 API
curl http://localhost/prod-api/xxx

7.2 浏览器访问

arduino 复制代码
http://scycx.xyz

八、Chrome 浏览器 HTTPS 强制跳转问题解决

如果 Chrome 自动跳转 HTTPS 导致无法访问:

方法一:关闭 HTTPS-Only Mode

  1. 打开 chrome://settings/security
  2. 找到 "始终使用安全连接"
  3. 关闭该开关

方法二:修改 Chrome Flag

  1. 打开 chrome://flags/#https-upgrades-typed-schemes-navigation-no-timeout-fallback
  2. 设置为 Disabled
  3. 重启 Chrome

方法三:使用其他浏览器

  • Edge、Firefox 默认不强制 HTTPS

九、常用管理命令

bash 复制代码
# 查看后端日志
tail -f /opt/ipam/logs/backend.log

# 查看 Nginx 日志
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

# 重启后端
pkill -f zy-admin.jar && /opt/ipam/backend/start.sh

# 重载 Nginx
sudo nginx -t && sudo systemctl reload nginx

# 查看所有服务状态
sudo systemctl status mysql redis nginx zy-ipam

# 查看端口
sudo netstat -tlnp | grep -E ":(80|8080|3306|6379)"

十、项目目录结构最终版

bash 复制代码
/opt/ipam/
├── backend/
│   ├── zy-admin.jar          # 后端 jar 包
│   └── start.sh              # 启动脚本
├── frontend/
│   ├── index.html            # 前端入口
│   ├── favicon.ico           # 图标
│   └── static/               # 静态资源
├── config/
│   └── application-prod.yml  # 生产环境配置
├── logs/
│   └── backend.log           # 后端日志
├── sql/
│   └── zy-ipam.sql           # SQL 初始化脚本
└── uploadPath/               # 文件上传目录

十一、配置文件汇总

文件 位置 用途
application-prod.yml /opt/ipam/config/ 后端生产环境配置
zy-ipam /etc/nginx/sites-available/ Nginx 站点配置
zy-ipam.service /etc/systemd/system/ Systemd 服务配置
start.sh /opt/ipam/backend/ 后端启动脚本

十二、常见问题排查

12.1 后端启动失败

bash 复制代码
# 查看日志
tail -100 /opt/ipam/logs/backend.log

# 常见原因:
# - 数据库密码错误
# - Redis 未启动
# - 端口被占用
# - 配置文件格式错误

12.2 前端访问 404

bash 复制代码
# 检查文件
ls -la /opt/ipam/frontend/index.html

# 检查 Nginx
sudo nginx -t
sudo systemctl status nginx

12.3 API 请求超时

bash 复制代码
# 检查后端
curl http://localhost:8080

# 检查 Nginx 超时配置
# 在 location /prod-api/ 中添加 proxy_read_timeout 180s;

部署完成!🎉

相关推荐
霸道流氓气质1 小时前
Spring 事务同步机制 —— AfterTransactionActionCollector 的异步解耦原理
java·后端·spring
Csvn1 小时前
🔍 TypeScript `satisfies` 操作符:既要类型安全,又要推断的原始字面量类型
前端
Csvn2 小时前
🚦 手写 Promise 并发控制:如何优雅限制异步请求的并发数?
前端
Csvn2 小时前
📊 SQL 入门 Day 19:事务与隔离级别
后端·sql
面试鸭2 小时前
Anthropic 让 Claude 接了 CI 值班的第一班,人剩下的是写规则和合 PR
后端·面试
gb42152872 小时前
python中Web应用服务器
开发语言·前端·python
小强19882 小时前
useRef 到底用来干什么?不止获取 DOM 元素
后端
大勇前进2 小时前
React Hooks 常见 5 大坑:写完代码疯狂 Bug,避坑总结
后端
默_笙2 小时前
💌 为了把"主题色"传给孙子组件,我翻了五层楼——直到遇见了 useContext
前端·javascript