前言
本文记录了将一个 Spring Boot 3 + Vue 3 博客系统从本地开发环境部署到阿里云轻量应用服务器的完整过程,涵盖环境搭建、项目打包、文件上传、服务配置等所有步骤,以及部署过程中踩过的坑和解决方案。
技术栈:Spring Boot 3.3.5 + MyBatis-Plus 3.5.7 + Vue 3 + Vite + Element Plus + MySQL 8 + Nginx
服务器:阿里云轻量应用服务器 2核2G,CentOS 8.2 系统
工具:Xshell(SSH 连接)、Xftp(文件传输)
一、服务器购买与初始化
1.1 购买服务器
- 登录阿里云控制台,购买轻量应用服务器
- 配置选择:2核2G,40GB SSD,200M 峰值带宽
- 系统镜像选择 CentOS 8.2(注意:不要选"应用镜像",选"系统镜像")
- 地域选择离自己近的(华东/华南/华北)
1.2 重置密码
购买完成后:
- 进入轻量应用服务器控制台
- 点击实例进入详情页
- 服务器信息卡片 →重置密码
- 设置 root 密码并记牢
1.3 放行端口
实例详情 →防火墙选项卡 → 添加规则:
| 应用类型 | 协议 | 端口范围 | 说明 |
|---|---|---|---|
| 自定义 | TCP | 80 | HTTP |
| 自定义 | TCP | 443 | HTTPS |
| 自定义 | TCP | 22 | SSH(通常默认已开) |
1.4 记录公网 IP
实例卡片上直接显示公网 IP,形如47.xxx.xxx.xxx,后面到处都要用。
二、Xshell 连接服务器
2.1 新建会话
- 打开 Xshell → 文件 → 新建
- 名称:随意(如"阿里云博客")
- 协议:SSH
- 主机:你的公网 IP
- 端口:22
- 用户身份验证:方法选 Password,用户名
root,密码为上一步设置的 - 点击连接 → 弹出密钥保存选"接受并保存"
- 看到
[root@iZxxx ~]#表示连接成功
2.2 Xshell 使用技巧
- 粘贴:在 Xshell 里右键即粘贴
- 复制:选中文字即自动复制到剪贴板
- 多行命令可以整段粘贴,Xshell 会自动逐行执行
三、系统初始化(CentOS 8 必做)
3.1 修复 yum 源(⚠️ CentOS 8 已停止维护,必须先换源)
CentOS 8 已于 2021 年底 EOL(End of Life),官方源全部失效,直接dnf install会报 404。必须先换成阿里云 vault 源:
# 备份原源 mkdir -p /etc/yum.repos.d/bak mv /etc/yum.repos.d/CentOS-*.repo /etc/yum.repos.d/bak/ # 写入阿里云 vault 源(8.5.2111 是 CentOS 8 最终归档版本) cat > /etc/yum.repos.d/CentOS-Vault.repo <<'EOF' [baseos] name=CentOS-8.5.2111 - BaseOS baseurl=https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/ gpgcheck=0 enabled=1 [appstream] name=CentOS-8.5.2111 - AppStream baseurl=https://mirrors.aliyun.com/centos-vault/8.5.2111/AppStream/x86_64/os/ gpgcheck=0 enabled=1 [extras] name=CentOS-8.5.2111 - Extras baseurl=https://mirrors.aliyun.com/centos-vault/8.5.2111/extras/x86_64/os/ gpgcheck=0 enabled=1 EOF dnf clean all && dnf makecache3.2 添加 2G 交换分区(2G 内存服务器推荐)
2G 内存跑 MySQL + Java 容易 OOM,建议加 2G swap:
dd if=/dev/zero of=/swapfile bs=1M count=2048 chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo '/swapfile swap swap defaults 0 0' >> /etc/fstab free -h看到Swap一行显示2.0Gi即成功。
四、安装 Nginx + MySQL 8
4.1 安装
dnf install -y nginx mysql-server tar wget systemctl enable --now nginx mysqld验证安装成功:
nginx -v mysql --versionCentOS 8 自带 MySQL 8.0.21,符合项目要求。
4.2 设置 MySQL 密码
mysql进入mysql>提示符后,逐行执行(密码需满足:8位以上 + 大小写字母 + 数字 + 特殊符号):
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Blog@2026Mysql'; FLUSH PRIVILEGES; exit验证新密码:
mysql -uroot -pBlog@2026Mysql -e "SELECT '登录成功';"4.3 限制 MySQL 内存(2G 机器建议)
cat > /etc/my.cnf.d/blog-tune.cnf <<'EOF' [mysqld] innodb_buffer_pool_size=256M max_connections=50 EOF systemctl restart mysqld五、安装 JDK 17(⚠️ CentOS 8 源里只有 JDK 11,必须手动装)
Spring Boot 3 要求 JDK 17+,CentOS 8 的源最高只有 JDK 11,需要从镜像站手动下载。
5.1 下载 JDK 17
cd /opt 方式一:清华镜像(自动获取最新版本文件名) JDK_FILE=$(curl -s https://mirrors.tuna.tsinghua.edu.cn/Adoptium/17/jdk/x64/linux/ | grep -oP 'OpenJDK17U-jdk_x64_linux_hotspot_[0-9._]+.tar.gz' | sort -uV | tail -1) echo "解析到文件名: $JDK_FILE" if [ -n "$JDK_FILE" ]; then wget "https://mirrors.tuna.tsinghua.edu.cn/Adoptium/17/jdk/x64/linux/$JDK_FILE" else 方式二:华为云镜像(固定版本 17.0.2) echo "清华镜像不可用,使用华为云镜像..." curl -L -o jdk17.tar.gz "https://repo.huaweicloud.com/openjdk/17.0.2/openjdk-17.0.2_linux-x64_bin.tar.gz" fi5.2 解压并配置
tar -xzf OpenJDK17U-jdk_x64_linux_hotspot_*.tar.gz # 或 tar -xzf jdk17.tar.gz(取决于用的哪个镜像) JDK_DIR=$(find /opt -maxdepth 1 -type d -name 'jdk-17*' | sort -V | tail -1) ln -sfn "$JDK_DIR" /opt/jdk-17 /opt/jdk-17/bin/java -version看到输出openjdk version "17.0.x"即安装成功。
六、本地打包
6.1 后端打包
在本地 PowerShell 中执行(路径切换到你的项目目录):
cd d:\代码\code\blog\blog-server mvn clean package -DskipTests⚠️ 如果报Failed to delete target\blog-server-1.0.0.jar,是因为本地后端还在运行占用了 jar 文件。先在 IDE 中停止后端进程,再重新打包。打包成功后生成:target\blog-server-1.0.0.jar(约 28MB)
6.2 前端打包
cd d:\代码\code\blog\blog-web npm run build打包成功后生成dist\目录,压缩方便上传:
cd dist tar -czf ..\dist.tar.gz . cd ..前端代码不需要改任何东西:axios 的baseURL: '/api'是相对路径,生产环境由 Nginx 负责转发。6.3 准备数据库脚本
确保schema.sql文件可用(项目src/main/resources/db/目录下)。
七、Xftp 上传文件
7.1 连接 Xftp
- 打开 Xftp → 文件 → 新建
- 主机/协议/用户名/密码与 Xshell 填的完全一样
- 连接后:左边是你电脑,右边是服务器
7.2 服务器建目录
先在 Xshell 中执行:
mkdir -p /opt/blog/uploads /opt/blog/backup7.3 上传三个文件
在 Xftp 右边导航到/opt/blog/,把以下文件从左边拖到右边:
| 本地文件 | 上传到 |
|---|---|
blog-server\target\blog-server-1.0.0.jar | /opt/blog/ |
blog-web\dist.tar.gz | /opt/blog/ |
blog-server\src\main\resources\db\schema.sql | /opt/blog/ |
等进度条全部 100% 后完成。
八、服务器部署(回到 Xshell)
8.1 解压前端 + 导入数据库
# 解压前端 mkdir -p /opt/blog/dist tar -xzf /opt/blog/dist.tar.gz -C /opt/blog/dist/ 导入数据库(schema.sql 自带 CREATE DATABASE 和 USE 语句) mysql -uroot -pBlog@2026Mysql < /opt/blog/schema.sql 验证表是否创建成功 mysql -uroot -pBlog@2026Mysql -e "USE blog; SHOW TABLES;"应看到 5 张表:article、article_tag、category、comment、user。
8.2 创建后端生产配置
cat > /opt/blog/application-prod.yml <<'EOF' server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: Blog@2026Mysql servlet: multipart: max-file-size: 5MB max-request-size: 10MB mybatis-plus: configuration: map-underscore-to-camel-case: true global-config: db-config: id-type: auto logic-delete-field: "" jwt: secret: kkkyBlogChangeThisToYourOwnLongRandomSecretString20260914abcdXYZ expire: 86400000 header: Authorization file: upload-dir: /opt/blog/uploads access-prefix: /uploads allowed-extensions: jpg,jpeg,png,gif,webp max-size: 5242880 EOF chmod 600 /opt/blog/application-prod.yml⚠️ 必须把password改成你实际设置的 MySQL 密码,jwt.secret换成你自己的随机字符串。
8.3 注册系统服务(开机自启 + 崩溃自动重启)
cat > /etc/systemd/system/blog.service <<'EOF' [Unit] Description=Blog Backend After=network.target mysqld.service [Service] User=root WorkingDirectory=/opt/blog ExecStart=/opt/jdk-17/bin/java -jar /opt/blog/blog-server-1.0.0.jar --spring.profiles.active=prod Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now blog8.4 验证后端启动
# 查看服务状态 systemctl is-active blog 等待 20 秒后测试接口(2G 机器启动慢) sleep 20 curl http://127.0.0.1:8080/api/categoriesis-active输出active→ 服务运行中curl返回 JSON 数据 → 后端正常
如果返回Connection refused,可能启动较慢,再等一会儿重试。如果持续失败,查看日志:journalctl -u blog -n 100 --no-pager8.5 配置 Nginx
# 备份并注释默认 server 块(否则抢占 80 端口显示欢迎页) cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak