Files
sumi.work/DEPLOY.md
T
2026-06-08 21:06:01 +08:00

345 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```