1097 lines
37 KiB
Markdown
1097 lines
37 KiB
Markdown
# 游牧中国 NomadCNA 项目与服务器部署报告
|
||
|
||
生成时间:2026-06-06 23:16 CST
|
||
服务器时区:Asia/Shanghai / CST +0800
|
||
项目路径:`/home/ubuntu/gitlab-instance-0a899031_cnomadcna`
|
||
Git 分支:`test2`
|
||
最新提交:`00b1c8e`,2026-06-06 23:05:17 +0800
|
||
报告范围:当前仓库代码、前端/后端/数据服务、服务器上实际运行的相关服务、反向代理、端口、构建状态、运维风险与后续建议。
|
||
敏感信息处理:本报告只记录环境变量名、用途、路径、端口和域名,不记录任何密码、Token、Access Key、Secret、数据库连接串原文。
|
||
|
||
## 1. 项目定位
|
||
|
||
NomadCNA / 游牧中国是一个面向数字游民的中文优先、英文可切换的一站式网站,当前定位可以概括为:
|
||
|
||
- 数字游民城市决策平台:展示中国城市的成本、网速、安全、气候、社区活跃度、标签和详情。
|
||
- 数字游民社区入口:提供报名、登录、会员、资料录入、同城活动、交友匹配、站内消息。
|
||
- 数字游民服务市场:提供共享办公、城市落地顾问、保障类服务、赏金任务、反馈和咨询线索。
|
||
- 数字游民内容与工具:电子书、视频、报告、AI 助手、FIRE/汇率/签证/气候工具。
|
||
- 生产部署站点:当前主域为 `nomadro.cn` / `www.nomadro.cn`,PocketBase 为 `pocketbase.nomadro.cn`,FastAPI 为 `api.nomadro.cn`。
|
||
|
||
当前项目已经不是纯前端展示站,已经具备“前端 + Next.js API + FastAPI + PocketBase + 支付 + 上传 + 消息 + 监控”的完整早期产品架构。
|
||
|
||
## 2. 访问地址与部署入口
|
||
|
||
### 2.1 对外域名
|
||
|
||
| 域名 | 当前用途 | 反向代理目标 | HTTPS 状态 |
|
||
| --- | --- | --- | --- |
|
||
| `https://nomadro.cn` | 游牧中国主站 | `127.0.0.1:4002` | 已配置证书 |
|
||
| `https://www.nomadro.cn` | 游牧中国主站 | `127.0.0.1:4002` | 已配置证书 |
|
||
| `http://api.nomadro.cn` | FastAPI 后端 API | `127.0.0.1:8000` | 当前只看到 HTTP 配置 |
|
||
| `https://pocketbase.nomadro.cn` | PocketBase REST API 与后台 | `127.0.0.1:8090` | 已配置证书 |
|
||
| `https://umami.nomadro.cn` | Umami 统计 | `127.0.0.1:9280` | 已配置证书 |
|
||
| `http://ntfy.nomadro.cn` | ntfy 推送服务 | `127.0.0.1:9180` | 当前只看到 HTTP 配置 |
|
||
| `http://netdata.nomadro.cn` | Netdata 监控面板 | `127.0.0.1:19999` | 当前只看到 HTTP 配置,已配置 Basic Auth |
|
||
|
||
### 2.2 本机端口
|
||
|
||
| 端口 | 监听地址 | 服务 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `4002` | `*:4002` | NomadCNA Next.js | 生产前端,systemd 管理 |
|
||
| `8000` | `127.0.0.1:8000` | NomadCNA FastAPI | 后端 API,systemd 管理 |
|
||
| `8090` | `127.0.0.1:8090` | PocketBase | 本站主数据服务 |
|
||
| `9280` | `127.0.0.1:9280` | Umami | 统计分析服务 |
|
||
| `9180` | `127.0.0.1:9180` | ntfy Docker 容器 | 通知推送服务 |
|
||
| `19999` | `127.0.0.1:19999` | Netdata | 宿主机监控 |
|
||
| `80/443` | `0.0.0.0` | Nginx | 站点反向代理 |
|
||
| `3306` | `0.0.0.0` | MariaDB/MySQL | 宝塔/其他服务使用,非当前 NomadCNA 主数据 |
|
||
| `5432` | `127.0.0.1` | PostgreSQL 16 | Umami 使用 |
|
||
| `21` | `0.0.0.0` | pure-ftpd | FTP 服务 |
|
||
| `888` | `0.0.0.0` | 宝塔面板 Nginx | 管理面板 |
|
||
| `36711` | `0.0.0.0` | 宝塔面板 webserver | 管理面板相关 |
|
||
| `7000/8999` | `*` | frp-panel | 同机运行的穿透/面板服务 |
|
||
|
||
### 2.3 健康检查结果
|
||
|
||
已验证:
|
||
|
||
- `http://127.0.0.1:8000/api/health` 返回 `200`,服务名为 `NomadCNA FastAPI`。
|
||
- `http://127.0.0.1:4002/zh` 返回 `200`,Next.js 页面可访问。
|
||
- `http://127.0.0.1:8090/api/health` 返回 `200`,PocketBase 可访问。
|
||
- `https://nomadro.cn` 返回 `307` 到 `/zh`,随后返回 `200`。
|
||
- `https://www.nomadro.cn` 返回 `307` 到 `/zh`,随后返回 `200`。
|
||
- `http://api.nomadro.cn/api/health` 返回 FastAPI 健康信息。
|
||
- `https://pocketbase.nomadro.cn/api/health` 返回 `200`。
|
||
|
||
## 3. 技术栈
|
||
|
||
### 3.1 前端
|
||
|
||
- Next.js `16.1.6`
|
||
- React `19.2.3`
|
||
- React DOM `19.2.3`
|
||
- TypeScript `^5`
|
||
- Tailwind CSS `^4`
|
||
- ECharts `^6.0.0`
|
||
- PocketBase JS SDK `^0.26.8`
|
||
- MinIO SDK `^8.0.7`
|
||
- 包管理器:`pnpm 10.25.0`
|
||
- Node.js:`v22.13.1`
|
||
|
||
### 3.2 后端
|
||
|
||
- FastAPI
|
||
- Uvicorn
|
||
- httpx
|
||
- python-multipart
|
||
- PyJWT
|
||
- passlib[bcrypt]
|
||
- Pydantic v2
|
||
- Python `3.12.3`
|
||
|
||
### 3.3 数据与存储
|
||
|
||
- PocketBase:主业务数据库,运行在 `/opt/pocketbase`。
|
||
- PocketBase 数据目录:`/opt/pocketbase/pb_data`。
|
||
- PocketBase 迁移目录:`/opt/pocketbase/pb_migrations`。
|
||
- MinIO:代码中已接入,Docker compose 中也有 `nomadro-minio` 配置,但当前 `docker ps` 只看到 `nomadro-ntfy` 正在运行。
|
||
- 本地上传:FastAPI 挂载 `backend/uploads`,Next.js 上传接口使用 MinIO。
|
||
|
||
### 3.4 代理、运维与监控
|
||
|
||
- Nginx:宝塔路径 `/www/server/nginx`,站点配置在 `/www/server/panel/vhost/nginx/`。
|
||
- systemd:管理 Next.js、FastAPI、PocketBase、Umami、Netdata 等服务。
|
||
- Docker:当前运行 `nomadro-ntfy` 容器。
|
||
- Netdata:宿主机实时监控。
|
||
- Umami:站点访问统计。
|
||
- 宝塔面板相关服务:Nginx、pure-ftpd、MariaDB、站点统计、面板防火墙。
|
||
|
||
## 4. 仓库结构
|
||
|
||
项目根目录主要文件:
|
||
|
||
| 路径 | 说明 |
|
||
| --- | --- |
|
||
| `app/` | Next.js App Router 应用主体 |
|
||
| `app/[locale]/` | 中英文路由页面,支持 `/zh` 和 `/en` |
|
||
| `app/api/` | Next.js API routes,主要处理认证、支付、上传、会员状态 |
|
||
| `app/components/` | Navbar、Hero、城市卡片、弹窗、菜单、通知铃等组件 |
|
||
| `app/context/` | 主题和语言 Context |
|
||
| `app/data/` | 城市、博客、招聘等 fallback/mock 数据 |
|
||
| `app/lib/` | API 客户端、PocketBase、支付、MinIO、图表、Cookie 等工具 |
|
||
| `backend/` | FastAPI 本地 API 服务 |
|
||
| `config/` | 站点、导航、域名、服务、首页、页脚、筛选配置 |
|
||
| `i18n/` | 国际化路由和导航适配 |
|
||
| `messages/` | 中文和英文文案 |
|
||
| `public/` | 静态资源 |
|
||
| `next.config.ts` | Next.js 配置和 API rewrite |
|
||
| `proxy.ts` | locale 重定向代理 |
|
||
| `package.json` | 前端依赖和脚本 |
|
||
| `backend/requirements.txt` | Python 后端依赖 |
|
||
| `cnomadcna.sh` | 生产 Next.js systemd 启动脚本 |
|
||
| `PROJECT_ANALYSIS_REPORT.md` | 旧分析报告 |
|
||
| `NOMADCNA_PROJECT_DEPLOYMENT_REPORT.md` | 当前报告 |
|
||
|
||
项目体积:当前仓库目录约 `746M`,包含 `.next`、`node_modules`、`backend/.venv` 等运行产物。
|
||
|
||
## 5. 前端应用结构
|
||
|
||
### 5.1 国际化
|
||
|
||
- 支持语言:`zh`、`en`。
|
||
- 默认语言:`zh`。
|
||
- URL 策略:总是带 locale 前缀。
|
||
- `proxy.ts` 会将无 locale 的页面请求重定向到 `/zh`。
|
||
- `/api`、`/_next`、静态文件和带扩展名路径不做 locale 重定向。
|
||
|
||
### 5.2 主要页面
|
||
|
||
当前 `app/[locale]` 下页面包括:
|
||
|
||
| 页面 | 用途 |
|
||
| --- | --- |
|
||
| `/` | 首页,城市列表、内容入口、统计、活动、路线、社区模块 |
|
||
| `/dashboard` | 下一站推荐,根据预算、网速、气候、标签推荐城市 |
|
||
| `/city/[slug]` | 城市详情动态页 |
|
||
| `/meetups` | 线下活动列表 |
|
||
| `/meetups/host` | 发起活动 |
|
||
| `/dating` | 智能匹配、交友、伙伴、室友、合伙人 |
|
||
| `/tools` | 汇率、税务估算、签证倒计时、FIRE、气候匹配 |
|
||
| `/ai` | AI 助手,基于城市数据库返回建议 |
|
||
| `/gigs` | 赏金任务发布和接单 |
|
||
| `/services` | 数字游民服务咨询入口 |
|
||
| `/pricing` | Free / Basic / Pro 定价展示 |
|
||
| `/join` | 社区报名、资料录入、上传、支付跳转 |
|
||
| `/join/paid` | 支付回跳与会员开通确认 |
|
||
| `/messages` | 站内消息中心 |
|
||
| `/settings/notifications` | 通知偏好设置 |
|
||
| `/report`、`/report/data` | 数字游民报告 |
|
||
| `/map` | 成员地图 |
|
||
| `/blog` | 博客 |
|
||
| `/ebooks/[slug]` | 电子书动态页 |
|
||
| `/videos/[slug]` | 视频动态页 |
|
||
| `/app` | App 下载/介绍页 |
|
||
| `/feedback` | 反馈 |
|
||
| `/discuss` | 讨论社区 |
|
||
| `/jobs`、`/careers` | 招聘/职业 |
|
||
| `/about`、`/contact`、`/press`、`/support`、`/help` | 基础内容页 |
|
||
| `/terms`、`/privacy`、`/cookies`、`/safety`、`/guidelines` | 法务和社区规则 |
|
||
|
||
### 5.3 首页数据策略
|
||
|
||
首页当前采用“线上 API 优先、fallback 静态数据兜底”的方式:
|
||
|
||
- `/api/cities`:城市列表。
|
||
- `/api/content/home`:首页内容卡片。
|
||
- `/api/stats/overview`:城市、游民、活动、成本、讨论等统计。
|
||
- `/api/profiles`:成员头像和正在旅行的人。
|
||
- `/api/meetups`:近期活动。
|
||
- `/api/discussions`:热门讨论。
|
||
- `/api/routes`:热门路线。
|
||
|
||
如果 API 请求失败,会回退到 `config/home.config.ts` 和 `app/data/cities.ts` 内的本地数据。这让站点在后端短暂不可用时仍能展示基本内容。
|
||
|
||
### 5.4 导航与站点配置
|
||
|
||
站点标题:`游牧中国 NomadCNA - 数字游民生活操作系统`
|
||
站点描述:数字游民的一站式生活操作系统,覆盖城市决策、税务签证、智能匹配、赏金任务。
|
||
主导航包括:
|
||
|
||
- 城市
|
||
- 下一站
|
||
- 聚会
|
||
- 社区
|
||
- 工具箱
|
||
- AI
|
||
- 赏金
|
||
- 会员
|
||
- 探索
|
||
|
||
## 6. API 层结构
|
||
|
||
当前 API 有两层,需要明确区分。
|
||
|
||
### 6.1 Next.js API routes
|
||
|
||
`app/api` 下当前存在:
|
||
|
||
| 路径 | 用途 |
|
||
| --- | --- |
|
||
| `/api/auth/me` | 读取登录态、刷新 PocketBase auth、返回 VIP 状态 |
|
||
| `/api/auth/logout` | 清除登录 Cookie |
|
||
| `/api/auth/sync-session` | 支付后同步 token 到 Cookie |
|
||
| `/api/auth/change-password` | 修改密码 |
|
||
| `/api/join` | 提交报名资料到 PocketBase 指定集合 |
|
||
| `/api/join/status` | 检查是否已经提交报名 |
|
||
| `/api/upload-media` | 通过 MinIO 上传图片/视频 |
|
||
| `/api/vip/check` | 检查 `site_vip` 会员记录 |
|
||
| `/api/pay` | 创建支付订单,调用 payjsapi / ZPay / XorPay |
|
||
| `/api/pay/status` | 查询支付状态 |
|
||
| `/api/meetup/check-user` | 检查用户是否存在和是否 VIP |
|
||
| `/api/meetup/ensure-user` | 确保用户存在 |
|
||
| `/api/meetup/complete-order` | 支付成功后确认订单并开通 VIP |
|
||
| `/api/meetup/need-password-change` | 检查是否需要改默认密码 |
|
||
| `/api/meetup/set-needs-password-change` | 设置需要改密码 |
|
||
| `/api/geo/china` | 拉取中国地图 GeoJSON |
|
||
|
||
### 6.2 FastAPI 后端
|
||
|
||
FastAPI 运行在 `127.0.0.1:8000`,服务名 `cnomadcna-api.service`。主要接口包括:
|
||
|
||
| 路径 | 用途 |
|
||
| --- | --- |
|
||
| `/api/health` | 健康检查 |
|
||
| `/api/auth/register` | 注册并设置 session |
|
||
| `/api/auth/login` | 登录并设置 session |
|
||
| `/api/auth/me` | 当前用户和会员状态 |
|
||
| `/api/auth/logout` | 清除 session |
|
||
| `/api/auth/change-password` | 修改密码 |
|
||
| `/api/meetup/check-user` | 检查用户和会员 |
|
||
| `/api/meetup/ensure-user` | 创建或登录用户 |
|
||
| `/api/meetup/complete-order` | 本地订单完成和 membership 写入 |
|
||
| `/api/vip/check` | 根据 `memberships` 检查 VIP |
|
||
| `/api/join` | 提交会员申请 |
|
||
| `/api/join/status` | 报名状态 |
|
||
| `/api/upload-media` | 本地上传到 `backend/uploads` |
|
||
| `/api/pay` | 本地开发支付 |
|
||
| `/api/pay/status` | 本地开发支付状态 |
|
||
| `/api/cities` | 城市列表 |
|
||
| `/api/cities/{slug}` | 城市详情 |
|
||
| `/api/content/home` | 首页内容 |
|
||
| `/api/content/{slug}` | 内容详情 |
|
||
| `/api/notifications` | 消息列表和筛选 |
|
||
| `/api/notifications/unread-count` | 未读数 |
|
||
| `/api/notifications/{id}/read` | 标记已读 |
|
||
| `/api/notifications/{id}/unread` | 标记未读 |
|
||
| `/api/notifications/{id}/archive` | 归档 |
|
||
| `/api/notifications/{id}/restore` | 恢复 |
|
||
| `/api/notifications/{id}/pin` | 置顶 |
|
||
| `/api/notifications/mark-all-read` | 全部已读 |
|
||
| `/api/notifications/preferences` | 读取/保存通知偏好 |
|
||
| `/api/recommendations/next-stop` | 下一站推荐 |
|
||
| `/api/routes` | 游牧路线 |
|
||
| `/api/services` | 服务列表 |
|
||
| `/api/services/leads` | 服务咨询线索 |
|
||
| `/api/downloads/{filename}` | 下载 PDF/Zip 等资源 |
|
||
| `/api/meetups` | 活动列表和创建 |
|
||
| `/api/discussions` | 讨论列表和创建 |
|
||
| `/api/gigs` | 赏金列表和发布 |
|
||
| `/api/gigs/{gig_id}/apply` | 接单 |
|
||
| `/api/profiles` | 成员资料 |
|
||
| `/api/matches/swipes` | 匹配滑动记录 |
|
||
| `/api/feedback` | 反馈 |
|
||
| `/api/stats/member-map` | 成员地图统计 |
|
||
| `/api/stats/overview` | 总览统计 |
|
||
| `/api/stats/city-ranking` | 城市排行 |
|
||
| `/api/geo/china` | 地图数据 |
|
||
| `/api/ai/assistant` | AI 助手模拟响应 |
|
||
|
||
### 6.3 Next.js rewrite
|
||
|
||
`next.config.ts` 把部分 `/api/*` 路径 rewrite 到 FastAPI:
|
||
|
||
- health
|
||
- cities
|
||
- content
|
||
- notifications
|
||
- recommendations
|
||
- routes
|
||
- services
|
||
- downloads
|
||
- meetups
|
||
- discussions
|
||
- gigs
|
||
- profiles
|
||
- matches
|
||
- feedback
|
||
- stats
|
||
- ai
|
||
|
||
这意味着:
|
||
|
||
- 上面列出的业务数据 API 会由 FastAPI 处理。
|
||
- Next.js 自身的 `/api/auth/*`、`/api/pay/*`、`/api/join/*`、`/api/upload-media`、`/api/vip/check` 等仍由 Next.js API routes 处理。
|
||
- `app/lib/api-client.ts` 默认 `NEXT_PUBLIC_API_BASE_URL || http://127.0.0.1:8000`。生产环境必须保证 `NEXT_PUBLIC_API_BASE_URL` 指向公网可访问的 API 地址,例如 `http://api.nomadro.cn` 或未来的 `https://api.nomadro.cn`,否则浏览器会尝试请求访问者自己机器的 `127.0.0.1:8000`。
|
||
|
||
## 7. PocketBase 数据模型
|
||
|
||
### 7.1 PocketBase 服务
|
||
|
||
PocketBase systemd 配置:
|
||
|
||
- 服务名:`pocketbase.service`
|
||
- 工作目录:`/opt/pocketbase`
|
||
- 启动命令:`/opt/pocketbase/pocketbase serve --http=127.0.0.1:8090 --dir=/opt/pocketbase/pb_data --origins=https://nomadro.cn,https://www.nomadro.cn,https://pocketbase.nomadro.cn`
|
||
- 数据目录:`/opt/pocketbase/pb_data`
|
||
- 迁移目录:`/opt/pocketbase/pb_migrations`
|
||
- 当前状态:active/running
|
||
|
||
PocketBase 数据库文件:
|
||
|
||
- `/opt/pocketbase/pb_data/data.db`
|
||
- `/opt/pocketbase/pb_data/auxiliary.db`
|
||
- `/opt/pocketbase/pb_data/types.d.ts`
|
||
|
||
### 7.2 初始化脚本中的集合
|
||
|
||
`backend/init_db.py` 定义并初始化以下集合:
|
||
|
||
| 集合 | 用途 |
|
||
| --- | --- |
|
||
| `cities` | 城市主数据,包括 slug、名称、成本、网速、安全、气候、坐标、标签 |
|
||
| `city_details` | 城市详情 JSON,包括指南、优缺点、评价、成本、天气、趋势等 |
|
||
| `profiles` | 成员资料和匹配展示 |
|
||
| `member_applications` | 社区报名资料 |
|
||
| `memberships` | FastAPI 使用的会员记录 |
|
||
| `orders` | FastAPI 本地订单 |
|
||
| `media_assets` | 上传媒体记录 |
|
||
| `meetups` | 线下活动 |
|
||
| `discussions` | 讨论帖 |
|
||
| `gigs` | 赏金任务 |
|
||
| `gig_applications` | 接单申请 |
|
||
| `services` | 服务市场条目 |
|
||
| `service_leads` | 服务咨询线索 |
|
||
| `routes` | 游牧路线 |
|
||
| `recommendation_logs` | 下一站推荐日志 |
|
||
| `notifications` | 站内通知 |
|
||
| `notification_receipts` | 通知已读/归档/置顶状态 |
|
||
| `notification_preferences` | 通知偏好 |
|
||
| `feedback` | 用户反馈 |
|
||
| `swipes` | 交友匹配滑动行为 |
|
||
| `content_items` | 电子书、视频、App、指南等内容卡片 |
|
||
|
||
### 7.3 种子数据
|
||
|
||
种子数据覆盖:
|
||
|
||
- 18 个中国数字游民城市,包括大理、成都、深圳、上海、杭州、厦门、北京、广州、重庆、昆明、三亚、丽江、西安、南京、长沙、青岛、苏州、珠海。
|
||
- 城市成本、网速、安全、气候、经纬度、标签和英文描述。
|
||
- 首页内容:数字游民落地手册、访谈视频、NomadCNA App、数字游民指南。
|
||
- 活动、讨论、赏金、成员资料、服务、路线、通知。
|
||
- 典型服务:远程工作者医疗与旅行保障、共享办公通行证、城市落地顾问。
|
||
- 典型路线:云南慢生活线、湾区创业线、江南互联网线。
|
||
|
||
### 7.4 会员模型一致性风险
|
||
|
||
当前存在两套会员判断模型:
|
||
|
||
- FastAPI 的 `/api/vip/check` 和 `/api/auth/me` 使用 `memberships` 集合。
|
||
- Next.js 的 `/api/vip/check`、`/api/auth/me`、`/api/meetup/complete-order` 使用 `site_vip` 集合。
|
||
- `/opt/pocketbase/pb_migrations` 当前列出的迁移包含 `memberships`,未在本次扫描输出中看到 `site_vip` 迁移文件。
|
||
|
||
这会带来风险:
|
||
|
||
- 如果生产 PocketBase 中没有 `site_vip` 集合,Next.js 会员检查会一直返回非 VIP。
|
||
- 如果支付完成只写 `site_vip`,FastAPI 的会员检查不会识别。
|
||
- 如果某些页面走 Next.js API,某些页面走 FastAPI API,会员状态可能不一致。
|
||
|
||
建议统一为一套会员集合,或明确 `site_vip` 是跨站会员表、`memberships` 是旧表,并补充迁移、同步逻辑和文档。
|
||
|
||
## 8. 支付与报名链路
|
||
|
||
### 8.1 报名流程
|
||
|
||
主要页面:`/zh/join`
|
||
|
||
流程:
|
||
|
||
1. 用户填写昵称、性别、感情状态、职业、简介、微信、学历、毕业年份、手机号、图片/视频。
|
||
2. 页面先检查 `/api/auth/me`。
|
||
3. 未登录则打开认证弹窗。
|
||
4. 已登录后调用 `/api/join` 写入报名资料。
|
||
5. 再调用 `/api/vip/check`。
|
||
6. 如果不是 VIP,则调用 `/api/pay` 跳转支付。
|
||
7. 支付成功回跳 `/join/paid`。
|
||
8. `/join/paid` 根据 `order_id` 调用 `/api/meetup/complete-order`。
|
||
9. 订单确认后同步登录态、触发 `auth:updated` 和 `vip:updated` 事件。
|
||
10. 新用户会显示默认密码提示,并允许修改密码。
|
||
|
||
### 8.2 支付配置
|
||
|
||
代码支持:
|
||
|
||
- `zpay`
|
||
- `xorpay`
|
||
- payjsapi 风格 API
|
||
- PC / H5 / 微信浏览器支付环境判断
|
||
- 微信内强制走 XorPay 的逻辑
|
||
- ZPay 二维码轮询和支付成功后自动确认
|
||
|
||
关键环境变量名:
|
||
|
||
- `PAYMENT_API_URL`
|
||
- `PAYMENT_PROVIDER`
|
||
- `PAYMENT_DEFAULT_AMOUNT`
|
||
- `PAYMENT_DEFAULT_TYPE`
|
||
- `PAYMENT_JOIN_AMOUNT`
|
||
- `PAYMENT_JOIN_TYPE`
|
||
- `ZPAY_SUBMIT_URL`
|
||
- `NEXT_PUBLIC_SITE_ID`
|
||
|
||
`config/domain.config.ts` 中有保护逻辑:生产环境如果 `PAYMENT_API_URL` 指向 localhost,会使用 `https://api.${ROOT_DOMAIN}`。
|
||
|
||
### 8.3 安全注意点
|
||
|
||
- 新用户默认密码当前是 `12345678`,且页面会展示和复制该密码。这适合 MVP,但生产上存在弱口令风险。
|
||
- 建议改为一次性随机临时密码、一次性登录链接,或强制首次设置密码后才完成登录。
|
||
- 支付确认依赖订单 ID 格式解析,建议补充订单表记录、签名校验、回调审计和重复开通幂等测试。
|
||
|
||
## 9. 上传与对象存储
|
||
|
||
当前存在两套上传实现:
|
||
|
||
### 9.1 Next.js MinIO 上传
|
||
|
||
路径:`app/api/upload-media/route.ts`
|
||
|
||
- 接收 `multipart/form-data`。
|
||
- 文件大小限制:20MB。
|
||
- 生成对象 key:`{uploadPrefix}/{timestamp}_{random}.{ext}`。
|
||
- 调用 `app/lib/minio/client.ts` 的 `putObject`。
|
||
- 返回公开 URL。
|
||
|
||
关键环境变量:
|
||
|
||
- `MINIO_ENDPOINT`
|
||
- `MINIO_PORT`
|
||
- `MINIO_USE_SSL`
|
||
- `MINIO_BUCKET`
|
||
- `MINIO_ACCESS_KEY`
|
||
- `MINIO_SECRET_KEY`
|
||
- `MINIO_REGION`
|
||
- `MINIO_PUBLIC_URL`
|
||
- `MINIO_UPLOAD_PREFIX`
|
||
|
||
### 9.2 FastAPI 本地上传
|
||
|
||
路径:`backend/main.py` 的 `/api/upload-media`
|
||
|
||
- 文件大小限制:20MB。
|
||
- 写入 `settings.upload_dir`,默认 `backend/uploads`。
|
||
- 通过 `/uploads/{name}` 静态路径提供访问。
|
||
- 同时写 `media_assets` 集合。
|
||
|
||
### 9.3 当前部署观察
|
||
|
||
- Docker compose 中定义了 `nomadro-minio`,端口计划为 `127.0.0.1:9100` 和 `127.0.0.1:9101`。
|
||
- 但当前 `docker ps` 只看到 `nomadro-ntfy` 运行,未看到 MinIO 容器。
|
||
- `.env.local` 中存在 MinIO 配置项,但报告未记录敏感值。
|
||
|
||
建议尽快确认生产上传到底走 MinIO 还是 FastAPI 本地目录,并统一一条路径。
|
||
|
||
## 10. systemd 服务
|
||
|
||
### 10.1 NomadCNA Next.js
|
||
|
||
服务名:`cnomadcna.service`
|
||
状态:enabled / active / running
|
||
工作目录:`/home/ubuntu/gitlab-instance-0a899031_cnomadcna`
|
||
启动脚本:`/home/ubuntu/gitlab-instance-0a899031_cnomadcna/cnomadcna.sh`
|
||
环境:
|
||
|
||
- `NODE_ENV=production`
|
||
- `HOSTNAME=0.0.0.0`
|
||
- `PORT=4002`
|
||
|
||
启动命令最终为:
|
||
|
||
```bash
|
||
pnpm start
|
||
```
|
||
|
||
`package.json` 中 `start` 为:
|
||
|
||
```bash
|
||
next start
|
||
```
|
||
|
||
当前运行:
|
||
|
||
- 主进程:`node /usr/local/bin/pnpm start`
|
||
- 子进程:`next-server (v16.1.6)`
|
||
- 监听:`*:4002`
|
||
- 最近启动:2026-06-06 21:50 CST
|
||
|
||
### 10.2 NomadCNA FastAPI
|
||
|
||
服务名:`cnomadcna-api.service`
|
||
状态:enabled / active / running
|
||
工作目录:`/home/ubuntu/gitlab-instance-0a899031_cnomadcna`
|
||
环境文件:`/home/ubuntu/gitlab-instance-0a899031_cnomadcna/backend/.env`
|
||
启动命令:
|
||
|
||
```bash
|
||
/home/ubuntu/gitlab-instance-0a899031_cnomadcna/backend/.venv/bin/uvicorn backend.main:app --host 127.0.0.1 --port 8000
|
||
```
|
||
|
||
当前运行:
|
||
|
||
- 主进程:`uvicorn`
|
||
- 监听:`127.0.0.1:8000`
|
||
- 最近启动:2026-06-06 21:46 CST
|
||
|
||
### 10.3 PocketBase
|
||
|
||
服务名:`pocketbase.service`
|
||
状态:enabled / active / running
|
||
工作目录:`/opt/pocketbase`
|
||
启动命令:
|
||
|
||
```bash
|
||
/opt/pocketbase/pocketbase serve --http=127.0.0.1:8090 --dir=/opt/pocketbase/pb_data --origins=https://nomadro.cn,https://www.nomadro.cn,https://pocketbase.nomadro.cn
|
||
```
|
||
|
||
监听:`127.0.0.1:8090`
|
||
|
||
### 10.4 Umami
|
||
|
||
服务名:`umami.service`
|
||
状态:enabled / active / running
|
||
用户:`umami`
|
||
工作目录:`/opt/umami`
|
||
环境文件:`/opt/umami/.env.production`
|
||
启动命令:
|
||
|
||
```bash
|
||
/usr/local/bin/node /opt/umami/.next/standalone/server.js
|
||
```
|
||
|
||
监听:`127.0.0.1:9280`
|
||
注意:最近日志有 Next.js Server Action 找不到的错误,可能来自旧前端请求或版本切换后的残留请求。
|
||
|
||
### 10.5 Netdata
|
||
|
||
服务名:`netdata.service`
|
||
状态:enabled / active / running
|
||
监听:`127.0.0.1:19999`
|
||
Nginx 反代:`netdata.nomadro.cn`,带 Basic Auth。
|
||
|
||
### 10.6 其他同机服务
|
||
|
||
| 服务 | 状态 | 说明 |
|
||
| --- | --- | --- |
|
||
| `nginx` | running | 宝塔 Nginx,主反向代理 |
|
||
| `mysqld` | running | MariaDB/MySQL |
|
||
| `postgresql@16-main` | running | PostgreSQL 16,Umami 使用 |
|
||
| `docker` / `containerd` | running | Docker 运行时 |
|
||
| `pure-ftpd` | running | FTP |
|
||
| `frpp.service` | running | frp-panel |
|
||
| `site_total.service` | running | 宝塔站点统计 |
|
||
| `BT-FirewallServices.service` | running | 宝塔防火墙服务 |
|
||
|
||
## 11. Nginx 反向代理
|
||
|
||
Nginx 配置路径:`/www/server/panel/vhost/nginx/`
|
||
|
||
### 11.1 主站
|
||
|
||
配置文件:`/www/server/panel/vhost/nginx/www.nomadro.cn.conf`
|
||
|
||
- upstream:`nomadro_nextjs`
|
||
- upstream 地址:`127.0.0.1:4002`
|
||
- `80` 端口:重定向到 HTTPS。
|
||
- `443 ssl http2`:代理到 Next.js。
|
||
- 证书:`/etc/letsencrypt/live/nomadro.cn/fullchain.pem`
|
||
- 日志:
|
||
- `/www/wwwlogs/www.nomadro.cn.log`
|
||
- `/www/wwwlogs/www.nomadro.cn.error.log`
|
||
|
||
### 11.2 FastAPI
|
||
|
||
配置文件:`/www/server/panel/vhost/nginx/api.nomadro.cn.conf`
|
||
|
||
- upstream:`nomadro_api`
|
||
- upstream 地址:`127.0.0.1:8000`
|
||
- 当前只看到 HTTP server 配置。
|
||
- 日志:
|
||
- `/www/wwwlogs/api.nomadro.cn.log`
|
||
- `/www/wwwlogs/api.nomadro.cn.error.log`
|
||
|
||
建议为 `api.nomadro.cn` 配置 HTTPS,尤其是认证、支付、会员接口需要安全传输。
|
||
|
||
### 11.3 PocketBase
|
||
|
||
配置文件:`/www/server/panel/vhost/nginx/pocketbase.nomadro.cn.conf`
|
||
|
||
- upstream:`nomadro_pocketbase`
|
||
- upstream 地址:`127.0.0.1:8090`
|
||
- `80` 重定向到 HTTPS。
|
||
- `443 ssl http2` 代理到 PocketBase。
|
||
- 证书:`/etc/letsencrypt/live/pocketbase.nomadro.cn/fullchain.pem`
|
||
|
||
### 11.4 Umami
|
||
|
||
配置文件:`/www/server/panel/vhost/nginx/umami.nomadro.cn.conf`
|
||
|
||
- upstream:`nomadro_umami`
|
||
- upstream 地址:`127.0.0.1:9280`
|
||
- `80` 重定向到 HTTPS。
|
||
- `443 ssl http2` 代理到 Umami。
|
||
|
||
### 11.5 ntfy
|
||
|
||
配置文件:`/www/server/panel/vhost/nginx/ntfy.nomadro.cn.conf`
|
||
|
||
- upstream:`nomadro_ntfy`
|
||
- upstream 地址:`127.0.0.1:9180`
|
||
- 当前只看到 HTTP server 配置。
|
||
- 建议后续补 HTTPS。
|
||
|
||
### 11.6 Netdata
|
||
|
||
配置文件:`/www/server/panel/vhost/nginx/netdata.nomadro.cn.conf`
|
||
|
||
- upstream:`nomadro_netdata`
|
||
- upstream 地址:`127.0.0.1:19999`
|
||
- 使用 Basic Auth 文件:`/www/server/panel/vhost/nginx/netdata.nomadro.cn.htpasswd`
|
||
- 当前只看到 HTTP server 配置。
|
||
|
||
### 11.7 Nginx 配置校验
|
||
|
||
已执行 Nginx 配置测试:
|
||
|
||
```bash
|
||
nginx -t
|
||
```
|
||
|
||
结果:syntax ok,test successful。
|
||
|
||
## 12. TLS 证书
|
||
|
||
Certbot 当前证书:
|
||
|
||
| 证书名 | 域名 | 到期时间 |
|
||
| --- | --- | --- |
|
||
| `nomadro.cn` | `nomadro.cn`, `www.nomadro.cn` | 2026-09-04 12:34:54 UTC |
|
||
| `pocketbase.nomadro.cn` | `pocketbase.nomadro.cn` | 2026-09-04 12:49:52 UTC |
|
||
| `umami.nomadro.cn` | `umami.nomadro.cn` | 2026-09-04 13:58:40 UTC |
|
||
|
||
当前未看到 `api.nomadro.cn`、`ntfy.nomadro.cn`、`netdata.nomadro.cn` 的 Certbot 证书。
|
||
|
||
## 13. Docker 服务
|
||
|
||
当前 `docker ps` 只看到:
|
||
|
||
| 容器 | 镜像 | 状态 | 端口 |
|
||
| --- | --- | --- | --- |
|
||
| `nomadro-ntfy` | `binwiederhier/ntfy:latest` | running | `127.0.0.1:9180->80` |
|
||
|
||
`/opt/nomadro-services/docker-compose.yml` 中还定义了:
|
||
|
||
- `nomadro-minio`:对象存储,计划监听 `127.0.0.1:9100` / `127.0.0.1:9101`。
|
||
- `nomadro-ntfy`:通知推送。
|
||
- `nomadro-uptime-kuma`:可用性监控,计划监听 `127.0.0.1:9301`。
|
||
- `nomadro-netdata`:容器版 Netdata,计划监听 `127.0.0.1:9199`。
|
||
- `nomadro-mirotalk`:视频会议,计划监听 `127.0.0.1:9300`。
|
||
|
||
实际运行和 compose 定义不完全一致。当前宿主机 systemd 版 Netdata 正在运行,Docker 版 Netdata 未运行。MinIO、Uptime Kuma、MiroTalk 当前也未在 `docker ps` 中出现。
|
||
|
||
## 14. 服务器资源与安全边界
|
||
|
||
### 14.1 系统信息
|
||
|
||
- 主机名:`VM-0-16-ubuntu`
|
||
- 云厂商:Tencent Cloud CVM
|
||
- 操作系统:Ubuntu 24.04.4 LTS
|
||
- 内核:Linux 6.8.0-101-generic
|
||
- 架构:x86_64
|
||
- 运行时间:约 6 天 9 小时
|
||
|
||
### 14.2 资源状态
|
||
|
||
- 内存:3.6Gi,总可用约 2.5Gi。
|
||
- Swap:1.9Gi,已用约 512Mi。
|
||
- 根分区:69G,总用量 17G,可用 50G,使用率 25%。
|
||
- 当前负载较低。
|
||
|
||
### 14.3 防火墙
|
||
|
||
UFW 状态:active
|
||
默认策略:
|
||
|
||
- incoming:deny
|
||
- outgoing:allow
|
||
- routed:deny
|
||
|
||
当前开放端口包括:
|
||
|
||
- `80`
|
||
- `443`
|
||
- `22`
|
||
- `21`
|
||
- `20/tcp`
|
||
- `888/tcp`
|
||
- `8080`
|
||
- `36711/tcp`
|
||
- `39000:40000/tcp`
|
||
- 以及一个 `8` 规则
|
||
|
||
风险点:
|
||
|
||
- FTP 端口 `20/21` 和被动端口段 `39000:40000` 对公网开放。
|
||
- 宝塔面板端口 `888`、`36711` 对公网开放。
|
||
- `22` 对公网开放。
|
||
- `3306` MariaDB 当前监听 `0.0.0.0:3306`,即便 UFW 未列出 `3306` 开放,也建议数据库服务改为只监听本地或确保云防火墙关闭公网访问。
|
||
|
||
## 15. 环境变量与配置
|
||
|
||
### 15.1 根目录 `.env.local`
|
||
|
||
当前项目根目录存在 `.env.local`,生产构建会加载它。已确认其包含以下类别变量:
|
||
|
||
- 根域名:`ROOT_DOMAIN`、`NEXT_PUBLIC_ROOT_DOMAIN`
|
||
- PocketBase:`NEXT_PUBLIC_POCKETBASE_URL`、`POCKETBASE_URL`
|
||
- 支付:`PAYMENT_API_URL`、`PAYMENT_PROVIDER`、`PAYMENT_DEFAULT_AMOUNT`、`PAYMENT_JOIN_AMOUNT`
|
||
- 站点:`NEXT_PUBLIC_SITE_ID`、`NEXT_PUBLIC_SITE_URL`、`NEXT_PUBLIC_API_BASE_URL`
|
||
- MinIO:`MINIO_ENDPOINT`、`MINIO_PORT`、`MINIO_USE_SSL`
|
||
- PocketBase 管理员:`POCKETBASE_EMAIL`、`POCKETBASE_PASSWORD`
|
||
|
||
### 15.2 FastAPI `backend/.env`
|
||
|
||
当前 systemd 会读取 `backend/.env`,包含:
|
||
|
||
- `PB_URL`
|
||
- `PB_ADMIN_EMAIL`
|
||
- `PB_ADMIN_PASSWORD`
|
||
- `API_COOKIE_NAME`
|
||
- `FRONTEND_ORIGINS`
|
||
- `UPLOAD_DIR`
|
||
- `DEV_AUTO_PAY`
|
||
|
||
### 15.3 敏感文件 Git 风险
|
||
|
||
`git ls-files` 显示以下文件被 Git 跟踪:
|
||
|
||
- `.env.example`
|
||
- `.env.local`
|
||
- `.env.local.bak.20260606212903`
|
||
- `backend/.env.example`
|
||
|
||
其中 `.env.local` 和 `.env.local.bak.*` 不应被提交。`.env.example` 当前也包含真实样式的敏感配置,不应放真实账号或密码。
|
||
|
||
建议:
|
||
|
||
1. 立即将 `.env.local` 和 `.env.local.bak.*` 从 Git 索引移除。
|
||
2. 将 `.gitignore` 中的 `# .env*` 改为实际忽略规则。
|
||
3. 重置已经暴露过的 PocketBase、支付、MinIO 等所有密钥。
|
||
4. `.env.example` 只保留占位符,例如 `POCKETBASE_PASSWORD=replace_me`。
|
||
|
||
## 16. 构建与质量状态
|
||
|
||
### 16.1 `pnpm build`
|
||
|
||
已执行:
|
||
|
||
```bash
|
||
pnpm build
|
||
```
|
||
|
||
结果:通过。
|
||
|
||
构建输出:
|
||
|
||
- Next.js `16.1.6`
|
||
- 成功编译。
|
||
- TypeScript 检查通过。
|
||
- 静态页面生成:85 个。
|
||
- 路由包含 `/zh`、`/en` 以及所有主要页面。
|
||
- API route 均被识别为动态服务端路由。
|
||
|
||
注意:本次构建刷新了 `.next` 产物时间戳,`.next/BUILD_ID` 时间为 2026-06-06 23:16 CST。
|
||
|
||
### 16.2 `pnpm lint`
|
||
|
||
已执行:
|
||
|
||
```bash
|
||
pnpm lint
|
||
```
|
||
|
||
结果:失败,`7 errors / 31 warnings`。
|
||
|
||
主要错误:
|
||
|
||
- `app/[locale]/dashboard/page.tsx`:React Hooks 新规则提示 effect 内同步 `setLoading(true)`。
|
||
- `app/api/meetup/complete-order/route.ts`:`userId` 和 `payType` 应使用 `const`。
|
||
- `app/components/CityModal.tsx`:effect 内同步 `setMounted(true)`。
|
||
- `app/components/SiteMenu.tsx`:effect 内同步 `setUserEmail(...)`。
|
||
- `app/components/ThemeToggle.tsx`:effect 内同步 `setMounted(true)`。
|
||
- `app/context/ThemeContext.tsx`:effect 内同步设置 theme/mounted。
|
||
|
||
主要警告:
|
||
|
||
- 多处使用 `<img>`,Next.js 建议使用 `next/image`。
|
||
- 若干未使用变量。
|
||
- `MembersMap.tsx` 有 hook 依赖提示。
|
||
|
||
结论:
|
||
|
||
- 当前源码可以生产构建并运行。
|
||
- 但 lint 不通过,CI 若以 lint 为发布门槛会失败。
|
||
- 建议先修复 7 个 lint error,再逐步处理图片优化和未使用变量。
|
||
|
||
## 17. 当前运行日志观察
|
||
|
||
### 17.1 Next.js
|
||
|
||
最近重启后正常启动,监听 `4002`。日志有 Node.js deprecation warning:
|
||
|
||
- `util._extend` 已废弃,建议依赖链后续升级或等待 Next/相关依赖修复。
|
||
|
||
### 17.2 FastAPI
|
||
|
||
最近启动正常。早些时候曾出现:
|
||
|
||
- `PocketBase 404: Missing collection context.`
|
||
|
||
随后 PocketBase 集合初始化后,`/api/cities`、`/api/profiles`、`/api/content/home` 已返回 `200`。
|
||
|
||
当前还看到外部或代理访问 `/` 和 `/favicon.ico` 到 FastAPI 时返回 `404`,这是正常的,因为 FastAPI 只提供 `/api/*` 和 `/uploads/*`。
|
||
|
||
### 17.3 PocketBase
|
||
|
||
启动正常,REST API 和 Dashboard 均监听 `127.0.0.1:8090`。
|
||
|
||
### 17.4 Umami
|
||
|
||
服务运行中,但日志出现 `Failed to find Server Action "000000..."`。可能是部署切换后旧请求、缓存或探测请求造成,需要后续观察。
|
||
|
||
### 17.5 宝塔 site_total
|
||
|
||
`site_total.service` 日志持续出现写 HyperLogLog 文件失败,路径类似:
|
||
|
||
- `/www/server/site_total/data/hll/2026-06-04/www.nomadro.cn.hll`
|
||
- `/www/server/site_total/data/hll/2026-06-04/ALL.hll`
|
||
|
||
这不直接影响 NomadCNA 主站,但会影响宝塔站点统计准确性。
|
||
|
||
## 18. 运维命令速查
|
||
|
||
### 18.1 项目前端
|
||
|
||
```bash
|
||
cd /home/ubuntu/gitlab-instance-0a899031_cnomadcna
|
||
pnpm install
|
||
pnpm build
|
||
pnpm start
|
||
```
|
||
|
||
开发模式:
|
||
|
||
```bash
|
||
pnpm dev
|
||
```
|
||
|
||
注意:`package.json` 中 dev 实际端口是 `3001`:
|
||
|
||
```bash
|
||
next dev -p 3001 -H 0.0.0.0
|
||
```
|
||
|
||
### 18.2 后端
|
||
|
||
```bash
|
||
cd /home/ubuntu/gitlab-instance-0a899031_cnomadcna
|
||
source backend/.venv/bin/activate
|
||
pip install -r backend/requirements.txt
|
||
uvicorn backend.main:app --host 127.0.0.1 --port 8000
|
||
```
|
||
|
||
初始化 PocketBase 集合和种子:
|
||
|
||
```bash
|
||
cd /home/ubuntu/gitlab-instance-0a899031_cnomadcna
|
||
source backend/.venv/bin/activate
|
||
python -m backend.init_db
|
||
```
|
||
|
||
### 18.3 systemd
|
||
|
||
查看状态:
|
||
|
||
```bash
|
||
systemctl status cnomadcna.service --no-pager -l
|
||
systemctl status cnomadcna-api.service --no-pager -l
|
||
systemctl status pocketbase.service --no-pager -l
|
||
systemctl status umami.service --no-pager -l
|
||
```
|
||
|
||
重启服务:
|
||
|
||
```bash
|
||
systemctl restart cnomadcna.service
|
||
systemctl restart cnomadcna-api.service
|
||
systemctl restart pocketbase.service
|
||
```
|
||
|
||
查看日志:
|
||
|
||
```bash
|
||
journalctl -u cnomadcna.service -n 100 --no-pager
|
||
journalctl -u cnomadcna-api.service -n 100 --no-pager
|
||
journalctl -u pocketbase.service -n 100 --no-pager
|
||
journalctl -u umami.service -n 100 --no-pager
|
||
```
|
||
|
||
### 18.4 Nginx
|
||
|
||
测试配置:
|
||
|
||
```bash
|
||
nginx -t
|
||
```
|
||
|
||
重载配置:
|
||
|
||
```bash
|
||
systemctl reload nginx
|
||
```
|
||
|
||
主站日志:
|
||
|
||
```bash
|
||
tail -f /www/wwwlogs/www.nomadro.cn.log
|
||
tail -f /www/wwwlogs/www.nomadro.cn.error.log
|
||
```
|
||
|
||
API 日志:
|
||
|
||
```bash
|
||
tail -f /www/wwwlogs/api.nomadro.cn.log
|
||
tail -f /www/wwwlogs/api.nomadro.cn.error.log
|
||
```
|
||
|
||
### 18.5 健康检查
|
||
|
||
```bash
|
||
curl -fsS http://127.0.0.1:8000/api/health
|
||
curl -I http://127.0.0.1:4002/zh
|
||
curl -I http://127.0.0.1:8090/api/health
|
||
curl -fsS http://api.nomadro.cn/api/health
|
||
curl -I https://nomadro.cn
|
||
curl -I https://pocketbase.nomadro.cn/api/health
|
||
```
|
||
|
||
### 18.6 Docker 服务
|
||
|
||
```bash
|
||
docker ps
|
||
cd /opt/nomadro-services
|
||
docker compose ps
|
||
docker compose up -d
|
||
docker compose logs -f ntfy
|
||
```
|
||
|
||
## 19. 主要风险清单
|
||
|
||
### P0:敏感环境文件被 Git 跟踪
|
||
|
||
`.env.local` 和 `.env.local.bak.20260606212903` 已被 Git 跟踪。`.env.example` 也包含真实样式敏感信息。
|
||
影响:密钥泄露风险。
|
||
建议:从 Git 索引移除、重置所有已暴露密钥、改 `.env.example` 为占位符、更新 `.gitignore`。
|
||
|
||
### P0:API 子域未配置 HTTPS
|
||
|
||
`api.nomadro.cn` 当前只看到 HTTP Nginx 配置。
|
||
影响:登录态、支付确认、用户资料提交等请求如果走公网 HTTP,存在明文传输风险。
|
||
建议:为 `api.nomadro.cn` 申请证书并强制 HTTP 到 HTTPS。
|
||
|
||
### P0:默认密码 `12345678`
|
||
|
||
新用户支付后使用固定默认密码。
|
||
影响:弱口令和撞库风险。
|
||
建议:改为随机临时密码、一次性链接、强制首次设置密码。
|
||
|
||
### P1:会员集合不一致
|
||
|
||
Next.js 使用 `site_vip`,FastAPI 使用 `memberships`。
|
||
影响:支付后不同接口可能返回不同会员状态。
|
||
建议:统一会员表或明确同步策略。
|
||
|
||
### P1:MinIO 运行状态和代码配置不一致
|
||
|
||
代码中 Next.js 上传走 MinIO,但当前 Docker 只看到 `nomadro-ntfy`,未看到 MinIO 运行。
|
||
影响:生产上传可能失败。
|
||
建议:确认 MinIO 是否部署在其他机器/域名;如果是本机,启动并配置反代;如果不用 MinIO,统一改为 FastAPI 本地上传或其他对象存储。
|
||
|
||
### P1:Lint 不通过
|
||
|
||
`pnpm lint` 当前 7 个 error。
|
||
影响:CI/CD、代码质量和后续维护。
|
||
建议:优先修复 lint error,再处理 warning。
|
||
|
||
### P1:数据库与管理端口暴露面较大
|
||
|
||
MariaDB 监听 `0.0.0.0:3306`,FTP、宝塔面板、SSH 对公网开放。
|
||
影响:攻击面扩大。
|
||
建议:数据库只监听本地;管理端口限制 IP;SSH 使用密钥、禁用密码或更换端口;FTP 如非必要关闭。
|
||
|
||
### P2:`NEXT_PUBLIC_API_BASE_URL` 必须稳定设置
|
||
|
||
`app/lib/api-client.ts` 默认值是 `http://127.0.0.1:8000`。
|
||
影响:若生产构建没有设置 `NEXT_PUBLIC_API_BASE_URL`,浏览器会访问用户本机 localhost。
|
||
建议:生产环境固定设置为 API 公网域名,且优先升级到 HTTPS。
|
||
|
||
### P2:站点统计服务有错误日志
|
||
|
||
宝塔 `site_total` 无法写 hll 文件。
|
||
影响:宝塔统计不准确。
|
||
建议:检查目录是否存在、权限是否正确,或关闭无用统计。
|
||
|
||
### P2:同机服务较多
|
||
|
||
同机运行 NomadCNA、PocketBase、Umami、MariaDB、PostgreSQL、Docker、Netdata、FTP、宝塔、frp-panel。
|
||
影响:故障面复杂,资源争用和安全边界不清晰。
|
||
建议:为生产服务建立清晰分层,至少将数据库/监控/管理面板访问收紧。
|
||
|
||
## 20. 建议的下一步
|
||
|
||
### 20.1 立即处理
|
||
|
||
1. 清理 Git 中的 `.env.local`、`.env.local.bak.*`,重置所有相关密钥。
|
||
2. 为 `api.nomadro.cn` 配置 HTTPS,并让前端 `NEXT_PUBLIC_API_BASE_URL` 使用 HTTPS。
|
||
3. 统一 VIP 数据模型,确认 `site_vip` 是否存在并补充迁移。
|
||
4. 修复 `pnpm lint` 的 7 个 error。
|
||
5. 确认 MinIO 是否实际运行;若未运行,先修复上传链路。
|
||
|
||
### 20.2 一周内处理
|
||
|
||
1. 将默认密码机制改为随机临时密码或首次设置密码。
|
||
2. 为 `ntfy.nomadro.cn`、`netdata.nomadro.cn` 补 HTTPS,或仅内网/白名单访问。
|
||
3. 收紧 FTP、宝塔、SSH、MariaDB 的公网访问面。
|
||
4. 为 PocketBase 数据目录建立自动备份策略。
|
||
5. 添加 API smoke test,包括 `/api/health`、`/api/cities`、`/api/auth/me`、`/api/vip/check`、`/api/upload-media`。
|
||
|
||
### 20.3 产品增强
|
||
|
||
1. 城市数据接入真实来源,增加数据更新时间和数据来源说明。
|
||
2. AI 助手接入真实模型,并基于用户画像、预算、收藏、路线生成建议。
|
||
3. 站内消息接入 ntfy / 邮件 / 企业微信。
|
||
4. 活动报名、赏金接单、服务咨询增加后台运营视图。
|
||
5. 定价页与真实支付金额、会员权益完全一致。
|
||
6. 对首页和城市卡片图片迁移到 `next/image` 或明确 CDN 图片策略。
|
||
|
||
## 21. 当前结论
|
||
|
||
NomadCNA 当前已经完成了数字游民网站的关键骨架:
|
||
|
||
- 主站可通过 `nomadro.cn` 和 `www.nomadro.cn` 访问。
|
||
- Next.js 生产服务、FastAPI、PocketBase 均在 systemd 中运行。
|
||
- Nginx 已完成主站、PocketBase、Umami 的 HTTPS 反向代理。
|
||
- FastAPI 健康接口、主站页面、PocketBase 健康接口均验证可用。
|
||
- PocketBase 已有城市、内容、活动、讨论、赏金、成员、服务、路线、通知等完整业务集合。
|
||
- 前端页面覆盖城市发现、下一站推荐、活动、匹配、工具、AI、赏金、服务、会员、报名、支付成功页和消息中心。
|
||
- `pnpm build` 已通过,说明当前生产构建可用。
|
||
|
||
同时,当前最需要优先处理的是生产安全和一致性:
|
||
|
||
- 敏感环境文件不能继续被 Git 跟踪。
|
||
- API 域名需要 HTTPS。
|
||
- 会员数据模型需要统一。
|
||
- 固定默认密码需要替换。
|
||
- 上传服务需要确认实际可用。
|
||
- lint error 需要修复,以便后续稳定迭代。
|
||
|
||
整体判断:当前项目已经具备上线早期数字游民平台的基础能力,但在正式扩大用户规模前,应先完成密钥治理、HTTPS、会员模型、上传链路和 lint 修复。
|