Files
MyHomepage/docs/DEPLOY.md
T
g82tt 68be41e7a2 初始提交:浏览器首页 MyHomePage 全栈项目
# 项目概述
个人浏览器首页导航应用,支持书签分类管理、搜索引擎快捷搜索、
必应每日壁纸轮播、前后端分离部署,适配 1Panel 服务器(Docker 模式)。

# 技术栈
- 前端:Vue 3 + TypeScript + Vite + Pinia + Capacitor(Android 打包)
- 后端:.NET 8 + SqlSugar(多数据库) + SQLite/MySQL + Swashbuckle
- 部署:1Panel 应用商店自定义应用(Docker Compose 模式)

# 项目结构
- backend/    .NET 8 API 后端(8 个 Controller + 15 个 Service)
- frontend/   Vue 3 前端(19 个组件 + 9 个 API 模块 + 5 个 Store)
- docker/     Docker 部署文件(后端镜像 + Nginx 反代)
- docs/       部署手册(1Panel 实战版)
- scripts/    E2E 测试脚本

# 已实现功能
- 书签管理:增删改查 + 树形分类 + 拖拽排序 + 主色自适应
- 搜索引擎:8 个内置引擎 + 自定义引擎 + favicon 自动抓取
- 必应壁纸:每日轮播 + 多分辨率自动选择 + 1.6MP 质量优先
- 全局设置:主题/行为/数据/工具 4 分类 + 跨设备同步
- 文件上传:图标/书签/通用(容器持久化 + 跨域 URL 拼接)
- 同步:基于变更日志的设备间数据同步
- 跨域部署:前后端分离 + runtime config.json 无需重新编译

# 进度记录
- 已完成 P0~P52 共 53 个开发节点(详细见 说明文档.md)
- 当前版本:v1.0 部署就绪

# 部署文档
- README.md:项目说明 + 快速开始
- 说明文档.md:完整开发进度(中文)
- docs/DEPLOY.md:1Panel 部署手册(Docker 模式)
2026-07-05 05:09:56 +08:00

