跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaSaaSAI大前端java

基于宝塔 Linux 与 Nginx 部署智能协同云图库实战

综述由AI生成详细记录了在云服务器上利用宝塔面板完成 Linux 环境初始化及依赖安装的过程。内容涵盖 MySQL 数据库创建、Redis 远程访问配置、JDK 17 环境搭建,以及前后端项目的打包与部署方案。重点讲解了如何通过 Nginx 实现前后端分离架构下的请求转发与 WebSocket 支持,解决了单页应用刷新 404 问题,最终实现智能协同云图库的全流程上线部署。

技术博主发布于 2026/3/28更新于 2026/6/619 浏览
基于宝塔 Linux 与 Nginx 部署智能协同云图库实战

在这里插入图片描述

在这里插入图片描述

云服务器初始化

安装宝塔 Linux 面板

登录服务器后,首先安装宝塔面板。执行官方提供的安装命令,等待脚本完成。

image-20250812165441183

安装过程中会提示设置面板的默认账号和密码,建议直接修改为自定义的安全凭证。

image-20250812165224988

image-20250812165255666

配置防火墙

为了安全起见,需要在服务器控制台或宝塔面板中开放必要的端口。首先是宝塔面板的管理端口(默认为 8888)。

image-20250812165512032

点击添加规则,放行宝塔 Linux 端口 8888。

image-20250812165621298

登录与管理

使用外网 IPv4 地址访问面板地址,复制终端生成的账号密码进行登录。

image-20250812165748494

image-20250812165835400

粘贴复制的命令并执行以激活环境。

image-20250812165928904

打开外网 IPv4 面板地址,复制账号秘密并登录。

image-20250812170127458

激活依赖

激活面板后,选择 LNMP 依赖套件进行安装。务必勾选 PHP 选项,这是运行后端应用的基础。

image-20250812170311292

如果在安装依赖时遇到超时或失败,可以在服务器重置系统中选择重装 Linux 宝塔面板。

image-20250812165224988

安装过程中,可以点击设置面板,修改默认账号、密码以提升安全性。

image-20250814101520465

查看安装进度,确保所有组件就绪。

image-20250814101451972

部署规划

源码地址

项目源码托管于 GitHub: https://github.com/liyupi/yu-picture

部署方案

为了提高效率,本项目前端和后端均使用宝塔面板进行管理。前端遵循 Vue 项目的部署模式,基于 Nginx 运行;后端利用宝塔的 Java 项目管理器运行 JAR 包。

地址规划

  • 前端:通过 Nginx 进行转发,访问地址为 http://{域名}。
  • 后端:通过 Nginx 进行转发,访问地址为 http://{域名}/api。实际运行在 8123 端口。JDK 建议选择 17 版本(caffeine 要求 JDK > 11)。

为什么要用 Nginx 转发?前后端域名一致,保证不会出现跨域问题。

  • Nginx:服务器 80 端口,默认已安装。
  • 数据库:服务器 3306 端口,默认已安装。
  • Redis:服务器 6379 端口,需要手动安装。

注意事项

做好规划后,需要在腾讯云控制台的防火墙中开通需要外网访问的服务端口,比如 MySQL 和 Redis。

image-20250812174520017

安装依赖

1、数据库

宝塔面板已经自动安装 MySQL 数据库,我们可以直接使用。

先为后端项目添加一个数据库。数据库名称和项目需要的保持一致,注意用户名、密码和访问权限。

image-20250814101407836

在宝塔中开放数据库端口号。

image-20250813180124151

在 IDE 中打开后端项目,通过数据库面板在本地检查连接是否正常。

image-20250812175114390

image-20250813180221789

配置数据源,执行脚本初始化库表。

-- 创建数据库
create database if not exists yu_picture;
-- 切换库
use yu_picture;

-- 用户表
create table if not exists user (
    id bigint auto_increment comment 'id' primary key,
    userAccount varchar(256) not null comment '账号',
    userPassword varchar(512) not null comment '密码',
    userName varchar(256) null comment '用户昵称',
    userAvatar varchar(1024) null comment '用户头像',
    userProfile varchar(512) null comment '用户简介',
    userRole varchar(256) default 'user' not null comment '用户角色:user/admin',
    editTime datetime default current_timestamp not null comment '编辑时间',
    createTime datetime default current_timestamp not null comment '创建时间',
    updateTime datetime default current_timestamp not null on update current_timestamp comment '更新时间',
    isDelete tinyint default 0 not null comment '是否删除',
    unique key uk_userAccount (userAccount),
    index idx_userName (userName)
) comment '用户' collate = utf8mb4_unicode_ci;

