从零开始搭建、部署个人博客指南
Person_Web 是一个基于 **React 19 + Express + tRPC + MySQL** 的现代化全栈个人博客系统。本项目采用 Docker 容器化部署,提供完整的一键部署脚本,让你可以快速在云服务器上搭建属于自己的技术博客。
从零开始搭建、部署个人博客指南
📖 前言
项目简介
Person_Web 是一个基于 React 19 + Express + tRPC + MySQL 的现代化全栈个人博客系统。本项目采用 Docker 容器化部署,提供完整的一键部署脚本,让你可以快速在云服务器上搭建属于自己的技术博客。
📝 项目信息
📝 开源地址:Person_Web
🎯 在线演示:zhcmqtt.top
📅 最后更新:2026-02-24
🚀 部署目标:将个人博客部署到云服务器(华为云、阿里云、腾讯云等)
⏱️ 预计耗时:首次部署约 30-60 分钟(含服务器配置)
📸 项目截图
个人页面
首页展示
文章详情页
🎯 适合人群
本教程适合以下人群:
- ✅ 技术爱好者:有基本的编程基础和 Linux 命令行使用经验
- ✅ 内容创作者:需要一个稳定、美观的博客平台来发布技术文章
⭐ 项目特点
🚀 技术栈先进
- 前端:React 19 + TypeScript + Vite + TailwindCSS
- 后端:Express + tRPC
- 数据库:MySQL 8.0 + Drizzle ORM
- 数据可视化:Recharts(图表统计)
- SEO:React Helmet + JSON-LD + Open Graph + XML Sitemap
- 部署:Docker + Docker Compose + Nginx + Let’s Encrypt
🎨 功能完整
- ✅ Markdown 编辑器,支持代码高亮和实时预览
- ✅ 文章分类管理、标签系统
- ✅ 响应式设计,完美适配移动端
- ✅ 暗黑模式支持
- ✅ GitHub OAuth 认证,安全可靠
- ✅ 图片上传和管理
- ✅ 文档系统(支持技术文档编写)
- ✅ SEO 优化(Open Graph、JSON-LD 结构化数据、XML Sitemap)
- ✅ 数据分析仪表盘(页面浏览量、访客统计、趋势图表)
- ✅ 文章目录导航(自动生成、滚动高亮、平滑跳转)
- ✅ 页面浏览追踪与文章阅读统计
- ✅ 数据库自动备份与数据导入导出
🛠️ 部署简单
- ✅ 一键部署脚本:自动化完成所有配置
- ✅ Docker 容器化:环境隔离,避免依赖冲突
- ✅ 详细文档:每一步都有清晰的说明和截图
- ✅ 国内优化:提供镜像加速方案,解决网络问题
- ✅ HTTPS 支持:自动申请和续期 SSL 证书
💰 成本低廉
- 云服务器:2核2G 配置约 100-300 元/年
- 域名:.top/.xyz 等域名约 10-50 元/年
- SSL 证书:Let’s Encrypt 免费证书
- 总成本:约 110-350 元/年即可拥有专业博客
📊 部署效果
部署完成后,你将拥有:
- 🌐 一个可通过域名访问的个人博客网站
- 🔒 HTTPS 加密连接,绿色安全锁标识
- 📝 功能完整的后台管理系统
- 📱 完美适配 PC、平板、手机的响应式界面
- ⚡ 快速的页面加载速度(内置缓存优化)
- 🔐 安全的 GitHub OAuth 认证
- 📊 数据分析仪表盘,实时掌握访问数据
- 🔍 SEO 优化,搜索引擎友好
部署架构简介
📋 目录
- 第一步:准备云服务器
- 第二步:一键配置服务器环境
- 第三步:配置云服务商安全组
- 第四步:上传项目代码
- 第五步:配置个人信息(重要)
- 第六步:配置环境变量
- 第七步:一键部署应用
- 第八步:访问你的博客
- 第九步:配置域名和 HTTPS(可选)
- 新增功能说明(数据分析、SEO、目录导航)
- 数据库自动备份和迁移
- 项目升级
- 日常维护指南
一、准备云服务器
1.1 购买云服务器
你可以选择以下任一云服务商:
- 华为云:https://www.huaweicloud.com/
- 阿里云:https://www.aliyun.com/
- 腾讯云:https://cloud.tencent.com/
推荐配置:
| 配置项 | 最低要求 | 说明 |
|---|---|---|
| CPU | 2 核心 | 保证应用流畅运行 |
| 内存 | 2GB | 足够运行 Docker 容器 |
| 磁盘 | 20GB | 存储系统、应用和数据库 |
| 操作系统 | Ubuntu 22.04 LTS | 推荐使用 Ubuntu |
| 带宽 | 1Mbps | 个人博客足够使用 |
💡 小贴士:新用户通常有优惠活动,2核2G配置一年大约 100-300 元。
1.2 购买域名(可选但推荐)
如果你想使用自己的域名(如 myblog.com),需要:
- 在域名注册商购买域名(如阿里云、腾讯云、GoDaddy)
- 将域名解析到你的服务器 IP 地址
域名解析步骤:
1. 登录域名管理控制台
2. 找到 DNS 解析设置
3. 添加 A 记录:
- 主机记录:@ (代表根域名)
- 记录类型:A
- 记录值:你的服务器公网 IP
4. 添加 A 记录:
- 主机记录:www
- 记录类型:A
- 记录值:你的服务器公网 IP
💡 小贴士:如果暂时没有域名,可以先使用服务器 IP 地址访问,后续再配置域名。
1.3 连接到服务器
使用 SSH 连接到你的服务器:
Windows 用户:
# 使用 PowerShell 或 Windows Terminal
ssh root@你的服务器IP
# 例如:ssh root@123.45.67.89
Mac/Linux 用户:
# 使用终端
ssh root@你的服务器IP
首次连接会提示是否信任服务器,输入 yes 并回车,然后输入服务器密码。
✅ 成功标志:看到类似 root@hostname:~# 的命令提示符。
二、一键配置服务器环境
项目提供了一键配置脚本,可以自动完成 Docker、Nginx 和防火墙的安装配置。
2.1 创建项目目录
# 创建项目目录
sudo mkdir -p /opt/Person_Web
# 设置目录所有者为当前用户
sudo chown -R $USER:$USER /opt/Person_Web
# 进入项目目录
cd /opt/Person_Web
2.2 上传项目到服务器
方法一:使用 GitHub 镜像加速(推荐,适用于国内服务器)
如果你的云服务器无法直接访问 GitHub,可以使用以下镜像加速服务:
# 安装 Git(如果未安装)
sudo apt install -y git
# 方案 1:使用 ghproxy.com 镜像(推荐)
git clone https://ghproxy.com/https://github.com/zhanghongchen1213/Person_Web /opt/Person_Web
# 方案 2:使用 gitclone.com 镜像
git clone https://gitclone.com/github.com/zhanghongchen1213/Person_Web /opt/Person_Web
# 方案 3:使用 fastgit 镜像
git clone https://hub.fastgit.xyz/zhanghongchen1213/Person_Web /opt/Person_Web
# 进入项目目录
cd /opt/Person_Web
💡 小贴士:
- 镜像服务可能会有延迟,建议优先尝试 ghproxy.com
- 如果一个镜像失败,可以尝试其他镜像
- 镜像服务仅用于克隆,后续 git 操作会自动使用原始仓库地址
方法二:手动上传代码(备选方案)
如果 Git 克隆始终失败,可以手动上传代码:
-
在本地下载项目:
- 访问 https://github.com/zhanghongchen1213/Person_Web
- 点击 “Code” → “Download ZIP”
- 解压到本地
-
上传到服务器并解压
unzip Person_Web-main.zip rm -rf Person_Web-main.zip cd Person_Web-main
2.3 配置网络环境(重要,适用于国内服务器)
⚠️ 重要提示:如果你的云服务器在国内,或者无法正常访问 GitHub、Docker Hub 等国外资源,必须先执行此步骤配置镜像源,否则后续安装可能会失败或非常缓慢。
项目提供了网络环境配置脚本,可以自动配置国内镜像源,解决网络访问问题。
# 进入项目目录
cd /opt/Person_Web
# 赋予脚本执行权限
chmod +x deploy/scripts/*
# 执行网络环境配置脚本
sudo bash deploy/scripts/setup-network.sh
脚本会自动完成以下配置:
- ✅ APT 软件源 - 切换到阿里云镜像,加速软件包下载
- ✅ Docker 镜像源 - 配置国内镜像加速器(腾讯云、DaoCloud、DockerProxy)
- ✅ Git 配置优化 - 禁用 HTTP/2,增加缓冲区,解决克隆失败问题
- ✅ npm 镜像源 - 配置淘宝镜像(如已安装 npm)
✅ 预期输出:
💡 配置效果:
- ✅ APT 软件包下载速度提升 10-50 倍
- ✅ Docker 镜像拉取速度提升 10-100 倍
- ✅ Git 克隆成功率接近 100%
- ✅ npm 包安装速度提升 5-20 倍
2.4 执行服务器环境配置脚本
# 执行服务器环境配置脚本
sudo bash deploy/scripts/setup-server.sh
脚本会自动完成以下操作:
- ✅ 更新系统软件包 - 更新 apt 软件包列表
- ✅ 安装 Docker - 使用官方脚本安装 Docker 和 Docker Compose
- ✅ 配置 Docker 权限 - 将当前用户添加到 docker 组
- ✅ 安装 Nginx - 安装并启动 Nginx 服务
- ✅ 配置防火墙 - 开放必要端口(22, 80, 443)
- ✅ 验证安装 - 测试所有服务是否正常运行
2.5 预期输出
三、配置云服务商安全组
除了服务器防火墙,还需要在云服务商控制台配置安全组:
- 登录云服务商控制台
- 找到你的服务器实例
- 进入"安全组"或"防火墙"设置
- 添加入站规则:
- 端口 22(SSH)
- 端口 80(HTTP)
- 端口 443(HTTPS)
⚠️ 安全警告:绝对不要开放 3306 端口(MySQL)到公网! 数据库端口暴露会导致被黑客扫描攻击,造成数据丢失。本项目已配置 MySQL 仅监听本地地址(127.0.0.1),无需在安全组开放 3306 端口。
💡 小贴士:不同云服务商的界面略有不同,但操作逻辑相同。
四、配置个人信息(重要)
⚠️ 重要提示:在部署之前,你需要将项目中的示例个人信息替换为你自己的信息。
4.1 使用一键配置脚本(推荐)
项目提供了交互式个人信息配置脚本,可以自动替换所有相关文件中的个人信息。
cd Person_Web-main
bash deploy/scripts/setup-personal-info.sh
脚本会提示你输入以下信息:
- GitHub 用户名:你的 GitHub 用户名(用于头像和个人主页链接)
- 域名:你的博客域名(如
myblog.com) - 邮箱地址:你的联系邮箱
- 微信号:你的微信号(可选)
4.2 手动替换(备选方案)
如果你不想使用脚本,也可以手动替换以下文件中的个人信息:
需要替换的文件:
client/src/pages/About.tsx- 关于页面client/src/components/Footer.tsx- 页脚组件README.md- 项目文档
需要替换的信息:
zhanghongchen1213→ 你的 GitHub 用户名zhcmqtt.top→ 你的域名admin@zhcmqtt.top→ 你的邮箱zhang_hongchen→ 你的微信号
💡 小贴士:使用脚本替换更安全,可以避免遗漏。
五、配置环境变量
环境变量包含了应用运行所需的配置信息,如数据库密码、JWT 密钥等。
5.1 使用一键配置脚本(推荐)
项目提供了交互式环境变量配置脚本,可以自动生成强密码并创建配置文件。
⚠️ 重要提示:为了确保博客安全,强烈推荐使用 GitHub OAuth 认证,这样只有你的 GitHub 账号能够登录管理员后台。
步骤 1:创建 GitHub OAuth 应用(推荐)
在运行配置脚本之前,建议先创建 GitHub OAuth 应用以获取必要的认证参数。
- 访问 GitHub Developer Settings
- 点击 “New OAuth App” 创建新应用
- 填写应用信息:
- Application name: 你的博客名称(如 “My Personal Blog”)
- Homepage URL:
https://你的域名 - Authorization callback URL:
https://你的域名/api/auth/github/callback
- 点击 “Register application”
- 记录下 Client ID 和 Client Secret(稍后配置时需要)
- 获取你的 GitHub 用户 ID:
- 访问
https://api.github.com/users/你的GitHub用户名 - 记录返回的 JSON 中的
id字段值
- 访问
💡 示例:如果你的 GitHub 用户名是 zhangsan,访问 https://api.github.com/users/zhangsan,会看到类似:
{
"id": 12345678,
"login": "zhangsan",
...
}
记录下 id: 12345678,稍后配置时需要填写 github:12345678。
步骤 2:运行配置脚本
# 执行环境变量配置脚本
sudo bash deploy/scripts/setup-env.sh
脚本会交互式地询问你以下配置:
- MySQL root 密码(留空自动生成32位强密码)
- JWT 密钥(留空自动生成32位强密码)
- GitHub OAuth 配置(必须配置,输入上一步获取的参数):
- GitHub Client ID
- GitHub Client Secret
- GitHub Callback URL
- 管理员 GitHub 用户 ID(格式为
github:你的GitHub用户ID)
配置完成后,脚本会自动生成 .env.production 文件。
✅ 预期输出(配置 GitHub OAuth):
🔒 安全优势:
- ✅ 只有你的 GitHub 账号能够登录管理员后台
- ✅ 使用 GitHub 官方 OAuth 认证,安全可靠
- ✅ 无需记忆复杂的登录链接
- ✅ 支持后续添加其他 GitHub 用户为管理员
六、一键部署应用
项目提供了一键部署脚本,会自动完成所有部署步骤。
6.1 执行一键部署
# 执行一键部署脚本
sudo bash deploy/scripts/deploy.sh
⏱️ 预计耗时:10-20 分钟(首次部署需要下载 Docker 镜像,会比较慢,请耐心等待)
5.2 部署过程说明
部署脚本会自动执行以下 8 个步骤:
- ✅ 检查 Docker 环境 - 确保 Docker 和 Docker Compose 已安装
- ✅ 检查配置文件 - 验证
.env.production文件存在且配置正确 - ✅ 停止旧容器 - 如果有旧版本运行,先停止并删除
- ✅ 构建新镜像 - 构建包含最新代码的 Docker 镜像
- ✅ 启动新容器 - 启动应用容器和数据库容器
- ✅ 执行数据库迁移 - 创建数据库表结构
- ✅ 健康检查 - 等待应用启动并验证运行状态
- ✅ 输出部署结果 - 显示部署成功信息和常用命令
5.3 预期输出
5.4 验证部署
检查容器状态
# 查看所有容器状态
docker compose ps
✅ 预期输出:
NAME IMAGE STATUS PORTS
person_web_app person-web:latest Up 2 minutes (healthy) 0.0.0.0:3000->3000/tcp
person_web_mysql mysql:8.0 Up 2 minutes (healthy) 127.0.0.1:3306->3306/tcp
两个容器的状态都应该是 Up 且显示 (healthy)。
查看应用日志
# 查看应用日志(实时)
docker compose logs -f app
✅ 预期输出:应该能看到类似以下的日志:
[INFO] Server running on http://localhost:3000
[INFO] Database connected successfully
按 Ctrl + C 退出日志查看。
测试应用访问
# 测试本地访问
curl http://localhost:3000
✅ 预期输出:返回 HTML 内容(博客首页)
七、配置域名和 HTTPS
⚠️ 本步骤为可选项:如果你没有域名或暂时不需要 HTTPS,可以跳过此步骤。使用 IP 地址访问博客已经完全可以正常使用。
如果你有自己的域名,强烈建议配置 HTTPS 证书,让你的博客更安全、更专业。
6.1 前置准备
在开始配置之前,请确保:
- ✅ 你已经购买了域名(如
myblog.com) - ✅ 域名已经解析到你的服务器 IP 地址
- ✅ 博客已经可以通过 IP 地址正常访问
6.2 配置域名(一键脚本)
项目提供了域名配置脚本,可以自动替换所有配置文件中的域名。
# 执行域名配置脚本
sudo bash deploy/scripts/setup-domain.sh 你的域名
# 例如:bash deploy/scripts/setup-domain.sh zhcmqtt.top
⏱️ 预计耗时:10 秒
脚本会自动完成以下操作:
- ✅ 备份原始配置文件
- ✅ 替换 SSL 证书申请脚本中的域名
- ✅ 创建新的 Nginx 配置文件(使用你的域名)
- ✅ 输出后续操作步骤
6.3 准备 Let’s Encrypt 验证目录
在部署 Nginx 配置前,需要先创建 SSL 证书验证目录:
# 创建 Let's Encrypt 验证目录
sudo mkdir -p /var/www/html/.well-known/acme-challenge
# 设置正确的权限
sudo chmod -R 755 /var/www/html/.well-known
6.4 部署 HTTP Nginx 配置(用于证书申请)
⚠️ 重要:首次配置时,需要先部署 HTTP 配置,申请证书成功后再切换到 HTTPS 配置。
# 删除旧配置(如果存在)
sudo rm -f /etc/nginx/sites-enabled/default
sudo rm -f /etc/nginx/sites-enabled/你的域名.conf
# 例如:sudo rm -f /etc/nginx/sites-enabled/zhcmqtt.top.conf
# 复制 HTTP 配置文件到系统目录
sudo cp deploy/nginx/你的域名.conf /etc/nginx/sites-available/
# 例如:sudo cp deploy/nginx/zhcmqtt.top.conf /etc/nginx/sites-available/
# 创建软链接启用配置
sudo ln -s /etc/nginx/sites-available/你的域名.conf /etc/nginx/sites-enabled/
# 例如:sudo ln -s /etc/nginx/sites-available/zhcmqtt.top.conf /etc/nginx/sites-enabled/
# 测试 Nginx 配置
sudo nginx -t
# 重启 Nginx
sudo systemctl restart nginx
✅ 预期输出:syntax is ok 和 test is successful
验证 HTTP 访问:
# 测试域名访问
curl -I http://你的域名
# 例如:curl -I http://zhcmqtt.top
# 应该返回 HTTP/1.1 200 或看到 HTML 内容
6.5 申请 SSL 证书(一键脚本)
⚠️ 前提条件:确保 HTTP 访问正常后再执行此步骤。
项目提供了 SSL 证书申请脚本,可以自动完成所有步骤。
# 执行 SSL 证书申请脚本
sudo bash deploy/scripts/setup-ssl.sh 你的域名 你的邮箱
# 例如:sudo bash deploy/scripts/setup-ssl.sh zhcmqtt.top admin@zhcmqtt.top
⏱️ 预计耗时:2-3 分钟
脚本会自动完成以下操作:
- ✅ 检查并安装 Certbot
- ✅ 申请 Let’s Encrypt SSL 证书
- ✅ 配置证书自动续期
- ✅ 测试证书续期功能
✅ 成功标志:看到 Congratulations! Your certificate and chain have been saved 消息
6.6 部署 HTTPS Nginx 配置
证书申请成功后,需要切换到 HTTPS 配置:
# 删除 HTTP 配置
sudo rm -f /etc/nginx/sites-enabled/你的域名.conf
# 例如:sudo rm -f /etc/nginx/sites-enabled/zhcmqtt.top.conf
# 复制 HTTPS 配置文件
sudo cp deploy/nginx/你的域名-https.conf /etc/nginx/sites-available/
# 例如:sudo cp deploy/nginx/zhcmqtt.top-https.conf /etc/nginx/sites-available/
# 启用 HTTPS 配置
sudo ln -s /etc/nginx/sites-available/你的域名-https.conf /etc/nginx/sites-enabled/
# 例如:sudo ln -s /etc/nginx/sites-available/zhcmqtt.top-https.conf /etc/nginx/sites-enabled/
# 测试配置
sudo nginx -t
# 重启 Nginx
sudo systemctl restart nginx
6.7 验证 HTTPS 访问
# 测试 HTTPS 访问
curl -I https://你的域名
# 例如:curl -I https://zhcmqtt.top
✅ 预期输出:HTTP/2 200
或者在浏览器中访问 https://你的域名,应该能看到:
- ✅ 绿色锁图标
- ✅ 地址栏显示"安全"或"连接是安全的"
- ✅ HTTP 自动重定向到 HTTPS
6.8 证书自动续期说明
SSL 证书申请脚本已经自动配置了证书续期任务。Let’s Encrypt 证书有效期为 90 天,系统会在到期前自动续期。
你可以手动测试续期功能:
# 测试证书续期(不会真正续期)
sudo certbot renew --dry-run
✅ 预期输出:Congratulations, all simulated renewals succeeded
💡 小贴士:
- 证书会在到期前 30 天自动续期
- 续期失败会发送邮件通知到你配置的邮箱
- 可以使用
sudo certbot certificates查看证书状态
八、访问你的博客
恭喜!你的博客已经部署成功了。现在让我们了解如何访问博客。
💡 提示:如果你还没有域名,可以直接使用服务器 IP 地址访问。域名配置是可选的,可以在第七步中完成。
7.1 使用 域名 访问
访客访问
访客可以通过以下方式访问你的博客:
https://你的域名
例如:https://zhcmqtt.top
💡 访客可以做什么:
- ✅ 浏览所有已发布的博客文章
- ✅ 查看文章分类
- ✅ 搜索文章
- ✅ 查看文档(如果有)
- ❌ 无法创建、编辑或删除文章
管理员访问
作为博客的管理员,你需要使用 GitHub OAuth 登录进行身份验证。
⚠️ 重要提示:在第五步"配置环境变量"时,如果你已经按照推荐方式配置了 GitHub OAuth,可以直接登录。如果还没有配置,请先返回第五步完成 GitHub OAuth 配置。
登录入口
管理员通过 直接访问登录 URL 进行身份验证(普通访客看不到登录按钮):
https://你的域名/api/auth/github/login
例如:https://zhcmqtt.top/api/auth/github/login
开发过程中使用http://localhost:3000/api/dev/login-admin即可进入管理员后台页面
登录流程:
- 在浏览器地址栏输入上述登录 URL
- 自动跳转到 GitHub 授权页面
- 如果该浏览器已登录 GitHub 且之前授权过,会直接完成登录
- 如果未登录 GitHub,需要先登录 GitHub 账号
- 如果是首次授权,需要点击 “Authorize” 确认授权
- 授权成功后自动跳转回博客首页,此时你已登录为管理员
💡 提示:登录状态依赖浏览器的 GitHub 登录状态,不绑定设备。你可以在任何设备上通过此 URL 登录管理后台。
管理员功能入口
登录成功后,你可以访问以下管理页面:
| 功能 | 访问地址 | 说明 |
|---|---|---|
| 写文章 | https://你的域名/write |
创建新的博客文章或文档 |
| 文章管理 | https://你的域名/admin/articles |
编辑、删除、管理所有文章 |
| 数据分析 | https://你的域名/admin/analytics |
查看访问统计和文章阅读数据 |
| 数据库管理 | https://你的域名/admin/database |
数据导出、导入和备份设置 |
💡 管理员可以做什么:
- ✅ 创建新文章(博客或文档)
- ✅ 编辑已有文章
- ✅ 删除文章
- ✅ 管理分类
- ✅ 修改文章发布状态(草稿/已发布/归档)
- ✅ 查看数据分析(访问量、文章阅读统计、趋势图表)
- ✅ 数据库管理(导出、导入、自动备份配置)
✅ 成功标志:
- 访客模式:可以浏览文章,但无法编辑
- 管理员模式:右上角显示你的 GitHub 头像,导航栏出现"写文章"按钮,可以创建和编辑文章
八(附)、新增功能说明
数据分析仪表盘
管理员登录后,可以通过导航栏进入数据分析页面(/admin/analytics),查看博客的访问数据:
- 总览统计:总浏览量、今日浏览量、独立访客数
- 趋势图表:每日访问量趋势(支持 1-365 天范围选择)
- 文章排行:按阅读量排序的热门文章 Top 20
- 页面统计:各页面的访问量分布
数据分析基于 pageViews 表自动记录,访客浏览页面时会静默记录访问数据(IP、路径、时间),不影响用户体验。分析数据使用 1 分钟缓存,兼顾实时性和性能。
SEO 优化
项目内置了完整的搜索引擎优化方案:
- XML Sitemap:自动生成站点地图(
/sitemap.xml),包含所有已发布文章 - Open Graph 标签:文章分享到社交平台时自动展示标题、描述和封面图
- JSON-LD 结构化数据:帮助搜索引擎更好地理解文章内容
- 爬虫检测:自动识别搜索引擎爬虫并返回预渲染内容
- Canonical URL:避免重复内容问题
文章目录导航
文章详情页右侧自动生成目录导航(桌面端可见):
- 自动提取文章中的 h1、h2、h3 标题
- 滚动时高亮当前阅读位置
- 点击目录项平滑跳转到对应章节
九、数据库自动备份和迁移
本项目提供了完整的数据库备份和迁移功能,包括自动定时备份和管理员手动导入导出。
9.1 自动备份功能
系统支持自动定时备份数据库,备份文件保存在服务器的 backups/ 目录中。
自动备份原理
自动备份功能基于 node-cron 实现,在应用启动时根据配置的备份间隔自动执行:
- 每周备份:每周日凌晨 00:00 执行
- 每月备份:每月 1 日凌晨 00:00 执行
- 每季度备份:每季度第一天凌晨 00:00 执行
配置自动备份
- 以管理员身份登录博客
- 访问
https://你的域名/admin/database - 在"自动备份"区域:
- 开启"启用自动备份"开关
- 选择备份间隔(每周/每月/每季度)
- 点击"保存设置"
备份文件说明
- 存储位置:
/opt/Person_Web/Person_Web-main/backups/ - 文件格式:
auto-backup-YYYY-MM-DDTHH-mm-ss.json - 文件内容:包含所有用户、文章、分类数据的 JSON 文件
9.2 手动导出数据
管理员可以随时手动导出数据库数据:
- 访问
https://你的域名/admin/database - 点击"导出数据"按钮
- 确认弹窗中显示的数据统计
- 点击"确认导出"下载 JSON 文件
9.3 导入数据(数据迁移)
当需要迁移数据或恢复备份时:
- 访问
https://你的域名/admin/database - 点击"选择文件"上传 JSON 备份文件
- 预览导入数据的统计信息
- 确认后系统会:
- 自动创建当前数据的备份(防止数据丢失)
- 清空现有数据
- 导入新数据
⚠️ 注意:导入操作会覆盖现有数据,请确保已备份重要数据。
9.4 命令行备份(传统方式)
除了管理界面,你也可以使用命令行进行备份:
备份数据库:
# 创建备份目录
mkdir -p /opt/backups
# 备份数据库
docker exec person_web_mysql mysqldump -uroot -p$(grep MYSQL_ROOT_PASSWORD .env.production | cut -d'=' -f2) personal_blog | gzip > /opt/backups/blog-$(date +%Y%m%d).sql.gz
恢复数据库:
# 解压并恢复
gunzip -c /opt/backups/blog-20260204.sql.gz | docker exec -i person_web_mysql mysql -uroot -p$(grep MYSQL_ROOT_PASSWORD .env.production | cut -d'=' -f2) personal_blog
十、项目升级
当项目有新版本时,可以使用一键升级脚本快速更新,数据库数据会完整保留。
10.1 一键升级(推荐)
项目提供了一键升级脚本,自动完成所有升级步骤:
cd /opt/Person_Web/Person_Web-main
sudo bash deploy/scripts/upgrade.sh
脚本会自动执行以下操作:
- ✅ 备份当前数据 - 自动备份数据库和配置文件
- ✅ 拉取最新代码 - 从 GitHub 获取最新版本
- ✅ 重新构建镜像 - 构建包含新代码的 Docker 镜像
- ✅ 重启应用 - 启动新版本应用
- ✅ 验证部署 - 检查应用是否正常运行
10.2 手动升级步骤
如果你想手动控制升级过程:
步骤 1:备份当前数据
cd /opt/Person_Web/Person_Web-main
# 备份数据库
mkdir -p /opt/backups
docker exec person_web_mysql mysqldump -uroot -p$(grep MYSQL_ROOT_PASSWORD .env.production | cut -d'=' -f2) personal_blog | gzip > /opt/backups/blog-before-upgrade-$(date +%Y%m%d).sql.gz
# 备份环境配置文件
cp .env.production /opt/backups/env-backup-$(date +%Y%m%d)
步骤 2:拉取最新代码
git pull origin main
步骤 3:重新部署应用
sudo bash deploy/scripts/deploy.sh
步骤 4:验证升级
docker compose ps
docker compose logs --tail=20 app
10.3 数据安全说明
💡 为什么升级不会丢失数据?
- 数据库数据存储在 Docker Volume
person_web_mysql_data中- Volume 与应用容器完全分离,重建应用不影响数据
- 即使执行
docker compose down,数据也会保留(除非加-v参数)- 升级脚本会自动备份,即使出现问题也可以恢复
日常维护指南
常用命令速查表
| 操作 | 命令 |
|---|---|
| 查看容器状态 | docker compose ps |
| 启动所有服务 | docker compose up -d |
| 停止所有服务 | docker compose down |
| 重启应用 | docker compose restart app |
| 重启数据库 | docker compose restart mysql |
| 查看应用日志 | docker compose logs -f app |
| 查看数据库日志 | docker compose logs -f mysql |
| 进入应用容器 | docker exec -it person_web_app sh |
| 进入数据库容器 | docker exec -it person_web_mysql mysql -uroot -p |
| 重新部署 | bash deploy/scripts/deploy.sh |
| 重载 Nginx | sudo systemctl reload nginx |
| 测试 Nginx 配置 | sudo nginx -t |
定期维护任务
每周任务
-
检查容器状态
docker compose ps docker stats --no-stream -
查看磁盘使用情况
df -h du -sh /opt/Person_Web/uploads -
备份数据库
mkdir -p /opt/backups docker exec person_web_mysql mysqldump -uroot -p你的数据库密码 personal_blog | gzip > /opt/backups/blog-$(date +%Y%m%d).sql.gz
每月任务
-
更新系统软件包
sudo apt update sudo apt upgrade -y -
清理 Docker 资源
# 清理未使用的镜像、容器、网络 docker system prune -a -
检查 SSL 证书有效期
sudo certbot certificates
每季度任务
-
完整备份
# 备份数据库 docker exec person_web_mysql mysqldump -uroot -p你的数据库密码 personal_blog | gzip > /opt/backups/full-backup-$(date +%Y%m%d)-db.sql.gz # 备份上传文件 tar -czf /opt/backups/full-backup-$(date +%Y%m%d)-uploads.tar.gz -C /opt/Person_Web uploads/ # 备份配置文件 cp /opt/Person_Web/.env.production /opt/backups/env-backup-$(date +%Y%m%d) -
性能优化检查
# 查看容器资源使用 docker stats # 查看数据库大小 docker exec person_web_mysql mysql -uroot -p你的数据库密码 -e "SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.tables GROUP BY table_schema;"
故障排查流程
当博客出现问题时,按照以下流程排查:
-
检查容器状态
docker compose ps -
查看应用日志
docker compose logs --tail=50 app -
查看数据库日志
docker compose logs --tail=50 mysql -
检查系统资源
free -h # 内存使用 df -h # 磁盘使用 -
重启服务
docker compose restart -
如果问题依然存在,查看详细日志
docker compose logs app > /tmp/app-logs.txt docker compose logs mysql > /tmp/mysql-logs.txt
附录
项目文件结构
Person_Web/
├── client/ # 前端代码
│ ├── src/
│ │ ├── pages/ # 页面组件
│ │ │ ├── AdminAnalytics.tsx # 数据分析仪表盘
│ │ │ ├── AdminArticles.tsx # 文章管理
│ │ │ ├── AdminDatabase.tsx # 数据库管理
│ │ │ └── ArticleDetail.tsx # 文章详情(含目录导航)
│ │ ├── components/ # UI 组件
│ │ │ ├── SEOHead.tsx # SEO 元数据组件
│ │ │ └── TableOfContents.tsx # 文章目录导航
│ │ ├── _core/
│ │ │ └── hooks/
│ │ │ └── usePageView.ts # 页面浏览追踪 Hook
│ │ └── lib/ # 工具函数
│ └── index.html
├── server/ # 后端代码
│ ├── _core/ # 核心功能
│ │ ├── cache.ts # 缓存层(性能优化)
│ │ ├── seo.ts # SEO 中间件(爬虫检测、结构化数据)
│ │ └── sitemap.ts # XML Sitemap 生成
│ ├── routers.ts # tRPC 路由(含数据分析 API)
│ ├── db.ts # 数据库操作
│ └── index.ts # 服务器入口
├── drizzle/ # 数据库相关
│ ├── schema.ts # 表结构定义(含 pageViews、backupSettings)
│ └── migrations/ # 迁移文件
├── deploy/ # 部署相关
│ ├── nginx/ # Nginx 配置
│ └── scripts/ # 部署脚本
├── uploads/ # 上传文件目录
├── backups/ # 数据库备份目录
├── .env.production # 生产环境变量
├── docker-compose.yml # Docker Compose 配置
├── Dockerfile # Docker 镜像构建
└── package.json # 项目依赖
技术栈说明
- 前端: React 19 + TypeScript + Vite + TailwindCSS
- 后端: Express + tRPC + TypeScript
- 数据库: MySQL 8.0
- ORM: Drizzle ORM
- 数据可视化: Recharts
- SEO: React Helmet + JSON-LD + Open Graph + XML Sitemap
- 容器化: Docker + Docker Compose
- Web 服务器: Nginx
- SSL 证书: Let’s Encrypt (Certbot)
获取帮助
如果遇到本文档未涵盖的问题:
-
查看日志
- 应用日志:
docker compose logs app - 数据库日志:
docker compose logs mysql - Nginx 日志:
/var/log/nginx/error.log
- 应用日志:
-
在线资源
- Docker 官方文档:https://docs.docker.com/
- Nginx 官方文档:https://nginx.org/en/docs/
- MySQL 官方文档:https://dev.mysql.com/doc/
更多推荐









所有评论(0)