379 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MyHomePage 1Panel 部署手册
> 适用环境:服务器已装 1Panelv2.x+ 1Panel 内置 MySQL(已部署并启动)
> 全程不碰 Docker / nginx.conf / systemd —— 全部交给 1Panel 面板管理
---
## 一、部署架构
```
[公网/局域网]
┌───────────────┴───────────────┐
│ │
域名 A(前端) 域名 B(后端,可选)
│ │
▼ ▼
1Panel 静态网站 1Panel .NET 运行时
Nginx 反代) Kestrel
│ │
│ /api/* 反代到 127.0.0.1:8080 │
└──────────────┐ ┌──────────────┘
▼ ▼
1Panel MySQL
(本机 127.0.0.1:3306
```
**一句话总结**:MySQL 已部署 + 前端走静态网站 + 后端走 .NET 运行环境 = 三步上线。
---
## 二、前置准备
### 2.1 服务器侧
| 条件 | 说明 |
|------|------|
| 1Panel v2.x | 已装好(主人的情况) |
| MySQL 实例 | 1Panel 应用商店装的 MySQL,已 running |
| 域名 | 可选:解析 A 记录到服务器 IP;没域名也能用 IP+端口 |
| 1Panel 防火墙 | 默认放行 80/443;后端用 8080 需手动放行 |
### 2.2 本地编译
#### 2.2.1 编译后端
```powershell
cd d:\Code\MyHomePage\backend
dotnet publish -c Release -o ..\publish\backend
```
产物:`publish\backend\`(约 80MB,含 .dll / appsettings.json / wwwroot/ 等)。
#### 2.2.2 编译前端
```powershell
cd d:\Code\MyHomePage\frontend
npm install # 首次或依赖变化时
npm run build
```
产物:`frontend\dist\`(约 400KB,含 index.html / assets/)。
### 2.3 上传产物到服务器
**方式 11Panel 文件管理(推荐,Web 拖拽)**
- 1Panel → 文件 → 进入 `/opt/1panel/apps/`
- 新建两个文件夹:`myhomepage-backend` / `myhomepage-frontend`
- 分别拖入编译产物
**方式 2:scp 上传(打 zip 后传一次)**
```powershell
cd d:\Code\MyHomePage
Compress-Archive -Path publish\backend,frontend\dist -DestinationPath myhomepage.zip
scp myhomepage.zip root@your-server:/opt/1panel/apps/
```
服务器侧:
```bash
cd /opt/1panel/apps/
unzip myhomepage.zip
mv publish/backend myhomepage-backend
mv frontend/dist myhomepage-frontend
```
---
## 三、第一步:1Panel 准备 MySQL
### 3.1 创建数据库
- 1Panel → 数据库 → MySQL → 你的实例 → **创建数据库**
- 数据库名:`myhomepage`
- 字符集:`utf8mb4`
- 排序规则:`utf8mb4_unicode_ci`
### 3.2 创建用户并授权
- 1Panel → 数据库 → MySQL → 你的实例 → **创建用户**
- 用户名:`myhomepage_user`
- 密码:自定义或自动生成(**复制保存**!)
- 主机:**`localhost`**(只允许本机连接,禁止公网)
- 授权:库 `myhomepage`,权限 `ALL`
### 3.3 记录连接信息
| 字段 | 值 |
|------|-----|
| host | `127.0.0.1` |
| port | `3306` |
| database | `myhomepage` |
| user | `myhomepage_user` |
| password | (你刚设的) |
---
## 四、第二步:部署后端
### 4.1 上传后端文件
`publish\backend\` 内**所有文件**传到 `/opt/1panel/apps/myhomepage-backend/`
最终目录结构(参考):
```
/opt/1panel/apps/myhomepage-backend/
├── MyHomePage.Api.dll
├── appsettings.json
├── appsettings.Production.json
├── web.config # 1Panel 运行环境会自动生成
├── Uploads/ # 后面建
├── wwwroot/ # 后端静态资源(如果有)
└── ...
```
### 4.2 创建 .NET 网站
- 1Panel → **网站****创建网站**
- 类型:选择「**运行环境**」标签 → 选 **.NET**(如果应用商店没装 .NET Runtime,先去应用商店搜 `.NET` 安装)
- 主域名:填后端域名(如 `api.example.com`),或留空用 `IP:8080`
- 端口:`8080`
- 代号:`myhomepage-api`
- 网站目录:`/opt/1panel/apps/myhomepage-backend`
- 启动命令:`dotnet MyHomePage.Api.dll --urls http://0.0.0.0:8080`
### 4.3 配置环境变量
在创建好的网站详情页 → 「环境变量」或「配置文件」tab,添加:
| 变量名 | 值 | 说明 |
|--------|-----|------|
| `ASPNETCORE_ENVIRONMENT` | `Production` | 启用生产配置 |
| `Database__Provider` | `MySql` | 切换到 MySQL |
| `Database__ConnectionString` | `server=127.0.0.1;port=3306;database=myhomepage;user=myhomepage_user;password=你的密码;charset=utf8mb4;` | 连接串 |
| `Upload__Path` | `/opt/1panel/apps/myhomepage-backend/Uploads` | 上传文件落盘路径 |
| `Upload__BaseUrl` | `https://你的前端域名/uploads` | 前端拼接 URL 前缀 |
| `Cors__Origins__0` | `https://你的前端域名` | 允许跨域的白名单(必须) |
> 双下划线 `__` 是 ASP.NET Core 配置嵌套的语法,等价于 JSON 里的 `{ "Cors": { "Origins": [ ... ] } }`。
> 如果主人在前端用 `VITE_API_BASE=https://api.example.com` 直接走独立域名,跨域问题更彻底。
### 4.4 创建上传目录
- 1Panel → 文件 → 在 `/opt/1panel/apps/myhomepage-backend/` 下新建 `Uploads/`
- 权限 755(默认即可)
### 4.5 启动后端
- 网站详情页 → **启动** 按钮
- 等 5-10 秒 → **日志** tab 应该看到:
```
Now listening on: http://0.0.0.0:8080
Application started.
```
### 4.6 本地验证
```bash
# 服务器侧
curl http://127.0.0.1:8080/health
# 期望:OK
```
看到 200 = 后端已就绪 ✅
---
## 五、第三步:部署前端
### 5.1 上传前端文件
把 `frontend\dist\` 内**所有文件**传到 `/opt/1panel/apps/myhomepage-frontend/`
### 5.2 创建静态网站
- 1Panel → **网站****创建网站**
- 类型:选择「**静态网站**」标签
- 主域名:填前端域名(如 `home.example.com`
- 端口:`80`HTTP)或 `443`HTTPS
- 代号:`myhomepage-web`
- 网站目录:`/opt/1panel/apps/myhomepage-frontend`
### 5.3 申请 SSL(强烈推荐)
- 网站详情页 → **SSL****申请** → Let's Encrypt
- 1Panel 自动续期
### 5.4 配置反向代理(关键!)
网站详情页 → **反向代理** 或直接编辑 **配置文件**Nginx),加这段:
```nginx
# /api/* 转发到后端
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 60s;
}
# /uploads/* 转发到后端(用户上传图片)
location /uploads/ {
proxy_pass http://127.0.0.1:8080;
}
```
> 如果前端 `.env.production` 配了 `VITE_API_BASE=https://api.example.com`**跳过本节**(前后端走不同域名更干净)。
### 5.5 验证前端
浏览器打开 `https://你的前端域名/` → 看到首页 = 成功 ✅
---
## 六、第四步:联调验证
### 6.1 必查清单
- [ ] 浏览器打开前端 → 首页正常渲染
- [ ] DevTools → Network → 5 个 API 请求(settings / categories / bookmarks / search-engines / wallpaper**全部 200**
- [ ] 新建一个分类 + 一个链接 → 刷新页面看是否持久化
- [ ] 切换主题 / 主色调 → 刷新看是否持久化
- [ ] 上传一张图片 → 看是否显示
- [ ] 360 壁纸功能(在设置里启用)→ 切换间隔生效
### 6.2 Android APP 后端地址
主人后续会打包 Android。`.env.production` 或 Capacitor 配置里填:
```
# 同域名反代
https://你的前端域名/api
# 或独立后端域名
https://api.example.com
```
---
## 七、日常运维
### 7.1 看日志
- 1Panel → 网站 → 你的网站 → **日志** tab
- 实时滚动 / 可下载 .log 文件
- 排错先看这里 ✅
### 7.2 重启服务
- 1Panel → 网站 → 你的网站 → **重启** 按钮
- 5-10 秒生效
### 7.3 备份数据库
- 1Panel → 数据库 → MySQL → 你的实例 → **备份**
- 1Panel 默认每天自动备份到本地目录
- 也可「立即备份」→ 下载到本地双保险
### 7.4 更新后端
```powershell
# 本地
cd d:\Code\MyHomePage\backend
dotnet publish -c Release -o ..\publish\backend
```
- 1Panel → 文件 → `/opt/1panel/apps/myhomepage-backend/` → 覆盖上传所有文件
- 1Panel → 网站 → myhomepage-api → **重启**
### 7.5 更新前端
```powershell
# 本地
cd d:\Code\MyHomePage\frontend
npm run build
```
- 1Panel → 文件 → `/opt/1panel/apps/myhomepage-frontend/` → 覆盖上传所有文件
- 静态网站无需重启,浏览器 Ctrl+F5 强刷即可
### 7.6 紧急回滚
| 想回滚 | 操作 |
|--------|------|
| 后端代码 | 1Panel → 文件 → 把后端目录回退到上一版 → 重启 |
| 前端代码 | 1Panel → 文件 → 把前端目录回退到上一版 → 强刷 |
| 数据库 | 1Panel → 数据库 → 选昨天的备份 → 恢复(**会覆盖当前数据**) |
---
## 八、常见问题
### Q1:前端打开是白屏
- 1Panel → 网站 → 静态网站 → 日志查 404
- 大概率是 `index.html` 没传,或 `assets/` 目录没传全
### Q2API 全部 404
- 检查第五步 5.4 的反向代理是否生效
- 服务器本地 `curl http://127.0.0.1:8080/health` 验证后端活着
### Q3CORS 跨域报错
- 检查第四步 4.3 的 `Cors__Origins__0` 是否设了前端完整域名(含 `https://`
- 重启后端
### Q4:数据库连接失败
- 1Panel → 数据库 → MySQL → 看实例 running
- 服务器本地 `mysql -u myhomepage_user -p` 验证能登
- 检查连接串的 `password=` 是不是带特殊字符(需要 URL encode)
### Q5:上传图片 500
- 检查 `/opt/1panel/apps/myhomepage-backend/Uploads/` 权限 755
- 服务器 `df -h` 看磁盘
### Q6:移动端 / Android APP 访问不到
- 1Panel 防火墙放行 8080(如果不走反代)
- 或在 Android 里直接填 `https://你的前端域名/api`(走反代最稳)
### Q7360 壁纸不显示
- 后端环境变量里 `Upload__BaseUrl``Cors__Origins__0` 都填前端完整域名
- 服务器能访问外网(curl `https://wallpaper.apc.360.cn` 验证)
---
## 附录 A:环境变量速查表
| 变量 | 必填 | 示例值 | 说明 |
|------|------|--------|------|
| `ASPNETCORE_ENVIRONMENT` | 是 | `Production` | 启用生产配置 |
| `Database__Provider` | 是 | `MySql` | 固定值 |
| `Database__ConnectionString` | 是 | `server=127.0.0.1;port=3306;database=myhomepage;user=myhomepage_user;password=xxx;charset=utf8mb4;` | MySQL 连接串 |
| `Upload__Path` | 是 | `/opt/1panel/apps/myhomepage-backend/Uploads` | 上传落盘绝对路径 |
| `Upload__BaseUrl` | 是 | `https://home.example.com/uploads` | 前端拼接 URL 前缀 |
| `Cors__Origins__0` | 是 | `https://home.example.com` | 跨域白名单(多域名时加 `Cors__Origins__1` |
## 附录 B:目录结构速查
```
/opt/1panel/apps/
├── myhomepage-backend/
│ ├── MyHomePage.Api.dll
│ ├── appsettings.json
│ ├── appsettings.Production.json
│ ├── Uploads/ # 用户上传
│ └── ...
└── myhomepage-frontend/
├── index.html
├── assets/
│ ├── index-xxxxxx.js
│ └── index-xxxxxx.css
└── ...
```