项目概述:本文记录一个完整的前后端分离个人博客项目部署流程。后端采用 Spring Boot + MyBatis-Plus + MySQL 8.0,前端为 Vue 3,通过 Nginx 反向代理实现生产环境部署。适合有一定编程基础、想从零搭建个人博客的开发者参考。


前言

拥有一个独立的个人博客,既能沉淀技术积累,也是面试时的加分项。本文涉及的项目是一套完整的前后端分离博客系统,支持 Markdown 编辑、图片粘贴上传、分类标签管理等功能。

整个部署流程分为:服务器准备 → 环境安装 → 数据库配置 → 后端部署 → 前端构建 → Nginx 代理 → 安全组配置。下面按步骤详细展开。


一、服务器选购与系统准备

1.1 服务器配置建议

对于个人博客这类轻量级应用,最低配置即可流畅运行:

配置项 建议 说明
CPU/内存 2核2G 支撑 Spring Boot + MySQL + Nginx 足够
带宽 3Mbps 个人博客访问量不大,3M 完全够用
系统盘 40GB SSD 代码 + 数据库 + 图片备份
操作系统 Ubuntu 22.04 LTS 社区支持好,文档丰富

成本优化建议:如果是新用户,阿里云轻量应用服务器目前有特惠活动,2核2G3M 配置低至 38 元/年,很适合个人开发者练手和小型项目部署。有需求的朋友可以通过官方活动页面了解详情:
https://www.aliyun.com/minisite/goods?userCode=iakscw7s
建议先登录找到服务器购买位置,再定个闹钟,每天9:55,14:55,提前5分钟进去,准备狂点,不然可能抢不到。
在这里插入图片描述

1.2 连接服务器

购买完成后,在阿里云控制台重置实例密码,然后通过 SSH 连接:

ssh root@你的公网IP

首次登录建议更新系统:

sudo apt update && sudo apt upgrade -y

二、基础环境安装

按顺序安装 JDK、Maven、Node.js、MySQL 和 Nginx。

2.1 JDK 17

sudo apt install openjdk-17-jdk -y
java -version

2.2 Maven

sudo apt install maven -y
mvn -v

2.3 Node.js 20.x(重要!)

注意:必须使用 Node.js 20+,18.x 版本在构建时会出现兼容性问题。

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install nodejs -y
node -v   # 确认输出 v20.x.x
npm -v

2.4 MySQL 8.0

sudo apt install mysql-server -y
sudo systemctl start mysql
sudo systemctl enable mysql
sudo systemctl status mysql  # 确认状态为 active

2.5 Nginx

sudo apt install nginx -y
sudo systemctl start nginx

三、MySQL 配置(易踩坑环节)

Ubuntu 下 MySQL 8.0 的 root 用户默认使用 auth_socket 认证插件,这会导致后端 JDBC 连接时频繁报错。建议创建独立的数据库用户,避免使用 root。

3.1 创建数据库与用户

sudo mysql -u root

在 MySQL 命令行中执行:

CREATE DATABASE IF NOT EXISTS personal_blog 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;

CREATE USER 'blog'@'localhost' IDENTIFIED WITH mysql_native_password BY 'blog123456';

GRANT ALL PRIVILEGES ON personal_blog.* TO 'blog'@'localhost';
FLUSH PRIVILEGES;
EXIT;

3.2 验证连接

mysql -u blog -p'blog123456' -e "USE personal_blog; SELECT 1;"

返回 1 即表示数据库和用户配置正确。这一步务必通过后再往下进行,否则后端启动时会报 CannotGetJdbcConnectionException

3.3 导入初始化数据

将项目中的 init.sql 上传到服务器,执行:

mysql -u blog -p'blog123456' < init.sql

验证表结构:

mysql -u blog -p'blog123456' -e "USE personal_blog; SHOW TABLES;"

正常应输出 bloguser 两张表。


四、项目上传与目录结构

