68be41e7a2
# 项目概述 个人浏览器首页导航应用,支持书签分类管理、搜索引擎快捷搜索、 必应每日壁纸轮播、前后端分离部署,适配 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 模式)
379 lines
12 KiB
Markdown
379 lines
12 KiB
Markdown
# MyHomePage 1Panel 部署手册
|
||
|
||
> 适用环境:服务器已装 1Panel(v2.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 上传产物到服务器
|
||
|
||
**方式 1:1Panel 文件管理(推荐,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/` 目录没传全
|
||
|
||
### Q2:API 全部 404
|
||
- 检查第五步 5.4 的反向代理是否生效
|
||
- 服务器本地 `curl http://127.0.0.1:8080/health` 验证后端活着
|
||
|
||
### Q3:CORS 跨域报错
|
||
- 检查第四步 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`(走反代最稳)
|
||
|
||
### Q7:360 壁纸不显示
|
||
- 后端环境变量里 `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
|
||
└── ...
|
||
```
|