From 228d625e1644de82a0d80750c832ab49594a7a54 Mon Sep 17 00:00:00 2001 From: lwt <215586800@qq.com> Date: Mon, 8 Jun 2026 21:06:01 +0800 Subject: [PATCH] docs: add npm deployment guide --- DEPLOY.md | 344 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 DEPLOY.md diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 0000000..e0b741a --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,344 @@ +# sumi.work NPM 部署说明 + +这份文档给 AI/运维执行者使用,用于把当前仓库部署为可运行的 Node.js 服务。项目包含静态首页、软件下载中心、玩家登录下载限制、软件管理后台和上传更新 API。 + +## 1. 运行环境 + +要求: + +- Node.js 20+,推荐 Node.js 22 LTS 或更高版本 +- npm +- 可写目录:`server/data/`、`server/uploads/` +- 对外端口:默认 `3030`,可通过 `PORT` 修改 + +检查: + +```bash +node --version +npm --version +``` + +## 2. 获取代码 + +```bash +git clone ssh://git@www.sumi.work:222/lwt/sumi.work.git +cd sumi.work +``` + +如果服务器上已经有仓库: + +```bash +cd /path/to/sumi.work +git pull origin main +``` + +## 3. 安装依赖 + +生产环境建议使用锁文件安装: + +```bash +npm ci +``` + +如果没有 `package-lock.json` 或需要临时恢复: + +```bash +npm install +``` + +## 4. 配置环境变量 + +必须为生产环境设置自己的管理令牌和玩家账号密码,不要使用默认值。 + +```bash +export PORT=3030 +export ADMIN_TOKEN="change-this-admin-token" +export PLAYER_USERNAME="player" +export PLAYER_PASSWORD="change-this-player-password" +``` + +可选变量: + +```bash +export MAX_UPLOAD_BYTES=1073741824 +export PLAYER_SESSION_TTL_MS=604800000 +``` + +变量说明: + +- `PORT`:Node 服务监听端口,默认 `3030` +- `ADMIN_TOKEN`:管理后台调用上传/更新/删除 API 的令牌 +- `PLAYER_USERNAME`:玩家登录账号 +- `PLAYER_PASSWORD`:玩家登录密码 +- `MAX_UPLOAD_BYTES`:最大上传文件大小,默认 1GB +- `PLAYER_SESSION_TTL_MS`:玩家登录有效期,默认 7 天 + +首次启动时,如果 `server/data/players.json` 不存在,服务会生成默认玩家。设置了 `PLAYER_USERNAME` 和 `PLAYER_PASSWORD` 时,会写入或更新对应玩家账号。 + +## 5. 启动服务 + +直接启动: + +```bash +npm start +``` + +启动后访问: + +- 首页:`http://服务器IP:3030/` +- 下载中心:`http://服务器IP:3030/software.html` +- 玩家登录:`http://服务器IP:3030/login.html` +- 管理后台:`http://服务器IP:3030/admin/software.html` + +## 6. 用 PM2 部署 + +安装 PM2: + +```bash +npm install -g pm2 +``` + +启动: + +```bash +PORT=3030 \ +ADMIN_TOKEN="change-this-admin-token" \ +PLAYER_USERNAME="player" \ +PLAYER_PASSWORD="change-this-player-password" \ +pm2 start server/server.js --name sumi-work +``` + +保存进程: + +```bash +pm2 save +pm2 startup +``` + +查看日志: + +```bash +pm2 logs sumi-work +``` + +重启: + +```bash +pm2 restart sumi-work +``` + +更新部署: + +```bash +cd /path/to/sumi.work +git pull origin main +npm ci +pm2 restart sumi-work +``` + +## 7. 用 systemd 部署 + +创建服务文件: + +```bash +sudo nano /etc/systemd/system/sumi-work.service +``` + +示例内容,按实际路径替换 `WorkingDirectory`: + +```ini +[Unit] +Description=sumi.work Node Service +After=network.target + +[Service] +Type=simple +WorkingDirectory=/path/to/sumi.work +ExecStart=/usr/bin/node server/server.js +Restart=always +RestartSec=3 +Environment=NODE_ENV=production +Environment=PORT=3030 +Environment=ADMIN_TOKEN=change-this-admin-token +Environment=PLAYER_USERNAME=player +Environment=PLAYER_PASSWORD=change-this-player-password + +[Install] +WantedBy=multi-user.target +``` + +启动并设置开机自启: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable --now sumi-work +sudo systemctl status sumi-work +``` + +查看日志: + +```bash +journalctl -u sumi-work -f +``` + +更新部署: + +```bash +cd /path/to/sumi.work +git pull origin main +npm ci +sudo systemctl restart sumi-work +``` + +## 8. Nginx 反向代理 + +建议让 Nginx 只反向代理到 Node 服务,不要直接把 `server/uploads/packages` 暴露成静态目录。安装包下载必须走 `/api/software/:id/download`,这样才能验证玩家登录。 + +示例: + +```nginx +server { + listen 80; + server_name sumi.work www.sumi.work; + + client_max_body_size 1024m; + + location / { + proxy_pass http://127.0.0.1:3030; + 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; + } +} +``` + +重新加载: + +```bash +sudo nginx -t +sudo systemctl reload nginx +``` + +## 9. 验证部署 + +健康检查: + +```bash +curl -i http://127.0.0.1:3030/api/health +``` + +预期包含: + +```json +{"ok":true,"service":"sumi-software-center"} +``` + +检查软件下载列表: + +```bash +curl -i http://127.0.0.1:3030/api/software +``` + +检查未登录不能下载: + +```bash +curl -i -H "Accept: application/json" http://127.0.0.1:3030/api/software/sumi-launcher/download +``` + +预期: + +```text +HTTP/1.1 401 Unauthorized +``` + +检查玩家登录: + +```bash +curl -i \ + -c /tmp/sumi-player.cookie \ + -H "Content-Type: application/json" \ + -d '{"username":"player","password":"change-this-player-password","next":"/software.html"}' \ + http://127.0.0.1:3030/api/auth/login +``` + +检查登录状态: + +```bash +curl -i -b /tmp/sumi-player.cookie http://127.0.0.1:3030/api/auth/me +``` + +管理后台读取列表: + +```bash +curl -i -H "X-Admin-Token: change-this-admin-token" http://127.0.0.1:3030/api/admin/software +``` + +## 10. 数据与备份 + +需要持久化和备份: + +- `server/data/software.json`:软件元数据 +- `server/data/players.json`:玩家账号数据 +- `server/uploads/icons/`:上传的软件图标 +- `server/uploads/packages/`:上传的软件安装包 + +建议备份命令: + +```bash +tar -czf sumi-work-data-$(date +%F).tar.gz server/data server/uploads +``` + +恢复时把这两个目录放回仓库根目录,然后重启服务。 + +## 11. 常见问题 + +端口被占用: + +```bash +lsof -i :3030 +``` + +修改 `PORT` 后重启服务。 + +上传失败: + +- 检查 `client_max_body_size` +- 检查 `MAX_UPLOAD_BYTES` +- 检查 `server/uploads/` 是否可写 + +管理后台 401: + +- 确认前端输入的 `ADMIN_TOKEN` 与服务端环境变量一致 +- 确认请求头是 `X-Admin-Token` + +玩家无法下载: + +- 先访问 `/login.html` 登录 +- 确认 `/api/auth/me` 返回 `authenticated: true` +- 确认 Nginx 没有直接拦截或改写 Cookie + +安装包被绕过下载: + +- 不要配置 Nginx 直接静态暴露 `server/uploads/packages/` +- 正确做法是所有请求都反代到 Node 服务 + +## 12. 快速执行清单 + +```bash +cd /path/to/sumi.work +git pull origin main +npm ci +export PORT=3030 +export ADMIN_TOKEN="change-this-admin-token" +export PLAYER_USERNAME="player" +export PLAYER_PASSWORD="change-this-player-password" +npm start +``` + +验证: + +```bash +curl http://127.0.0.1:3030/api/health +```