宝塔面板部署Spring Boot 3与Vue 3前后端分离项目完整指南
前阵子帮朋友把一个前后端分离的个人项目推到公网服务器上整个过程走下来最大的感受就是用宝塔面板做可视化部署确实比纯 SSH 命令行操作省心太多。特别是对于 Spring Boot 3 后端加 Vue 3 前端这种典型组合从 Ubuntu 安装宝塔面板到配置 Nginx、MySQL、Redis再到把前后端分别发布到公网每一个环节都能在浏览器里点出来不用再对着黑窗口一遍遍敲命令、改配置、试错。这篇文章就把我这次完整的部署过程整理出来从环境准备到最终上线每一步的选型思路、配置文件、踩坑记录都写清楚刚接触服务器部署的新手可以照着做有经验的开发者也能从中找到一些平时容易忽略的细节。1. 为什么选择宝塔面板做可视化部署1.1 可视化部署到底解决了什么问题先聊点实在的。没有面板之前部署一个前后端分离项目需要手动干这些事情安装 Nginx、配置站点、修改 nginx.conf安装 MySQL初始化数据库、创建账号授权装 Redis设置密码、绑定内网地址还要装 Java 环境、用 nohup 把 jar 包拉起来再用 grep 去查日志。这套流程写下来就够累的实际执行的时候任何一个配置项写错排查起来都是按小时计的。宝塔面板的核心价值就是把这些重复劳动变成可视化操作。软件商店里点两下Nginx、MySQL、Redis 就装好了数据库管理页面直接创建库、创建用户网站页面填写域名和根目录Nginx 配置文件就自动生成好了SSL 证书也能在面板里一键申请。对个人开发和中小团队来说这不仅仅是省时间更重要的是降低了部署门槛——你不需要记住 Nginx 每一行配置的含义也不需要手写 MySQL 的 GRANT 授权语句面板已经把最常见的场景封装好了。我个人用过挺长时间命令行部署也经历过线上环境改错配置导致整站 502 的深夜。改用宝塔之后至少大部分操作都能通过面板来管理出问题也方便回溯。这里要说清楚宝塔不是让你完全不懂底层原理而是让你把精力集中在业务代码本身把那些枯燥的环境搭建交给可视化界面。1.2 部署方案的整体架构这次要部署的是 Spring Boot 3 Vue 3 的项目整体架构比较典型先在一张表里理清楚层级组件服务器上的角色对外暴露端口入口Nginx托管前端静态文件、反向代理后端接口80 / 443前端Vue 3 构建产物dist 目录由 Nginx 直接托管无独立端口后端Spring Boot 3可执行 jar 包Java 进程运行8080仅内网数据库MySQL业务数据存储3306仅内网缓存Redis会话、验证码、热门数据缓存6379仅内网浏览器访问用户域名时请求先到 Nginx如果请求的是/开头的静态资源路径Nginx 直接把 Vue 构建后的 dist 目录里的文件返回给浏览器如果请求的是/api开头的接口Nginx 将请求反向代理给内网 8080 端口的 Spring Boot 服务。这样设计有几个明显的好处。第一Nginx 对静态文件处理效率很高前端资源由它托管能扛住不少并发。第二浏览器只跟域名打交道前端和后端在同一个域名下天然避免了跨域问题不用在前端代码里写一堆 CORS 配置。第三MySQL、Redis、后端 Java 进程都不直接暴露公网只监听内网地址攻击面小很多。这也就是“公网部署”和“内网开发环境”最大的区别——公网环境必须考虑端口暴露、进程守护、日志管理这些事。2. Ubuntu 服务器环境准备与宝塔面板安装2.1 服务器选型与系统初始化要点部署的第一步是准备一台公网服务器。系统方面我推荐 Ubuntu 22.04 LTS宝塔对 Ubuntu 的支持很完善而且 22.04 是 LTS 版本软件源和内核维护期都很长。配置方面单纯跑一个 Spring Boot 项目加 Nginx1 核 2G 内存就够用了如果打算上面同时跑 MySQL 和 Redis内存建议选 2G 以上避免内存不足触发 OOM 把进程杀掉。拿到服务器后我建议先做系统更新把系统自带的软件包升到最新版本apt update apt upgrade -y这一步不是可选的。刚买来的服务器系统镜像的软件包版本往往比较旧先更新可以减少后续安装软件时遇到依赖冲突的概率。然后再装一下基础工具比如 curl、vim、lsof 这些后面排查问题都会用到apt install -y curl vim lsof net-tools服务器联网后还要确认几个信息系统架构一般用uname -mx86_64 是最常见的、磁盘分区情况df -h、内存大小free -h。这些信息决定后面装什么版本的软件、JVM 内存参数怎么调。比如 2G 内存的机器Spring Boot 的 JVM 堆内存就控制在 512M 左右比较稳妥不能默认分配很大。提示如果服务器是云厂商的轻量应用服务器记得在控制台安全组里提前放行 80、443 端口以及后面面板自定义的端口。安全组没放行服务器里再怎么配置都访问不了。2.2 宝塔面板安装与首次安全设置Ubuntu 上安装宝塔面板官方给了一键安装脚本。执行这个脚本面板会自动拉起一个 Web 服务托管在 8888 端口curl -sSfL https://download.bt.cn/install/install-ubuntu_6.0.sh | sudo bash安装过程中会有一段时间在下载和编译组件大概几分钟到十几分钟不等取决于服务器网络状况。装完后终端会输出面板的访问地址、默认用户名和密码类似下面的格式面板地址:http://服务器公网IP:8888/xxxxxxxusername:xxxxpassword:xxxxx这里的/xxxxxxx是面板的随机安全入口一定要保存好。我见过很多新手直接访问http://IP:8888结果发现页面打不开就是因为安全入口这段路径没有带上。第一次访问面板页面会要求绑定宝塔账号。这个是免费的去宝塔官网注册一个账号绑定即可目的是面板更新和部分功能需要账号体系支撑不影响正常使用。登录之后先别急着装环境做三件安全设置修改面板端口把默认的 8888 改成其他端口比如 8899。默认端口是扫描器最常探测的端口改掉能省掉不少恶意请求。设置安全入口把面板登录地址的随机路径换成一个自己记得住但别人猜不到的字符串例如/myadmin_bt_2024。启动 BasicAuth 认证可选在“安全”页面开启访问面板前会额外弹一层账号密码认证。这三个设置做完面板对外暴露的入口才算安全一些。注意这些安全措施都是面板自带的功能属于常规服务器维护操作强烈建议养成习惯。3. 面板环境安装LNMP 环境配置3.1 软件商店安装 Nginx、MySQL、Redis宝塔登录成功后进入“软件商店”页面在“运行环境”分类里找到 Nginx、MySQL、Redis。这里不用去服务器上执行 apt 安装直接点击“安装”就行。安装前有几个选型细节Nginx选稳定版 1.22 或 1.24不建议选 mainline 版本。稳定版在模块兼容性和稳定性上更可靠个人项目完全够用。MySQL机器内存小于 2G 推荐 MySQL 5.7内存充足就上 MySQL 8.0。8.0 的默认认证插件是 caching_sha2_password一些老版本 JDBC 驱动可能不兼容但 Spring Boot 3 使用 MySQL 8.0 驱动没有这个问题。Redis选 7.x 版本安装后默认监听在 127.0.0.1这个不需要改。面板里有“极速安装”和“编译安装”两种方式。新手或者追求省时间的直接选极速安装它使用系统软件包安装速度快编译安装可以自定义参数但耗时长不建议在没有特殊需求时使用。我在这次部署中选的是极速安装前后不超过十分钟三个软件就全部装好了。3.2 数据库与 Redis 初始化与访问控制软件装完之后进入“数据库”页面点击“添加数据库”。宝塔会自动生成数据库名、用户名和一个随机密码你也可以自己指定。这里我建议自己设定一个复杂度足够的密码至少要包含大小写字母、数字和特殊字符。创建完成后宝塔会把这个库的权限自动授权给对应账号不用手动执行 GRANT 语句。如果你需要图形化管理数据库宝塔自带的 PHPMyAdmin 或者 Adminer 足够用了。在“数据库”页面点击“管理”按钮就会通过面板配置的路径打开数据库管理界面。生产环境中PHPMyAdmin 默认路径是随机的不对外直接开放这个设计比较稳妥。Redis 方面宝塔安装完默认没有设置密码这是公网部署的大忌。Redis 如果没有密码校验又监听了公网地址黑客可以直接连上去写 cron 计划任务实现远控。必须立刻设置密码。Redis 配置文件一般在/www/server/redis/redis.conf在里面找到requirepass这行改成requirepass 你的强密码改完后在宝塔软件商店里找到 Redis点击“重启”让配置生效。后端 Spring Boot 配置文件中只要在spring.redis.password填入同一个密码即可。实际项目中还可以进一步配置 Redis 只监听 127.0.0.1这是默认配置我就不额外改了。4. Spring Boot 3 后端部署实操4.1 本地打包Maven 构建可执行 jar后端代码在本地开发测试通过后需要打包成可执行的 jar 包。Spring Boot 3 要求 Java 17 及以上所以本地 JDK 版本必须是 17否则打包时会报编译错误。进入项目根目录执行mvn clean package -DskipTests-DskipTests表示跳过单元测试加快打包速度。如果你希望测试跑完再打包去掉这个参数就行但生产构建一般都会跳过避免测试环境配置导致打包失败。打包完成后target 目录下会生成一个xxx.jar文件。这里要注意 Spring Boot 的 Maven 插件是否配置了repackage目标正常情况下 Spring Boot 项目都会自动生成可执行 jar体积比普通 jar 大不少里面包含了所有依赖。如果生成的文件很小几十 KB多半是打成了普通 jarSpring Boot 插件配置有问题需要检查spring-boot-maven-plugin。4.2 上传 jar 包与 Java 环境检查jar 包传到服务器这一步用宝塔自带的文件管理器最方便。打开“文件”页面进入/www/wwwroot/目录为项目建一个独立目录比如/www/wwwroot/myapp/然后把 jar 包拖拽进去。相比 scp 命令面板文件管理器对不熟悉终端的人友好很多而且支持断点续传。上传完后检查服务器 Java 环境。宝塔不会自动装 Java需要在终端执行apt install -y openjdk-17-jdk java -versionjava -version输出里看到 OpenJDK 17说明环境就绪。如果服务器上已经有多版本 Java需要确认java命令指向的是 17可以在终端用update-alternatives --config java切换。在正式交给进程守护工具之前我习惯先在终端手动启动一次 jar验证环境和配置对不对cd /www/wwwroot/myapp java -jar xxx.jar --spring.profiles.activeprod看到Started相关的日志说明后端启动成功。这时可以用curl http://127.0.0.1:8080/api/hello测一下接口通不通。能通再关掉进程进入下一步。4.3 用 Supervisor 守护后端进程直接java -jar启动的后端进程有一个很大的问题终端一关进程就可能收到 SIGHUP 信号退出进程崩溃了也没人自动拉起来日志输出到终端不方便动态查看。生产环境必须有一个守护进程来管理它。宝塔软件商店里有一个“进程守护管理器”Supervisor就是干这个用的。安装后进入“进程守护”页面添加守护进程名称比如myapp-backend启动用户root或者 www 用户注意文件权限即可运行目录/www/wwwroot/myapp启动命令java -jar /www/wwwroot/myapp/xxx.jar --spring.profiles.activeprod进程数量1这里提个细节如果后端配置文件里的数据库地址、Redis 地址是通过环境变量注入的可以把环境变量填在“环境变量”栏里格式是KEYVALUE每行一个。Supervisor 启动时会自动加载这些变量避免在 jar 包和启动命令里暴露明文密码。配置完成后点击“启动”。Supervisor 会把进程挂在自己的名下后端崩溃会自动拉起服务器重启后也会自动启动。日志可以在面板页面上直接查看也可以配置日志文件位置路径填为/www/wwwroot/myapp/logs/out.log方便后面排查问题。我在实际使用中遇到过一个坑jar 包所在目录是一个挂载的磁盘分区如果开机挂载时机晚于 Supervisor 服务启动目录还是空的Supervisor 会找不到 java 命令。解决办法是给 Supervisor 服务加一个等待或者把 jar 放到系统盘路径下。这个问题不是每次都会遇到但碰到了确实容易一头雾水。5. Vue 3 前端构建与 Nginx 发布5.1 前端环境准备与生产构建前端部分需要在本地执行构建需要 Node.js 18 及以上版本。进入前端项目目录npm install npm run buildnpm run build执行完成后项目根目录下会生成dist/目录里面就是打包好的 HTML、JS、CSS 静态文件。构建之前最关键的一步是确认生产环境接口地址。Vue 3 Vite 项目通常在根目录有个.env.production文件里面配置了生产环境的环境变量。这里有两种风格VITE_API_BASE_URL/api # 或者 VITE_API_BASE_URLhttps://your-domain.com/api我推荐用相对路径/api。原因很简单前端和后端部署在同一个域名下Nginx 会把/api开头的请求代理到后端前端代码里用/api作为前缀就不存在写死 IP 或域名导致环境切换的问题。npm run build时Vite 会把代码里的import.meta.env.VITE_API_BASE_URL替换为实际值打包进 JS 文件所以构建前一定要确认这个变量是对的。5.2 上传 dist 目录到服务器目录回到宝塔面板在文件管理器中进入站点根目录。我习惯在/www/wwwroot/下新建一个专门放前端资源的目录例如/www/wwwroot/myapp-web。把本地 dist 目录里的内容全部上传到这个目录。很多新手容易犯一个错误把 dist 目录整个压缩包上传然后传到服务器上忘了解压Nginx root 指到.zip文件上当然访问不了。我用文件管理器一般是先上传 zip 压缩包在面板里选中压缩包直接点“解压”解压完确认目录结构正确——也就是 index.html 直接在站点根目录下不是dist/dist/index.html这种嵌套结构。5.3 Nginx 站点配置与 SPA 路由适配前端文件上传后进入宝塔“网站”页面点击“添加站点”填写要绑定的域名例如www.example.com根目录选择/www/wwwroot/myapp-web。宝塔会自动生成一份 Nginx 配置这份配置默认支持静态站点访问但 Vue 3 默认使用 HTML5 History 模式路由如果不做处理刷新某个子路由比如/about时Nginx 找不到对应路径的物理文件会返回 404。解决办法是在站点配置文件中加入一段 try_files 指令。进入“网站” - 设置 - 配置文件把默认的location /配置调整为location / { root /www/wwwroot/myapp-web; index index.html; try_files $uri $uri/ /index.html; }try_files的含义是如果当前请求路径能对应到真实文件就直接返回如果找不到就回退到 index.html由 Vue 路由接管页面。这样刷新子路由就不会 404 了。另外建议开启 gzip 压缩减少静态资源传输体积gzip on; gzip_min_length 1k; gzip_comp_level 5; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xmlrss text/javascript;保存配置后在网站页面点“重载配置”前端静态站点基本就生效了。这时候访问http://域名应该能看到前端页面但接口还是不通下一步就处理反向代理和 HTTPS。6. 域名解析与 HTTPS 配置6.1 域名解析到服务器 IP前端页面要在公网被访问必须让域名指向服务器 IP。这一步在云厂商的域名解析控制台操作添加一条 A 记录主机记录填www或者记录值填服务器公网 IP。DNS 解析生效需要一定时间一般是几分钟到几十分钟取决于 TTL 设置。可以用ping 你的域名来验证是否解析到目标 IP。如果想同时支持www.example.com和example.com就添加两条 A 记录都指向同一个 IP然后在 Nginx 站点配置里绑定这两个域名。6.2 配置 Nginx 反向代理前端页面已经能访问了但页面里发起的/api请求目前还是 404因为 Nginx 并不知道这个路径应该交给谁。现在需要在同一个站点配置里加入反向代理location /api/ { proxy_pass http://127.0.0.1:8080/api/; 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; }这段配置的作用是把浏览器发来的/api/xxx请求转发给本机 8080 端口的 Spring Boot 服务。配置里有几个细节值得注意第一proxy_pass后面的 URL 末尾是否带/行为完全不同。proxy_pass http://127.0.0.1:8080/api/;是保留完整路径也就是/api/xxx原样转发如果写成proxy_pass http://127.0.0.1:8080;不带路径则是去掉/api前缀后转发实际传给后端的是/xxx。这个区别很容易踩坑后端的 Controller 路径一定要和转发后的路径匹配否则接口全 404。第二proxy_set_header这几个头很重要。Host头如果不设置后端收到的请求 Host 是127.0.0.1:8080某些依赖 Host 的代码比如生成链接就会错。X-Real-IP和X-Forwarded-For让后端拿到客户端的真实 IP对于记录请求日志、风控都有价值。再加上一步如果后端有个别接口包含文件上传需要调大 request body 限制否则 Nginx 默认只能接收 1M 请求体上传大文件会直接报413 Request Entity Too Large。可以在 server 块里加一行client_max_body_size 50m;这个值根据实际业务调整上传图片、文件的应用建议至少设为 20m 以上。6.3 申请 SSL 证书并开启强制 HTTPS域名解析生效后就可以申请 HTTPS 证书了。宝塔的“网站” - SSL 页面选择 Lets Encrypt 免费证书勾选绑定的域名点击申请。面板会自动完成域名校验一般一分钟内就签发成功。到期前宝塔会在证书过期前自动续签不需要人工干预。申请成功后打开“强制 HTTPS”开关。这样所有通过 http 访问的请求都会 301 跳转到 https确保整个站点走加密通道。配置里自动生成的跳转规则长这样if ($server_port !~ 443){ rewrite ^(/.*)$ https://$host$1 permanent; }也可以直接在站点配置里添加listen 443 ssl;并加载证书文件。这些操作面板都自动处理了重点是在浏览器里实际访问一下https://你的域名确认地址栏有小锁标志接口也能正常请求。至此一个公网可访问的 Spring Boot 3 Vue 3 项目就算正式上线了。不过上线只是开始后面的维护和问题排查才是长期工作。7. 常见问题与排查技巧实录7.1 后端启动失败或访问出现 502后端是整套系统的核心启动失败出现的概率也最高。我整理了最典型的几个现象和对应的排查方向现象可能原因排查方法启动日志显示端口被占用8080 端口被其他进程占用lsof -i:8080找到占用的进程kill 或改启动端口启动报UnsupportedClassVersionErrorJava 版本低于 17java -version检查版本切换到 OpenJDK 17启动报数据库连接失败MySQL 密码错误或账号没有权限检查application-prod.yml中的数据库地址、用户名、密码Redis 连接报NOAUTH Authentication requiredRedis 已设置密码但后端没配置检查spring.redis.password是否与 Redis 配置一致Nginx 访问接口返回 502后端进程没有启动或代理地址写错先curl http://127.0.0.1:8080/api/xxx直连测通再看 Nginx 代理配置这里有个很实用的排查思路先绕过 Nginx直接在当前服务器上用 curl 访问后端接口确认接口本身通不通。如果直连通、走域名不通问题在 Nginx 配置如果直连不通问题在后端应用或中间件。这个二分法能快速缩小故障范围不用在日志里大海捞针。7.2 前端白屏或路由刷新 404前端部署后最常见的问题是白屏。打开浏览器开发者工具F12的 Network 面板刷新页面看请求状态首页能打开页面空白Console 报错多半是 JS 文件 404 或加载失败。检查站点根目录里是否真的有 js/css 文件以及 Nginx 的 root 路径是否指对了。首次打开正常刷新子路由 404这就是前面提到的 History 路由问题。确认 Nginx 配置里有没有加try_files $uri $uri/ /index.html;。页面能打开但接口请求地址不对浏览器 Network 里看接口请求 URL如果请求的是localhost或错误的 IP说明.env.production里的VITE_API_BASE_URL没配对需要重新构建再上传。还有一种情况比较隐蔽前端项目使用的是vue-router的createWebHistory()如果部署环境的服务端没有正确返回 index.html刷新任何非根路径都会 404。上面 try_files 方案已经覆盖这里不多说。7.3 API 请求 401 或连接拒绝前后端用 Nginx 反代后大多数跨域问题已经消失。但有些情况下 API 还是会报 401前端请求里带了Authorization: Bearer token头Nginx 默认会透传这个头到后端一般不需要额外配置。但如果你在前端有自定义 header比如X-Tenant-IDNginx 默认可能不转发需要在反代配置里显式声明proxy_set_header Authorization $http_authorization; proxy_set_header X-Tenant-ID $http_x_tenant_id;如果后端报 401 不是因为头部缺失那就是 Token 校验失败。Spring Boot 3 Spring Security 的项目里检查一下 Security 配置里放行了哪些路径。生产环境常见的做法是/api/auth/login和/api/auth/register放行其余接口都要登录后才能访问前端每次请求必须带上 Token。7.4 面板访问异常与服务器安全设置有时候面板本身打不开或者频繁被扫描也值得花点时间处理面板打不开确认安全组是否放行了面板自定义端口用netstat -tlnp | grep 端口号确认面板进程在监听如果服务器有宝塔系统防火墙去“安全”页面把面板端口加入放行列表。登录时提示安全入口错误宝塔的安全入口是 URL 后面的一段随机路径从安装信息里能找到。如果忘记了可以到服务器终端执行bt default重新查看默认面板信息也可以修改安全入口为自定义字符串。经常收到面板登录失败告警说明有人在对端口做暴力破解尝试。除了修改端口和安全入口还可以在面板“安全”页面设置仅允许指定 IP 访问面板把本地办公网络的公网 IP 加进去其它 IP 一律拒绝。面板本身只是管理工具最重要的是记住它的安全基线默认端口要改、安全入口要留、服务器安全组要收敛。做到了这些才能让面板本身不成为系统的弱点。我自己在实际部署中还有一个小习惯每次发布新版本前先在本地完整走一遍构建流程确认 dist 目录生成正常、jar 包大小符合预期再上传服务器。上线后第一时间用手机 4G 网络访问一下公网地址确认不是本地缓存造成的假象。过程看起来繁琐但几轮迭代下来能省掉不少因为粗心导致的线上故障。部署这件事熟练之后会很快但每一步都值得认真对待。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →