当前位置: 首页 > news >正文

Spring Boot + Vue 全栈应用云端部署实战:从零到一上云指南

1. 环境准备:从零搭建你的云端“地基”

很多朋友在本地把Spring Boot和Vue项目跑得飞起,一到要部署上云服务器就有点发怵,感觉像要进入一个陌生的世界。别担心,我刚开始也这样,踩过不少坑。今天我就把自己从零开始,把一个全栈项目成功部署上云的全过程,掰开揉碎了讲给你听。这个过程其实就像装修房子,服务器就是你的毛坯房,环境就是水电煤气,咱们一步步来,保证你能跟着做下来。

首先,你得有个“毛坯房”,也就是云服务器。我比较推荐新手从腾讯云或阿里云的轻量应用服务器开始,它们预装了一些基础系统,价格也实惠。选购时,操作系统建议选择CentOS 7.xUbuntu 20.04 LTS或者国产的OpenCloudOS,这些都是社区活跃、资料丰富的Linux发行版。我这次演示就用OpenCloudOS,它和CentOS兼容性很好。买好服务器后,记下它的公网IP地址,这是你未来访问网站的“门牌号”。然后,用SSH工具(比如Xshell、FinalShell,或者Mac/Linux自带的终端)连接上去,我们的“装修”工程就正式开始了。

连接上服务器后,第一件事不是急着装软件,而是更新系统并安装最基础的编译工具。这能确保后续安装过程顺畅。你可以依次执行下面这几条命令:

# 更新系统软件包列表 sudo yum update -y # 安装常用的编译工具和库,比如gcc、make等,这是后续安装很多软件的基础 sudo yum groupinstall "Development Tools" -y sudo yum install -y pcre-devel zlib-devel openssl-devel

搞定基础工具后,我们就要安装项目的三大核心依赖:JDK、Node.js和数据库(这里以MySQL为例)。安装JDK是运行Spring Boot Jar包的前提。我习惯用yum直接安装OpenJDK,省去手动配置环境变量的麻烦。

# 搜索可用的JDK版本 sudo yum search java-11-openjdk # 安装JDK 11(Spring Boot 2.x/3.x的主流选择) sudo yum install -y java-11-openjdk-devel # 安装完成后验证 java -version

接下来安装Node.js。Vue项目的打包依赖它。为了能方便地切换Node版本,我推荐使用Node Version Manager (nvm)来安装。

# 下载并安装nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash # 让终端重新加载配置,或者新开一个终端窗口 source ~/.bashrc # 使用nvm安装Node.js的长期支持版(LTS) nvm install --lts # 验证安装 node -v npm -v

数据库方面,如果你项目里用到了MySQL,也需要在服务器上安装一个。直接用yum安装MariaDB(MySQL的一个流行分支)就行。

# 安装MariaDB服务器 sudo yum install -y mariadb-server # 启动数据库服务并设置开机自启 sudo systemctl start mariadb sudo systemctl enable mariadb # 运行安全初始化脚本,设置root密码等 sudo mysql_secure_installation

执行最后一条命令时,会有一个交互式的向导,记得为root用户设置一个强密码,并移除测试数据库和匿名用户,这是生产环境的基本安全要求。完成这些,你的云端“地基”就算初步打好了。记住,每一步执行完都最好用-v--version命令验证一下,确保安装成功,这是避免后续连环坑的好习惯。

1.1 安装与配置Nginx:你的全能“门卫”

Nginx在这里扮演着至关重要的角色:它既是Vue打包后静态文件(HTML、CSS、JS)的Web服务器,又是将前端API请求转发到后端Spring Boot应用的反向代理。用个形象的比喻,它就像公司的前台兼门卫,既负责展示公司形象(静态页面),又负责把访客(API请求)引导到正确的部门(后端服务)。

我更喜欢从源码编译安装Nginx,这样能获得最新的特性,并且可以自定义需要编译的模块。首先,我们去官网下载稳定版的源码包。

# 进入一个常用的源码存放目录,比如/usr/local/src cd /usr/local/src # 使用wget下载Nginx源码包(请替换为官网最新稳定版链接) sudo wget http://nginx.org/download/nginx-1.24.0.tar.gz # 解压源码包 sudo tar -zxvf nginx-1.24.0.tar.gz # 进入解压后的目录 cd nginx-1.24.0

接下来是经典的“配置-编译-安装”三步曲。./configure命令会检查系统环境并生成编译所需的Makefile。我们可以通过参数开启一些常用模块,比如--with-http_ssl_module用于支持HTTPS。

# 执行配置脚本,这里指定安装路径为/usr/local/nginx sudo ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module # 编译(这个过程可能需要几分钟) sudo make # 安装 sudo make install

安装完成后,Nginx的主程序会在/usr/local/nginx/sbin/目录下。为了方便使用,我们可以把它链接到系统的环境变量路径里。

# 创建软链接,这样在任何位置都能直接输入`nginx`命令了 sudo ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

现在,可以启动Nginx来测试一下了。

# 启动Nginx sudo nginx # 检查Nginx是否启动成功 ps aux | grep nginx

如果看到有nginx: master processnginx: worker process的进程在运行,说明启动成功。此时,打开你的浏览器,输入服务器的公网IP地址(比如http://你的服务器IP),如果能看到“Welcome to nginx!”的默认页面,恭喜你,“门卫”已经上岗了!如果看不到,可能是服务器的防火墙(如firewalld)没有开放80端口,你需要运行sudo firewall-cmd --permanent --add-service=httpsudo firewall-cmd --reload来放行。

1.2 安装与配置Redis:高性能“缓存管家”

如果你的Spring Boot项目用到了Redis做缓存或会话存储,那么在服务器上安装Redis也是必须的。Redis的安装同样简单,我们可以通过EPEL仓库来安装。

# 首先安装EPEL扩展仓库 sudo yum install -y epel-release # 更新仓库缓存后安装Redis sudo yum update -y sudo yum install -y redis # 启动Redis服务并设置开机自启 sudo systemctl start redis sudo systemctl enable redis # 检查Redis运行状态 sudo systemctl status redis

安装完成后,默认的Redis配置已经可以满足基础开发需求。但为了安全,我强烈建议你做两件事:一是设置访问密码,二是限制只允许本地访问(因为我们的Spring Boot应用和Redis在同一台服务器上)。编辑Redis的配置文件:

sudo vi /etc/redis.conf

在配置文件中找到这两行,并修改:

# 大约在61行,将绑定地址改为127.0.0.1,这样只允许本机连接 bind 127.0.0.1 # 大约在507行,找到`# requirepass foobared`,去掉注释并把`foobared`改成你自己的强密码 requirepass your_strong_password_here

保存退出后,重启Redis服务使配置生效:

sudo systemctl restart redis

最后,用Redis自带的命令行客户端测试一下连接和密码是否生效:

redis-cli # 连接后,执行认证命令 auth your_strong_password_here # 设置一个测试键值 set test "hello from redis" # 获取这个键值 get test

如果能看到你设置的“hello from redis”,说明Redis已经正确安装并配置好了。这个“缓存管家”将为你的应用提速不少。

2. 前端Vue项目部署:让界面“安家落户”

环境准备好后,我们开始部署前端。这个过程的核心就两步:在本地把Vue项目“打包”成静态文件,然后把打包好的文件“搬家”到服务器上,并告诉Nginx去哪里找这些文件。

首先,回到你的本地开发机器,打开Vue项目。在打包之前,有一个关键配置需要检查:API请求的基地址。在开发时,我们通常用localhost:8080来连接本地的Spring Boot后端。但现在后端要部署到云服务器上,地址变了。你需要修改vue.config.js文件(如果没有就新建一个),配置生产环境的代理或直接设置axiosbaseURL

假设你的后端Spring Boot应用在服务器上将会运行在8080端口,服务器公网IP是123.123.123.123,那么配置可能像这样:

// vue.config.js module.exports = { devServer: { proxy: { '/api': { // 你前端请求接口的统一前缀 target: 'http://123.123.123.123:8080', // 云服务器后端地址 changeOrigin: true, pathRewrite: { '^/api': '' } } } }, // 或者,如果你在代码里直接使用axios,可以在创建实例时设置baseURL // 新建一个`src/api/request.js`文件 }

更常见的做法是在项目中创建一个.env.production环境变量文件:

# .env.production VUE_APP_API_BASE_URL = http://123.123.123.123:8080

然后在你的API请求模块(比如axios)中读取这个变量:

// src/utils/request.js import axios from 'axios'; const service = axios.create({ baseURL: process.env.VUE_APP_API_BASE_URL, // 读取环境变量 timeout: 5000 });

配置好后,就可以开始打包了。在项目根目录下打开终端,运行:

npm run build

或者如果你的package.json里定义了生产环境构建命令:

npm run build:prod

这个命令会启动Webpack等打包工具,将你的Vue组件、路由、状态管理代码以及所有依赖,压缩、优化并打包成一个纯粹的静态资源文件夹,默认名称为dist。你会在项目根目录下看到这个新生成的dist文件夹,里面通常包含index.htmlcssjs等子文件夹。这就是你前端应用的全部“家当”。

接下来,我们需要把这些“家当”上传到云服务器。有很多方法,对于新手,我推荐使用scp命令(在Mac/Linux终端或Windows PowerShell/WSL中可用),它通过SSH协议安全地复制文件。

# 在本地机器终端执行,将dist文件夹整个上传到服务器的/usr/local/src/myapp/目录下 # 注意替换`your_username`为你的服务器登录用户名,`your_server_ip`为你的服务器公网IP scp -r ./dist your_username@your_server_ip:/usr/local/src/myapp/

这个命令会把本地的dist文件夹递归地复制到服务器/usr/local/src/myapp/路径下。如果该路径不存在,scp会报错,所以最好先在服务器上创建好目录:

# 在服务器上执行 sudo mkdir -p /usr/local/src/myapp

文件上传成功后,前端部署的物理部分就完成了。但此时直接访问服务器IP,看到的还是Nginx的欢迎页,而不是你的Vue应用。因为Nginx还不知道要去/usr/local/src/myapp/dist这个目录找文件。这就需要我们去修改Nginx的配置,给它指条明路。

2.1 配置Nginx托管前端静态资源

现在,我们要告诉Nginx这个“门卫”:“以后所有来访问网站根路径的请求,都去/usr/local/src/myapp/dist这个房间找文件接待”。这就需要编辑Nginx的配置文件。

# 使用vi或nano编辑器打开Nginx的主配置文件 sudo vi /usr/local/nginx/conf/nginx.conf

我们需要重点关注http块里的server块。一个典型的、用于托管Vue单页应用并代理后端API的配置如下。我会在关键位置加上注释,你可以对照着修改或替换你配置文件中的server部分。

http { # ... 其他http模块全局配置 ... server { listen 80; # 监听80端口(HTTP默认端口) server_name your_server_ip; # 你的服务器公网IP,也可以填域名,如 www.yourdomain.com # 前端静态文件服务配置 location / { root /usr/local/src/myapp/dist; # 这里就是你刚才上传dist文件夹的绝对路径 index index.html index.htm; # 默认索引文件 try_files $uri $uri/ /index.html; # 非常重要!用于支持Vue Router的history模式,避免404 } # 后端API反向代理配置 # 假设你前端所有API请求都以 `/api` 开头 location /api/ { proxy_pass http://127.0.0.1:8080/; # 转发到本机运行的Spring Boot应用 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 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; } # 可选的错误页面配置,将404错误也指向index.html,对SPA很友好 error_page 404 =200 /index.html; } }

这里有几个关键点需要理解:

  1. root指令:指定静态文件的根目录。当用户访问http://your_server_ip/about时,Nginx会去/usr/local/src/myapp/dist目录下寻找about文件或目录。对于Vue Router生成的路径,实际文件是不存在的,这就引出了下一条。
  2. try_files指令:这是支持Vue Routerhistory模式的核心。它的意思是:先尝试找$uri(请求的URI对应的真实文件),再尝试找$uri/(作为一个目录),如果都找不到,最后返回/index.html。这样,像/about这样的前端路由路径,虽然服务器上没有about这个文件,但最终会返回index.html,由前端的Vue Router来处理这个路由,完美解决了刷新页面404的问题。
  3. location /api/:这是一个反向代理配置。所有以/api/开头的请求(比如前端发起的/api/user/login),都会被Nginx拦截,并转发到http://127.0.0.1:8080/(即本机8080端口运行的Spring Boot应用)。proxy_set_header系列指令是为了在转发时保留原始的请求头信息,方便后端获取真实客户端IP等。

修改完配置后,一定要检查配置文件语法是否正确,这是一个好习惯,能避免因为配置错误导致Nginx无法启动。

sudo nginx -t

如果看到nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful的提示,说明配置语法正确。然后让Nginx重新加载配置,使改动生效:

sudo nginx -s reload

现在,再次在浏览器中访问你的服务器公网IP(http://你的服务器IP)。如果一切顺利,你应该能看到你的Vue应用界面了!不过,此时点击需要调用后端接口的按钮,可能会失败或加载中,因为我们的Spring Boot后端还没部署呢。别急,我们马上就来解决它。

3. 后端Spring Boot项目部署:让服务“稳如泰山”

后端部署的核心思想是:将我们的Spring Boot应用打包成一个可执行的、包含所有依赖的“超级”JAR文件(即Fat Jar),然后把它放到服务器上,用Java命令运行起来。为了让这个服务在后台稳定运行,不受终端关闭的影响,我们还需要一些“守护”手段。

首先,回到本地开发环境,对Spring Boot项目进行打包前的最后配置检查。主要关注两点:数据库连接文件存储路径

  1. 数据库配置:打开application.ymlapplication.properties文件,将数据库的urlusernamepassword从本地的localhost和开发密码,修改为云服务器上MySQL的地址(通常是127.0.0.1localhost)和你在安装MySQL时设置的强密码。

    # application-prod.yml (生产环境配置文件) spring: datasource: url: jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: your_db_username password: your_strong_db_password driver-class-name: com.mysql.cj.jdbc.Driver
  2. 文件路径:如果你的应用有文件上传功能,并且代码中写死了像D:/upload/这样的Windows绝对路径,在Linux服务器上肯定会出错。你需要将其改为Linux的路径,比如/home/your_app/uploads/,并确保运行JAR包的用户对这个目录有读写权限。更好的做法是使用配置项,例如:

    file: upload-dir: /home/your_app/uploads/

    然后在代码中通过@Value("${file.upload-dir}")注入使用。

配置检查无误后,就可以打包了。在项目根目录(包含pom.xml的目录)下,打开终端,运行Maven打包命令:

# 跳过测试,打包生产环境配置 mvn clean package -DskipTests -Pprod

这里的-Pprod表示激活名为prod的Maven Profile,它通常会使用我们上面创建的application-prod.yml配置文件。打包成功后,你会在target目录下找到一个名字类似your-project-0.0.1-SNAPSHOT.jar的文件。这个就是我们可以独立运行的“超级”JAR包。

接下来,将这个JAR包上传到云服务器。同样使用scp命令:

scp target/your-project-0.0.1-SNAPSHOT.jar your_username@your_server_ip:/home/your_app/

在服务器上,我们进入JAR包所在的目录,准备运行它。但直接运行java -jar命令有个问题:一旦你关闭SSH终端,这个Java进程也会随之终止。这显然不是我们想要的生产环境运行方式。我们需要让它在后台运行,并且即使终端关闭也能持续提供服务。有几种方法可以实现:

方法一:使用nohup(最简单直接)nohup命令可以让进程忽略挂断信号(SIGHUP),从而在终端关闭后继续运行。

cd /home/your_app # 使用nohup在后台运行jar包,并将标准输出和错误输出重定向到nohup.out文件 nohup java -jar your-project-0.0.1-SNAPSHOT.jar > nohup.out 2>&1 &

命令解释:

  • nohup:保证进程不挂断。
  • > nohup.out:将命令的标准输出重定向到nohup.out文件。
  • 2>&1:将标准错误输出也重定向到标准输出,即同样写入nohup.out
  • &:让命令在后台运行。 执行后,你可以用tail -f nohup.out来实时查看应用启动日志,就像在IDE里看控制台一样。

方法二:使用systemd服务(更专业、推荐)systemd是Linux系统标准的服务管理器。用它来管理Spring Boot应用,可以实现更精细的控制,如开机自启、自动重启、资源限制等。首先,我们创建一个服务单元文件。

sudo vi /etc/systemd/system/your-app.service

将以下内容写入文件,注意替换DescriptionUserWorkingDirectoryExecStart等参数为你自己的信息:

[Unit] Description=Your Spring Boot Application After=network.target syslog.target [Service] User=your_username # 建议用一个非root用户来运行,更安全 WorkingDirectory=/home/your_app ExecStart=/usr/bin/java -jar /home/your_app/your-project-0.0.1-SNAPSHOT.jar SuccessExitStatus=143 Restart=always # 应用异常退出时自动重启 RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target

保存退出后,执行以下命令来启用并启动这个服务:

# 重新加载systemd配置,使其识别新的服务文件 sudo systemctl daemon-reload # 设置服务开机自启 sudo systemctl enable your-app.service # 立即启动服务 sudo systemctl start your-app.service # 查看服务状态和日志 sudo systemctl status your-app.service sudo journalctl -u your-app.service -f # 实时查看日志

使用systemd管理后,你可以通过systemctl start/stop/restart/status your-app来方便地控制应用的生命周期,并且服务会在服务器重启后自动启动,非常省心。

3.1 验证与故障排查:打通前后端“任督二脉”

后端服务启动后,我们如何验证它是否正常工作,并且前端能成功访问到它呢?

第一步,检查后端服务本身

  1. 查看日志:如果你用nohup,看nohup.out文件;如果用systemd,用journalctl -u your-app.service -f。关注是否有启动成功的标志,比如“Started Application in X seconds”,或者是否有数据库连接失败等错误信息。
  2. 本地测试API:在服务器上,你可以用curl命令直接测试后端API是否可达。
    curl http://localhost:8080/api/health # 假设你有一个健康检查接口
    如果返回预期的JSON数据或状态码,说明后端服务在服务器本地运行正常。

第二步,验证Nginx反向代理: 后端服务在本地(127.0.0.1:8080)跑通了,现在要验证Nginx能否正确地将前端发来的/api/xxx请求转发过来。

  1. 在服务器上,用curl测试经过Nginx转发的请求:
    curl http://localhost/api/health # 注意,这里访问的是Nginx的80端口
    如果这个命令也能返回和上一步相同的结果,恭喜你!说明Nginx的反向代理配置成功了。Nginx成功地将对/api/health的请求,转发给了127.0.0.1:8080端口的Spring Boot应用。

第三步,从前端界面进行完整验证: 现在,回到你的浏览器,刷新之前打开的前端页面(http://你的服务器IP)。尝试进行一个需要调用后端API的操作,比如登录。

  • 如果成功:页面正常跳转,数据正确显示,那么恭喜你,一个完整的Spring Boot + Vue全栈应用已经成功部署上云!
  • 如果失败:打开浏览器的开发者工具(F12),切换到“网络”(Network)标签页,查看失败的API请求。重点关注:
    • 状态码:404(Not Found)可能意味着Nginx的location /api/路径没匹配上,或者后端接口路径不对。502(Bad Gateway)通常意味着Nginx无法连接到后端的Spring Boot服务(后端没启动或端口不对)。504(Gateway Timeout)可能是代理超时设置太短。
    • 请求URL:检查请求是否确实发送到了http://你的服务器IP/api/xxx,而不是本地地址。
    • 控制台错误:查看“控制台”(Console)标签页是否有JavaScript错误。

常见“坑点”与解决方案

  1. 端口被占用:Spring Boot默认端口是8080,确保没有其他程序占用。可以用sudo netstat -tlnp | grep :8080查看。
  2. 防火墙阻拦:虽然我们后端只对本地(127.0.0.1)服务,但确保服务器的防火墙允许80端口(Nginx)入站。对于云服务器,还需要在云服务商的控制台(安全组)中放行80端口。
  3. 文件权限问题:运行Java应用的用户(如用systemd指定的User)必须对JAR包所在目录、日志文件目录、上传文件目录等有读写权限。可以用chownchmod命令修改。
  4. 数据库连接失败:确保服务器上的MySQL服务已启动,并且Spring Boot配置中的数据库用户名、密码、数据库名都正确。可以先用mysql -u username -p命令在服务器上尝试连接数据库。
  5. 前端路由刷新404:这几乎100%是因为Nginx中缺少try_files $uri $uri/ /index.html;这行配置。请务必在托管前端静态资源的location /块中加上它。

部署的过程就是不断遇到问题、解决问题的过程。每解决一个报错,你对整个系统的理解就会加深一层。当你在浏览器中看到自己开发的应用在公网上流畅运行时,那种成就感是非常棒的。记住,第一次部署可能会花些时间,但流程跑通后,以后再部署新版本就会非常快了,无非就是打包、上传、重启服务这几个步骤。

http://www.cnnetsun.cn/news/1252859.html

相关文章:

  • GTE-Chinese-Large一文详解:中文词粒度与短语语义在向量空间的分布特征
  • 企业级Dify Rerank架构设计(含可观测性埋点规范):覆盖Embedding对齐、Query改写、Score归一化全链路的8层校验机制
  • Unity资产处理全流程解析:从环境搭建到高级应用
  • Qwen2.5-7B-Instruct快速上手:基于vllm部署,chainlit可视化界面调用
  • EVA-01作品分享:基于Qwen2.5-VL的视觉神经同步系统效果展示
  • MT5中文改写工具效果实测:对抗样本生成能力与鲁棒性压力测试
  • STM32U5 Stop与Standby低功耗模式深度解析与工程实践
  • 3大核心场景+5步实施:HTTrack高效实现网站镜像与本地化存储全指南
  • PyWxDump高效实战全攻略:微信聊天记录备份与迁移工具深度指南
  • HSP硬件信号处理器全栈驱动与事件协同机制解析
  • Speech Seaco Paraformer效果展示:专业术语识别准确率提升30%实录
  • Janus-Pro-7B多模态实战:医疗报告图片→症状识别→通俗化解释
  • Java开发者必看!2026大模型转型全攻略:从零基础到实战收藏指南
  • Qwen3-TTS开源大模型:游戏NPC多语种语音实时生成技术方案
  • MiniCPM-o-4.5-nvidia-FlagOS赋能微信小程序:打造智能客服前端
  • PDF-Parser-1.0开源模型架构深度解析
  • 7个你必须知道的GPX Studio免费功能:完整编辑GPS轨迹的在线解决方案
  • 5个步骤掌握LDBlockShow:从入门到实战
  • Linux容器基石:LXC核心概念与实践指南
  • STM32H7 ADC共用寄存器原理与多ADC同步工程实践
  • 从此告别拖延! 降AIGC工具 千笔AI VS 知文AI
  • 建议收藏|千笔AI,继续教育论文写作救星
  • 造相-Z-Image-Turbo亚洲美女LoRA效果实测:快速生成惊艳人像作品
  • VSCode插件MarsCode AI:从安装到实战,解锁AI编程新范式
  • 新手友好:零基础使用快马AI构建个人编程资源库
  • 从零到一:基于Hadoop的Hive安装与元数据库配置实战
  • Meixiong Niannian画图引擎入门指南:Streamlit界面响应式布局与移动端适配
  • 显卡风扇智能控制:突破转速限制的完整指南
  • 从选题到见刊:Paperxie 期刊论文智能写作,让普通期刊 / 核心 / SCI 发表少走 3 年弯路
  • 从 0 到 1 发期刊:Paperxie 期刊论文写作功能实测,帮你搞定核心 / SCI 投稿全流程