# 部署指南 面向接手部署的人。按顺序执行即可,每一步都有验证方法。 --- ## 0. 变量约定 下文用占位符代替真实域名,部署时替换: 只需要**三个域名**:管理后台直接调用 ``(服务端同一进程内含 `/admin/v1/*`), 不需要单独的接口域名。 | 占位符 | 含义 | 举例 | |---|---|---| | `` | 服务端 API 域名 | `yelaymaths-api.example.com` | | `<后台域名>` | 管理后台域名 | `yelaymaths-admin.example.com` | | `<数据域名>` | 课程数据(图片 / 视频)域名 | `yelaymaths-data.example.com` | > ⚠️ **三个域名都不能含下划线。** 下划线不是合法的主机名字符(RFC 1034/1035 只允许字母、数字、连字符), > 后果是 Let's Encrypt 拒签证书、微信「request 合法域名」校验也会拒绝。 > > 用中划线:`yelaymaths-api.example.com`,不要用 `yelaymaths_api.example.com`。 --- ## 1. 服务器准备(宝塔面板) 1. 软件商店安装:**MySQL 5.7**、**Nginx**、**Node 版本管理器**(选 Node 22 LTS)。 2. 防火墙放行 80 / 443。 3. 建 3 个站点,各配 Let's Encrypt 证书: | 站点 | 反向代理到 | |---|---| | `` | `http://127.0.0.1:3000` | | `<后台域名>` | `http://127.0.0.1:3001` | > 这两个站点**都不是静态站点**,反向代理必须配,只上传文件不会工作。 4. 建数据端站点 `<数据域名>`,根目录指向课程数据目录(见第 6 节)。 --- ## 2. 数据库 1. 新建数据库 `yelaymaths`,字符集 `utf8mb4`。 2. 新建数据库账号并授权。 > **关于 Prisma 权限**:`prisma migrate dev` 需要 `CREATE DATABASE` 权限来建影子库,宝塔默认账号没有。 > 生产环境**只用** `pnpm prisma:migrate`(即 `prisma migrate deploy`),它不建影子库,无需额外权限。 3. **备份旧库**(迁移前必做): ```bash mysqldump -u <用户> -p api_yeomai_site > /root/backup/api_yeomai_site_$(date +%F).sql ``` --- ## 3. 部署服务端 ```bash cd /www/wwwroot git clone <仓库地址> yelaymaths cd yelaymaths/yelaymaths_api pnpm install cp .env.example .env vi .env # 按下表填写 ``` ### 必须填写的环境变量 | 变量 | 说明 | |---|---| | `DATABASE_URL` | `mysql://用户:密码@127.0.0.1:3306/yelaymaths` | | `LEGACY_DATABASE_URL` | 旧库连接串,仅迁移脚本使用 | | `API_BASE_URL` | `https://` | | `STATIC_BASE_URL` | `https://<数据域名>` | | `ADMIN_ORIGIN` | `https://<后台域名>`(跨域白名单) | | `JWT_ACCESS_SECRET` | 随机 32 位以上 | | `JWT_REFRESH_SECRET` | 随机 32 位以上 | | `SESSION_KEY_ENC_SECRET` | 随机 32 位以上,用于加密存储用户 sessionKey | | `MEDIA_SIGN_SECRET` | 随机 32 位以上,用于播放地址签名 | | `WX_APPID` | `wx3fbaf897825bf04f` | | `WX_APPSECRET` | 小程序密钥 | | `WX_OFFER_ID` / `WX_PAY_APPKEY` | 虚拟支付参数(现网),未开通可留空 | | `WX_PAY_APPKEY_SANDBOX` | 虚拟支付沙箱密钥,用于上线前试跑 | | `WX_PAY_ENV` | `0` 现网 / `1` 沙箱。改完需重启服务端 | | `DATA_ROOT` | 课程数据目录的**绝对路径** | > 生成随机密钥:`openssl rand -hex 32` > > ⚠️ `STATIC_BASE_URL` 必须在跑数据迁移**之前**填对。旧库里有 48 处内容写死了旧域名, > 迁移时会按这个变量改写;填错会导致图片与视频全部 404。 ### 建表、迁移、启动 ```bash pnpm prisma:generate pnpm prisma:migrate # 建表 pnpm legacy:check # 体检 pnpm legacy:migrate -- --dry-run # 核对行数 pnpm legacy:migrate # 正式迁移 pnpm build ``` 在宝塔「Node 项目」里新建项目: - 项目目录:`/www/wwwroot/yelaymaths/yelaymaths_api` - 启动文件:`dist/main.js` - 端口:`3000` - 运行方式:PM2 **验证**:`curl https:///healthz` 应返回 `{"code":0,...,"db":"ok"}`。 若 `db` 为 `down`,说明数据库连接串不对。 --- ## 4. 部署管理后台 ```bash cd /www/wwwroot/yelaymaths/yelaymaths_admin pnpm install cp .env.example .env.local vi .env.local # NEXT_PUBLIC_API_BASE_URL=https:// pnpm build ``` 同样用宝塔「Node 项目」启动: - 启动文件:`node_modules/next/dist/bin/next`,参数 `start -p 3001` - 或直接用 `pnpm start` - 端口:`3001` **验证**:打开 `https://<后台域名>`,应看到登录页。 首次使用点「创建管理员账号」,创建完成后切回登录。 > 该接口只在系统中没有任何管理员时生效,之后调用会返回「已存在」,因此可以安全保留。 --- ## 5. 部署课程数据端 把旧服务器的资源目录复制到 `<数据域名>` 站点根目录: | 来源 | 目标 | 体积参考 | |---|---|---| | 旧站 `Images/` | `<根>/Images/` | 约 195 MB | | 旧站 `WebPages/` | `<根>/WebPages/` | 约 21 MB | | 旧站 `Course/` | `<根>/Course/` | 视频文件 | | 旧站 `FreeVideos/` | `<根>/FreeVideos/` | 视频文件 | 再从旧小程序的 `static/image/` 复制三张占位图到 `<根>/Images/Placeholder/`: ``` Images/Placeholder/user.png Images/Placeholder/defaultAvatar.png Images/Placeholder/weixin.png ``` **目录名与文件名不可更改**,前端是拼路径访问的。完整约定见 [`yelaymaths_data.yeomai.site/README.md`](../yelaymaths_data.yeomai.site/README.md)。 ### ⚠️ 付费视频目录必须挡住 付费视频的鉴权由服务端 `/media/*` 签名通道提供(地址有效期 30 分钟,HLS 的 `.ts` 分片也逐行带签名)。 但如果 `Course/` 目录同时被数据域名公开暴露,任何人猜到路径就能直接下载,这套防护等于没有。 **在数据端站点的 Nginx 配置里加一条:** ```nginx location ^~ /Course/ { deny all; } ``` 免费内容(`Images/`、`WebPages/`、`FreeVideos/`)保持公开即可。 > 若后续改用 CDN,把 `MediaService.buildSignedUrl` 换成 CDN 厂商的签名方式,并在 CDN 侧对 `Course/` 开鉴权。 --- ## 6. 配置小程序 1. 编辑 `yelaymaths/config/index.js`: ```js API_BASE_URL: 'https://', STATIC_BASE_URL: 'https://<数据域名>', ``` 2. 用微信开发者工具打开 `yelaymaths/`,执行【工具 → 构建 npm】。 3. 上传并提交审核。 > 小程序**不打包任何业务图片**,只保留 6 个 tabBar 图标(约 19 KB)。 > tabBar 图标必须本地,这是微信的限制,无法改为网络图。 --- ## 7. 微信小程序后台配置 | 配置项 | 位置 | 值 | |---|---|---| | request 合法域名 | 开发 → 开发管理 → 开发设置 | `https://` | | 发货推送 URL | 虚拟支付 → 基本配置 | `https:///v1/payments/notify` | | 小程序简称 | 虚拟支付 → 基础配置 | iOS 支付必需 | | 苹果 IAP 支付 | 虚拟支付 → 基础配置 | iOS 支付需开启 | | 支付道具 | 虚拟支付 → 道具管理 | 每门课建一个,记下道具 ID 与价格 | > `` 与 `