# 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 └── ... ```