# 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 ```