-- 图片表
create table if not exists picture (
    id bigint auto_increment comment 'id' primary key,
    url varchar(512) not null comment '图片 url',
    name varchar(128) not null comment '图片名称',
    introduction varchar(512) null comment '简介',
    category varchar(64) null comment '分类',
    tags varchar(512) null comment '标签(JSON 数组)',
    picSize bigint null comment '图片体积',
    picWidth int null comment '图片宽度',
    picHeight int null comment '图片高度',
    picScale double null comment '图片宽高比例',
    picFormat varchar(32) null comment '图片格式',
    userId bigint not null comment '创建用户 id',
    createTime datetime default current_timestamp not null comment '创建时间',
    editTime datetime default current_timestamp not null comment '编辑时间',
    updateTime datetime default current_timestamp not null on update current_timestamp comment '更新时间',
    isDelete tinyint default 0 not null comment '是否删除',
    index idx_name (name),
    index idx_introduction (introduction),
    index idx_category (category),
    index idx_tags (tags),
    index idx_userId (userId)
) comment '图片' collate = utf8mb4_unicode_ci;

alter table picture add column reviewStatus INT default 0 not null comment '审核状态:0-待审核;1-通过;2-拒绝';
alter table picture add column reviewMessage VARCHAR(512) null comment '审核信息';
alter table picture add column reviewerId BIGINT null comment '审核人 ID';
alter table picture add column reviewTime DATETIME null comment '审核时间';
alter table picture add column thumbnailUrl varchar(512) null comment '缩略图 url';

-- 空间表
create table if not exists space (
    id bigint auto_increment comment 'id' primary key,
    spaceName varchar(128) null comment '空间名称',
    spaceLevel int default 0 null comment '空间级别:0-普通版 1-专业版 2-旗舰版',
    maxSize bigint default 0 null comment '空间图片的最大总大小',
    maxCount bigint default 0 null comment '空间图片的最大数量',
    totalSize bigint default 0 null comment '当前空间下图片的总大小',
    totalCount bigint default 0 null comment '当前空间下的图片数量',
    userId bigint not null comment '创建用户 id',
    createTime datetime default current_timestamp not null comment '创建时间',
    editTime datetime default current_timestamp not null comment '编辑时间',
    updateTime datetime default current_timestamp not null on update current_timestamp comment '更新时间',
    isDelete tinyint default 0 not null comment '是否删除',
    index idx_userId (userId),
    index idx_spaceName (spaceName),
    index idx_spaceLevel (spaceLevel)
) comment '空间' collate = utf8mb4_unicode_ci;

alter table space add column spaceType int default 0 not null comment '空间类型:0-私有 1-团队';
create index idx_spaceType ON space (spaceType);

-- 空间成员表
create table if not exists space_user (
    id bigint auto_increment comment 'id' primary key,
    spaceId bigint not null comment '空间 id',
    userId bigint not null comment '用户 id',
    spaceRole varchar(128) default 'viewer' null comment '空间角色:viewer/editor/admin',
    createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    UNIQUE KEY uk_spaceId_userId (spaceId, userId),
    INDEX idx_spaceId (spaceId),
    INDEX idx_userId (userId)
) comment '空间用户关联' collate = utf8mb4_unicode_ci;

记得验证数据库表是否创建成功。

image-20250813180502221

2、Redis

在宝塔面板的软件商店中,搜索并安装 Redis,版本选择默认的即可。

安装完成后,需要配置 Redis,开启远程访问并配置密码,否则本地无法连接。

image-20250814101338270

修改配置后,一定要重载配置才能生效。

image-20250813203112286

进行如下配置后,记得保存配置。

image-20250813203354370

最后,在 IDEA 数据库面板中验证本地能否连接远程 Redis。

image-20250813203455475

image-20250813203907038

如果 Redis 状态异常,可以在宝塔面板重启 Redis。

image-20250813204007830

image-20250813215948742

3、Java 环境

要部署 Java 项目,必须安装 JDK。在宝塔面板中,可以通过下图的方式快速安装指定版本的 JDK。此处我们先安装 JDK 17。

image-20250813204107672

image-20250813204142369

建议多安装几个版本,比如 JDK 8、11、17,需要用哪个版本的时候可以随时切换。

4、其他服务

比如腾讯云 COS 对象存储、阿里云百炼 AI,可以去对应的官网开通。

注意,要给对象存储增加该服务器 IP(或者实际访问前端域名)的跨域配置,否则编辑图片时将无法正确加载图片。

image-20250813204957560

接下来,我们分别进行后端和前端部署。

后端部署

1、修改配置

修改 application-prod 生产环境配置,包括数据库、Redis、对象存储、阿里云百炼 AI 的 key 等,替换为上述安装依赖时指定的配置(如用户名、密码)。

注意为了性能,还要关闭 MyBatis Plus 的日志;为了安全,要给 Knife4j 接口文档设置用户名和密码。

参考配置如下:

image-20250813210008293

# 线上配置文件
server:
  port: 8123
spring:
  # 数据库配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://云服务器 IP:3306/yu_picture
    username: yu_picture_root
    password: yu_picture_123456
  # Redis 配置
  redis:
    database: 0
    host: 101.34.40.20
    port: 6379
    timeout: 5000
    password: yu_picture_123456
mybatis-plus:
  configuration:
    # 生产环境关闭日志
    log-impl: ''
knife4j:
  basic:
    enable: true
    username: yu_picture_root
    password: yu_picture_123456
cos:
  client:
    host: xxx
    secretId: xxx
    secretKey: xxx
    region: xxx
    bucket: xxx
aliYunAi:
  apiKey: xxx

由于配置文件存在敏感信息,使用 git 提交代码时,忽视该配置文件的提交。

image-20250813210251489

2、打包部署

首先更改 pom.xml 文件的打包配置,删除掉主类配置的 skip 配置,才能打包。

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>${spring-boot.version}</version>
      <configuration>
        <mainClass>com.yupi.yupicturebackend.YuPictureBackendApplication</mainClass>
        <skip>true</skip>
      </configuration>
    </plugin>
  </plugins>
</build>

在 IDEA 中打开后端项目,忽略测试并打包。

image-20250813210449937

双击 package 打包,打包成功,得到 jar 包文件。

image-20250813210556796

找到 Jar 包对应的路径,复制路径,方便在面板上传 Jar 包。

image-20250813210746025

上传 jar 包到服务器,此处为了方便,就放到 web 根目录。

image-20250813210951464

然后添加 Java 项目。

image-20250813211108228

在项目执行命令中,必须指定生产环境的配置!还可以根据需要调整内存。

image-20250813211320130

项目启动命令中,指定生产环境配置:

/www/server/java/jdk-17.0.8/bin/java -jar -Xmx1024M -Xms256M /www/wwwroot/yu-picture-backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

点击确认后,忽略后面数据库密码的校验,可能是没识别到而已。

image-20250813211734567

image-20250813212157420

启动成功后,能够看到状态和端口占用如图。

image-20250813212116485

image-20250813212143365

img

如果发现启动失败,需要先观察日志,下图仅为一个示例。

image-20250813212358449

但是,我们现在无法通过浏览器访问接口文档:http://云服务器 IP:8123/api/doc.html

image-20250814101218163

这是因为我们的服务器防火墙没有放开 8123 端口。这里我们故意不放开,因为在之前的部署规划中,后端需要通过 Nginx 进行转发,从而解决跨域问题。

如果我们部署的 Jar 包部署后,总是莫名其妙中断,就一定要看看项目对应的日志,比如以下问题,需要重装 Redis 并且重新过一遍设置 Redis 的 IP、密码的流程。

image-20250813223600760

3、Nginx 转发

新建一个 Nginx 站点,域名填写当前服务器 IP 或者自己的域名,根目录随意填写即可(只要不包含中文)。

image-20250813213449639

如果访问的是后端接口(地址有 /api 前缀),则 Nginx 将请求转发到后端服务,对应配置代码如下:

image-20250813213623593

location /api {
  proxy_pass http://127.0.0.1:8123;
  proxy_set_header Host $proxy_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_buffering off;
  proxy_set_header Connection "";
}

但是,对于本项目,光有 HTTP 转发配置还不够!后端还需要提供 WebSocket 连接,所以也要对 WebSocket 进行转发,再给 Nginx 补充下列配置:

image-20250813213725424

# 代理 WebSocket 连接 (专门用于 WebSocket 请求)
location /api/ws {
  proxy_pass http://127.0.0.1:8123;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  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_buffering off;
  proxy_read_timeout 86400s;
}

修改 Nginx 配置如图:

img

修改完后,就可以通过 80 端口(可以省略)访问到接口了。

之后,我们重新访问以下去掉端口号的接口文档地址:

image-20250813223920608

登录之后什么也没有显示:

image-20250813224022033

按 F12 排查问题:

image-20250813224112827

一定要注释掉下列配置!否则访问接口文档时,静态资源的加载可能会出错。因为浏览器会从本地缓存加载资源,而不是动态请求资源。

image-20250813224257779

再次访问只有 IP 没有端口号的地址,访问成功:

image-20250813224412960

前端部署

前端部署可以参考 Vite 官方文档:https://cn.vitejs.dev/guide/static-deploy.html

分为修改配置、打包部署和 Nginx 转发这 3 个步骤。

1、修改配置

线上的前端需要请求线上的后端接口,所以需要修改 request.ts 文件中的请求地址为线上:

image-20250814075709150

// 区分开发和生产环境
const DEV_BASE_URL = "http://localhost:8123";
const PROD_BASE_URL = "http://云服务器 IP";

// 创建 Axios 实例
const myAxios = axios.create({
  baseURL: PROD_BASE_URL,
  timeout: 10000,
  withCredentials: true,
});

此外,由于本项目用到了 WebSocket,还要同步修改 pictureEditWebSocket.ts 文件中的 WebSocket 的连接地址:

image-20250814075927853

const DEV_BASE_URL = "ws://localhost:8123";
const PROD_BASE_URL = "ws://云服务器 IP";
const url = `${PROD_BASE_URL}/api/ws/picture/edit?pictureId=${this.pictureId}`;

2、打包部署

1)刚刚下载好源码,先运行 dev 命令:

image-20250814074401479

image-20250814074241565

参考 Vite 官网,在 package.json 文件中定义 pure-build 命令:

{
  "scripts": {
    "dev": "vite",
    "pure-build": "vite build",
    "build": "run-p type-check \"build-only {@}\" --"
  }
}

为什么明明已经有 build 命令了,我们还要自己定义 pure-build 命令呢?

因为脚手架内置的 build 命令会执行类型检查,如果项目代码中有任何类型不规范的地方,都会导致打包失败!

img

虽然可以自己一个个修复类型,但是太影响效率了,得不偿失,所以引入一个更干净的构建命令。

2)执行 pure-build 命令,执行打包构建。

注意,如果 Node.js 版本较低,会构建失败,这时可以到官网安装更新的版本,比如 v20.17.0 等长期支持版本。

构建成功后,可以得到用于部署的静态文件 dist 目录:

image-20250814074634308

把 dist 目录下的所有文件上传到服务器上(可以新建一个 yu-picture-frontend 目录)。

image-20250814080926821

image-20250814081013981

3、Nginx 转发

一般来说,用户无法直接访问服务器上的文件,需要使用 Nginx 提供静态文件的访问能力。

修改已有站点的网站目录配置,指向前端文件根目录:

image-20250814081224236

image-20250814081307269

然后访问服务器地址(或者自己配置的域名),就能打开前端网站了:

image-20250814081511577

但是经过验证,目前访问除了主页外的其他页面(比如 /add_picture),如果刷新页面,就会出现 404 错误。

image-20250814101053486

这个问题是由于 Vue 是单页面应用(前端路由),打包后的文件只有 index.html,服务器上不存在对应的页面文件(比如 /add_picture.html),所以需要在 Nginx 配置转发。如果找不到某个页面文件,就加载主页 index.html 文件。

修改 Nginx 配置,补充下列代码:

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

如图:

image-20250814081906793

保存配置后,再次刷新页面,可以正常访问。

image-20250814084629680

至此,智能协同云图库项目已经完成上线啦~~~

希望大家能通过这个项目掌握企业级项目的开发、优化和上线方法,得到全方面编程技能和程序员素养的提升。

在这里插入图片描述

目录

  1. 云服务器初始化
  2. 安装宝塔 Linux 面板
  3. 配置防火墙
  4. 登录与管理
  5. 激活依赖
  6. 部署规划
  7. 源码地址
  8. 部署方案
  9. 地址规划
  10. 注意事项
  11. 安装依赖
  12. 1、数据库
  13. 2、Redis
  14. 3、Java 环境
  15. 4、其他服务
  16. 后端部署
  17. 1、修改配置
  18. 线上配置文件
  19. 数据库配置
  20. Redis 配置
  21. 2、打包部署
  22. 3、Nginx 转发
  23. 代理 WebSocket 连接 (专门用于 WebSocket 请求)
  24. 前端部署
  25. 1、修改配置
  26. 2、打包部署
  27. 3、Nginx 转发
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 二叉树转字符串的递归解法核心逻辑与代码实现
  • AI 编程工具深度对比:Cursor、Copilot、Trae 与 Claude Code
  • 预训练语言模型与 BERT 实战应用
  • 10 款辅助学术写作的 AI 降重工具介绍
  • 华为 OD 机试算法题:矩阵扩散
  • 我们的数据到底有多安全?网络安全经济学分析
  • Windows 环境下 Git 安装与配置指南
  • K8s 集群外通过路由直连 Pod 实战
  • AI 时代如何脱颖而出:商业认知与行动指南
  • 大模型应用优化:提示工程、RAG 与微调等 5 种方法
  • Nilearn Python 神经影像机器学习完整指南
  • Python 与前端集成构建全栈应用指南
  • LeetCode 239 滑动窗口最大值:单调队列解法
  • 转型 AI 产品经理:能力模型、发展史与核心概念梳理
  • 深入解读人工智能 LLM 模型工作机制
  • 电力行业智能客服案例:知识图谱与大模型驱动方案解析
  • 深度神经网络的参数初始化方法
  • 2023 年 Android 开发岗位核心面试题汇总
  • yshopmall 开源电商 SaaS 解决方案解析
  • GCC 14与C++26并发新特性深度解析

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online