docs: add npm deployment guide
This commit is contained in:
@@ -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
|
||||
```
|
||||
Reference in New Issue
Block a user