/opt 下创建项目目录:

mkdir -p /opt/projects
cd /opt/projects

# 上传项目压缩包后解压
unzip personal-blog.zip
cd personal-blog

预期目录结构如下:

/opt/projects/personal-blog/
├── blog-server/          # Spring Boot 后端
│   ├── src/
│   ├── target/
│   └── uploads/          # 图片上传目录(需手动创建)
├── blog-web/             # Vue3 前端
│   └── dist/             # 构建产物目录
├── init.sql              # 数据库初始化脚本
└── ...

五、后端部署与配置

5.1 修改数据库配置

cd /opt/projects/personal-blog/blog-server
vim src/main/resources/application.yml

关键配置项如下(务必根据实际情况修改):

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/personal_blog?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
    username: blog              # 第3步创建的专用用户
    password: 'blog123456'      # 密码用单引号包裹,防止特殊字符解析错误
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true

jwt:
  secret: your-256-bit-secret-key-for-jwt-signing-must-be-at-least-32-characters-long
  expiration: 604800000

upload:
  path: /opt/projects/personal-blog/blog-server/uploads/
  max-size: 10485760

配置要点说明:

  • allowPublicKeyRetrieval=true:MySQL 8.0 必须加,否则连接失败
  • password 加单引号:如果密码包含 # 等特殊字符,YAML 解析会出错
  • upload.path 使用绝对路径:确保图片上传后 Nginx 能正确定位

5.2 编译打包

cd /opt/projects/personal-blog/blog-server
mvn clean package -DskipTests -q

打包完成后会在 target/ 目录下生成 blog-server-1.0.0.jar

5.3 创建上传目录

mkdir -p /opt/projects/personal-blog/blog-server/uploads/
chmod 755 /opt/projects/personal-blog/blog-server/uploads/

5.4 启动后端

测试阶段建议前台启动,便于观察日志:

java -jar target/blog-server-1.0.0.jar

看到 Started PersonalBlogApplication 且无报错后,Ctrl+C 停止,改为后台运行:

nohup java -jar target/blog-server-1.0.0.jar > /opt/projects/personal-blog/blog.log 2>&1 &

5.5 验证后端接口

curl http://localhost:8080/api/blog/list

返回如下 JSON 即表示后端运行正常:

{"code":200,"message":"success","data":{"total":0,"pages":0,"current":1,"size":10,"records":[]}}

六、前端构建

6.1 安装依赖并构建

cd /opt/projects/personal-blog/blog-web
npm install
npm run build

构建完成后会生成 dist/ 目录,里面是可用于生产环境的静态文件。

6.2 确认构建产物

ls -la /opt/projects/personal-blog/blog-web/dist/

应包含 index.htmlassets/ 等文件。


七、Nginx 配置(核心环节)

Nginx 在这里承担三个职责:托管前端静态资源反向代理后端 API提供图片访问入口

7.1 创建站点配置文件

sudo tee /etc/nginx/sites-available/blog <<'EOF'
server {
    listen 80;
    server_name _;  # 如有域名,此处替换为你的域名

    # 前端静态资源
    location / {
        root /opt/projects/personal-blog/blog-web/dist;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    # 图片上传目录(必须配置,否则博客图片无法加载)
    location /uploads/ {
        alias /opt/projects/personal-blog/blog-server/uploads/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # 后端 API 代理(注意 proxy_pass 末尾的 /api/ 不可省略)
    location /api/ {
        proxy_pass http://localhost: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;
    }
}
EOF

配置要点说明:

配置段 作用 常见错误
location / 托管 Vue 打包后的静态文件 try_files 不加会导致刷新 404
location /uploads/ 直接映射图片目录到 URL 不配置会导致博客图片无法展示
location /api/ 将前端请求转发到 8080 端口 proxy_pass 末尾缺少 /api/ 会导致接口 404

7.2 启用配置

# 删除默认站点,避免冲突
sudo rm -f /etc/nginx/sites-enabled/default

# 启用博客站点
sudo ln -sf /etc/nginx/sites-available/blog /etc/nginx/sites-enabled/blog

# 检查配置语法并重启
sudo nginx -t
sudo systemctl restart nginx

7.3 验证 Nginx 代理

# 验证 API 代理是否正常
curl http://localhost/api/blog/list

# 验证图片路径是否可访问
curl -I http://localhost/uploads/

八、安全组与防火墙配置

8.1 云服务器安全组(必须!)

登录阿里云控制台 → ECS → 安全组 → 配置规则,添加以下入方向规则

类型 端口 源地址 说明
HTTP 80 0.0.0.0/0 网站访问
HTTPS 443 0.0.0.0/0 后续配置 SSL 使用
自定义TCP 8080 127.0.0.1/32 仅本机访问后端(可选)

8.2 服务器本地防火墙

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

九、访问与验证

完成以上步骤后,通过浏览器访问:

地址 说明
http://你的公网IP 博客首页
http://你的公网IP/login 管理后台登录页

默认管理员账号:

  • 用户名:admin
  • 密码:admin123

建议登录后立即修改默认密码。


十、域名与备案(可选进阶)

如果希望使用域名访问(如 www.yourblog.com),需要:

  1. 购买域名:在阿里云万网或其他域名服务商注册
  2. 域名解析:添加 A 记录指向你的 ECS 公网 IP
  3. ICP 备案:中国内地服务器必须备案,流程约 7-20 个工作日
  4. 配置 HTTPS:在阿里云申请免费 SSL 证书,配置 Nginx 443 端口

备案期间网站需关闭访问或显示"备案中"页面,建议提前规划。


十一、常见问题汇总

Q1:后端启动报错 CannotGetJdbcConnectionException

按以下顺序排查:

  1. sudo systemctl status mysql 确认 MySQL 运行中
  2. mysql -u blog -p'密码' -e "SELECT 1;" 确认用户密码正确
  3. 检查 application.yml 中密码是否加了单引号
  4. 确认 JDBC URL 包含 allowPublicKeyRetrieval=true
  5. 确认使用的是 blog 用户而非 root

Q2:登录或调用接口返回 404

检查 Nginx 配置中 proxy_pass http://localhost:8080/api/; 末尾是否遗漏了 /api/

Q3:博客中上传的图片无法显示

  1. 确认 application.ymlupload.path 是绝对路径
  2. 确认 Nginx 中有 location /uploads/ 配置段
  3. 确认 alias 路径末尾有 /
  4. 执行 sudo systemctl restart nginx

Q4:前端构建报错 EBADENGINE

Node.js 版本过低,必须升级到 20.x。

Q5:Vue 路由刷新后 404

Nginx 的 location / 中缺少 try_files $uri $uri/ /index.html;


十二、运维常用命令

# 实时查看后端日志
tail -f /opt/projects/personal-blog/blog.log

# 重启后端服务
pkill -f blog-server
cd /opt/projects/personal-blog/blog-server
nohup java -jar target/blog-server-1.0.0.jar > /opt/projects/personal-blog/blog.log 2>&1 &

# 重启 Nginx
sudo systemctl restart nginx

# 查看端口占用
ss -tlnp | grep -E '80|8080'

# 查看 Nginx 错误日志
sudo tail -n 20 /var/log/nginx/error.log

总结

整个部署流程的核心在于环境版本匹配(Node 20+、MySQL 8.0 专用用户)和Nginx 代理路径的正确配置。只要按照文档中的顺序操作,大部分问题都可以避免。

对于想尝试独立部署全栈项目的朋友,这套博客系统是一个很好的练手项目。服务器成本方面,新用户选择阿里云的活动机型,一年几十元的投入即可获得完整的 Linux 服务器环境,性价比很高。

如果在部署过程中遇到其他问题,欢迎在评论区交流。


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