220 lines
4.1 KiB
Markdown
220 lines
4.1 KiB
Markdown
|
|
# Sub2API Windows 本地部署问题排查
|
|||
|
|
|
|||
|
|
## 问题描述
|
|||
|
|
|
|||
|
|
在 Windows 本地环境下运行 Sub2API 时,遇到以下问题:
|
|||
|
|
|
|||
|
|
| 症状 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| API 路由 404 | `/api/v1/*` 所有接口返回 404 |
|
|||
|
|
| 设置向导卡住 | `/setup/status` 返回 `needs_setup: true` |
|
|||
|
|
| 前端正常 | `/` 返回 HTML,但无法正常使用 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 根本原因
|
|||
|
|
|
|||
|
|
### 问题 1:`.installed` 锁文件缺失
|
|||
|
|
|
|||
|
|
**`NeedsSetup()` 函数的检查逻辑:**
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
// internal/setup/setup.go
|
|||
|
|
func NeedsSetup() bool {
|
|||
|
|
// 检查 1: config.yaml 必须不存在
|
|||
|
|
if _, err := os.Stat(GetConfigFilePath()); !os.IsNotExist(err) {
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
// 检查 2: .installed 锁文件(更难绕过)
|
|||
|
|
if _, err := os.Stat(GetInstallLockPath()); !os.IsNotExist(err) {
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**优先级:**
|
|||
|
|
1. `DATA_DIR` 环境变量
|
|||
|
|
2. `/app/data`(Docker 环境)
|
|||
|
|
3. **当前目录(默认)**
|
|||
|
|
|
|||
|
|
**症状:** 当前目录下缺少 `.installed` 文件,导致系统认为未安装。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 问题 2:`config.yaml` 中 `sslmode` 配置错误
|
|||
|
|
|
|||
|
|
**错误信息:**
|
|||
|
|
```
|
|||
|
|
pq: unsupported sslmode "prefer"; only "require" (default),
|
|||
|
|
"verify-full", "verify-ca", and "disable" supported
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**`config.yaml` 缺少 `sslmode` 字段:**
|
|||
|
|
```yaml
|
|||
|
|
database:
|
|||
|
|
host: "localhost"
|
|||
|
|
port: 5432
|
|||
|
|
user: "postgres"
|
|||
|
|
password: "xing@niu99"
|
|||
|
|
dbname: "sub2api"
|
|||
|
|
# ❌ 缺少 sslmode 字段
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 解决方案
|
|||
|
|
|
|||
|
|
### 修复步骤
|
|||
|
|
|
|||
|
|
#### 1. 创建 `.installed` 锁文件
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd backend
|
|||
|
|
echo "installed_at=2026-03-24T00:00:00Z" > .installed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. 添加 `sslmode` 配置
|
|||
|
|
|
|||
|
|
编辑 `backend/config.yaml`:
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
database:
|
|||
|
|
host: "localhost"
|
|||
|
|
port: 5432
|
|||
|
|
user: "postgres"
|
|||
|
|
password: "your_password"
|
|||
|
|
dbname: "sub2api"
|
|||
|
|
sslmode: "disable" # ✅ 添加此行
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**可选值:**
|
|||
|
|
| 值 | 说明 |
|
|||
|
|
|----|------|
|
|||
|
|
| `disable` | 不使用 SSL(本地开发推荐) |
|
|||
|
|
| `require` | 使用 SSL但不验证证书 |
|
|||
|
|
| `verify-ca` | 验证服务器证书由可信 CA 签发 |
|
|||
|
|
| `verify-full` | 验证证书和主机名(生产环境推荐) |
|
|||
|
|
|
|||
|
|
#### 3. 重启服务器
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 确保使用 DATA_DIR 环境变量
|
|||
|
|
DATA_DIR=. ./sub2api.exe
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 验证
|
|||
|
|
|
|||
|
|
### 测试设置状态
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl http://localhost:8080/setup/status
|
|||
|
|
# 期望: {"code":0,"data":{"needs_setup":false,"step":"completed"}}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 测试 API 路由
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl -X POST http://localhost:8080/api/v1/auth/login \
|
|||
|
|
-H "Content-Type: application/json" \
|
|||
|
|
-d '{"email":"your@email.com","password":"your_password"}'
|
|||
|
|
# 期望: 返回 access_token(而非 404)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 预防措施
|
|||
|
|
|
|||
|
|
### 1. 始终设置 `sslmode`
|
|||
|
|
|
|||
|
|
创建 `config.yaml` 时,始终包含 `sslmode` 字段:
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
database:
|
|||
|
|
# ... 其他配置
|
|||
|
|
sslmode: "disable" # 本地开发
|
|||
|
|
# sslmode: "require" # 生产环境(外部数据库)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 使用环境变量指定数据目录
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Windows
|
|||
|
|
set DATA_DIR=D:\project\sub2api\backend
|
|||
|
|
sub2api.exe
|
|||
|
|
|
|||
|
|
# 或一行命令
|
|||
|
|
DATA_DIR=. ./sub2api.exe
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 初始化后创建锁文件
|
|||
|
|
|
|||
|
|
如果通过数据库初始化脚本创建数据,需要手动创建锁文件:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 安装完成后
|
|||
|
|
echo "installed_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)" > .installed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 相关文件
|
|||
|
|
|
|||
|
|
| 文件 | 作用 |
|
|||
|
|
|------|------|
|
|||
|
|
| `internal/setup/setup.go` | 安装逻辑、`NeedsSetup()` 检查 |
|
|||
|
|
| `internal/config/config.go` | 配置加载、`LoadForBootstrap()` |
|
|||
|
|
| `config.yaml` | 配置文件 |
|
|||
|
|
| `.installed` | 安装锁文件(防止重装攻击) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 调试技巧
|
|||
|
|
|
|||
|
|
### 查看服务器启动日志
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 前台运行查看完整日志
|
|||
|
|
./sub2api.exe
|
|||
|
|
|
|||
|
|
# 或
|
|||
|
|
DATA_DIR=. ./sub2api.exe
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 检查锁文件位置
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
// 确认 GetDataDir() 返回值
|
|||
|
|
// internal/setup/setup.go
|
|||
|
|
func GetDataDir() string {
|
|||
|
|
if dir := os.Getenv("DATA_DIR"); dir != "" {
|
|||
|
|
return dir
|
|||
|
|
}
|
|||
|
|
// Docker 环境检查...
|
|||
|
|
return "." // 默认当前目录
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 测试 PostgreSQL 连接
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
PGPASSWORD="your_password" psql -h localhost -U postgres -d sub2api -c "SELECT 1;"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 测试 Redis 连接
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
redis-cli ping
|
|||
|
|
# 期望: PONG
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 修改记录
|
|||
|
|
|
|||
|
|
| 日期 | 修改内容 |
|
|||
|
|
|------|----------|
|
|||
|
|
| 2026-03-24 | 初始文档创建 |
|