fix: improve qbittorrent host connectivity

This commit is contained in:
ShukeBta
2026-05-29 03:35:14 +08:00
parent ab64101141
commit 2d90d9cba5
5 changed files with 102 additions and 29 deletions
+41 -12
View File
@@ -231,7 +231,7 @@ mkdir -p data cache media downloads
```bash
cat > .env <<'EOF'
# 固定版本;需要升级时改成新的 MediaStationGo-vX.Y.Z 后执行 docker compose pull && docker compose up -d
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
MEDIASTATION_HTTP_PORT=18080
# 程序数据和缓存建议放在 MediaStationGo 部署目录下,便于备份和迁移。
@@ -298,7 +298,7 @@ vim docker-compose.yml
#
# 镜像版本:
# 默认拉取 latest;如需固定版本,创建 .env 并写入:
# MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8
# MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
#
# 路径映射总览:
# /data 程序数据目录。保存 SQLite 数据库、JWT secret、系统配置等,必须持久化。
@@ -485,7 +485,7 @@ docker compose up -d
```bash
cat > .env <<'EOF'
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
MEDIASTATION_HTTP_PORT=18080
MEDIASTATION_DATA_DIR=./data
MEDIASTATION_CACHE_DIR=./cache
@@ -587,6 +587,35 @@ MEDIASTATION_DOWNLOAD_DIR=/vol1/1000/qBittorrent/downloads
容器内媒体库建议添加 `/media/电影` 和 `/media/电视剧` 两个根目录;整理后会自动进入 `/media/电影/动画电影`、`/media/电视剧/国产剧` 等分类目录。下载器保存根目录填写 `/downloads`,订阅下载会自动落到 `/downloads/动画电影`、`/downloads/国产剧` 等分类目录。
### qBittorrent 连接怎么填
如果 qBittorrent 运行在同一台 NAS/宿主机上,MediaStationGo 容器里不要优先填 `127.0.0.1`;`127.0.0.1` 代表 MediaStationGo 容器自己。推荐在「下载器管理」中填写:
```text
http://host.docker.internal:8085
```
仓库默认 `docker-compose.yml` 已配置:
```yaml
extra_hosts:
- "host.docker.internal:host-gateway"
```
如果你填写 `http://192.168.1.125:8085` 超时,但 `http://172.17.0.1:8085` 返回 403,通常表示:
- Docker 容器到局域网 IP 存在防火墙、路由或 hairpin 限制,建议改用 `host.docker.internal`。
- qBittorrent WebUI 已经能被容器访问,但登录被拒绝。请检查用户名/密码、IP 封禁、CSRF/Host Header 校验。
- qBittorrent WebUI 设置里建议确认:监听地址为 `0.0.0.0` 或所有地址;端口为 `8085`;解除/关闭连续失败后的 IP 封禁;必要时把 `host.docker.internal`、`172.17.0.1`、NAS 局域网 IP 加入允许域名/白名单,或关闭 Host Header 校验。
可在 NAS 上用下面命令快速验证 qBittorrent 登录:
```bash
docker exec -it mediastation-go sh -lc 'wget -S -O- --post-data="username=你的用户名&password=你的密码" http://host.docker.internal:8085/api/v2/auth/login'
```
返回 `Ok.` 才表示账号和 qBittorrent WebUI 配置都正常。返回 `Forbidden` / `403` 时先去 qBittorrent WebUI 解除封禁和检查安全设置。
### 下载器路径怎么填
如果 qBittorrent 也运行在 Docker 中,必须让 qBittorrent 与 MediaStationGo 看到同一份下载目录。
@@ -702,26 +731,26 @@ cd MediaStationGo
| 平台 | 包名示例 |
| --- | --- |
| Linux x86_64 | `MediaStationGo-v0.0.8-linux-amd64.tar.gz` |
| Linux ARM64 | `MediaStationGo-v0.0.8-linux-arm64.tar.gz` |
| Windows x86_64 | `MediaStationGo-v0.0.8-windows-amd64.zip` |
| macOS Intel | `MediaStationGo-v0.0.8-darwin-amd64.tar.gz` |
| macOS Apple Silicon | `MediaStationGo-v0.0.8-darwin-arm64.tar.gz` |
| Linux x86_64 | `MediaStationGo-v0.0.9-linux-amd64.tar.gz` |
| Linux ARM64 | `MediaStationGo-v0.0.9-linux-arm64.tar.gz` |
| Windows x86_64 | `MediaStationGo-v0.0.9-windows-amd64.zip` |
| macOS Intel | `MediaStationGo-v0.0.9-darwin-amd64.tar.gz` |
| macOS Apple Silicon | `MediaStationGo-v0.0.9-darwin-arm64.tar.gz` |
部署步骤:
```bash
# Linux 示例
tar -xzf MediaStationGo-v0.0.8-linux-amd64.tar.gz
cd MediaStationGo-v0.0.8-linux-amd64
tar -xzf MediaStationGo-v0.0.9-linux-amd64.tar.gz
cd MediaStationGo-v0.0.9-linux-amd64
MEDIASTATION_APP_PORT=18080 ./mediastation-go
```
Windows:
```powershell
Expand-Archive .\MediaStationGo-v0.0.8-windows-amd64.zip
cd .\MediaStationGo-v0.0.8-windows-amd64
Expand-Archive .\MediaStationGo-v0.0.9-windows-amd64.zip
cd .\MediaStationGo-v0.0.9-windows-amd64
$env:MEDIASTATION_APP_PORT = "18080"
.\mediastation-go.exe
```
+36 -11
View File
@@ -228,7 +228,7 @@ mkdir -p data cache media downloads
```bash
cat > .env <<'EOF'
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
MEDIASTATION_HTTP_PORT=18080
MEDIASTATION_DATA_DIR=./data
MEDIASTATION_CACHE_DIR=./cache
@@ -322,7 +322,7 @@ For production, pin a specific release tag instead of using `latest`. Recommende
```bash
cat > .env <<'EOF'
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
MEDIASTATION_HTTP_PORT=18080
MEDIASTATION_DATA_DIR=./data
MEDIASTATION_CACHE_DIR=./cache
@@ -414,6 +414,31 @@ MEDIASTATION_DOWNLOAD_DIR=/vol1/1000/qBittorrent/downloads
Inside MediaStationGo, add `/media/电影` and `/media/电视剧` as media library roots. Organized files will land in category folders such as `/media/电影/动画电影` and `/media/电视剧/国产剧`. Use `/downloads` as the download root; subscriptions will save to folders such as `/downloads/动画电影` and `/downloads/国产剧`.
### qBittorrent Connection
If qBittorrent runs on the same NAS/host, do not use `127.0.0.1` from MediaStationGo; inside the container it means the MediaStationGo container itself. In Download Clients, use:
```text
http://host.docker.internal:8085
```
The default `docker-compose.yml` includes:
```yaml
extra_hosts:
- "host.docker.internal:host-gateway"
```
If `http://192.168.1.125:8085` times out but `http://172.17.0.1:8085` returns 403, the container can reach qBittorrent but the WebUI rejects login. Check username/password, IP bans, CSRF/Host Header validation, and allowed subnets/domains.
Quick test from the MediaStationGo container:
```bash
docker exec -it mediastation-go sh -lc 'wget -S -O- --post-data="username=YOUR_USER&password=YOUR_PASS" http://host.docker.internal:8085/api/v2/auth/login'
```
`Ok.` means the connection is healthy. `Forbidden` / `403` means qBittorrent WebUI security settings or credentials still need adjustment.
### Download Client Paths
If qBittorrent also runs in Docker, make sure qBittorrent and MediaStationGo share the same host directory and use consistent container paths.
@@ -529,25 +554,25 @@ Each release provides multi-platform archives:
| Platform | Package example |
| --- | --- |
| Linux x86_64 | `MediaStationGo-v0.0.8-linux-amd64.tar.gz` |
| Linux ARM64 | `MediaStationGo-v0.0.8-linux-arm64.tar.gz` |
| Windows x86_64 | `MediaStationGo-v0.0.8-windows-amd64.zip` |
| macOS Intel | `MediaStationGo-v0.0.8-darwin-amd64.tar.gz` |
| macOS Apple Silicon | `MediaStationGo-v0.0.8-darwin-arm64.tar.gz` |
| Linux x86_64 | `MediaStationGo-v0.0.9-linux-amd64.tar.gz` |
| Linux ARM64 | `MediaStationGo-v0.0.9-linux-arm64.tar.gz` |
| Windows x86_64 | `MediaStationGo-v0.0.9-windows-amd64.zip` |
| macOS Intel | `MediaStationGo-v0.0.9-darwin-amd64.tar.gz` |
| macOS Apple Silicon | `MediaStationGo-v0.0.9-darwin-arm64.tar.gz` |
Linux example:
```bash
tar -xzf MediaStationGo-v0.0.8-linux-amd64.tar.gz
cd MediaStationGo-v0.0.8-linux-amd64
tar -xzf MediaStationGo-v0.0.9-linux-amd64.tar.gz
cd MediaStationGo-v0.0.9-linux-amd64
MEDIASTATION_APP_PORT=18080 ./mediastation-go
```
Windows example:
```powershell
Expand-Archive .\MediaStationGo-v0.0.8-windows-amd64.zip
cd .\MediaStationGo-v0.0.8-windows-amd64
Expand-Archive .\MediaStationGo-v0.0.9-windows-amd64.zip
cd .\MediaStationGo-v0.0.9-windows-amd64
$env:MEDIASTATION_APP_PORT = "18080"
.\mediastation-go.exe
```
+7 -1
View File
@@ -12,7 +12,7 @@
#
# 镜像版本:
# 默认拉取 latest;如需固定版本,创建 .env 并写入:
# MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8
# MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
#
# 路径映射总览:
# /data 程序数据目录。保存 SQLite 数据库、JWT secret、系统配置等,必须持久化。
@@ -63,6 +63,12 @@ services:
# 宿主机端口:容器端口。默认访问 http://<服务器IP>:18080
- "${MEDIASTATION_HTTP_PORT:-18080}:8080"
extra_hosts:
# Linux / NAS Docker 中访问宿主机服务的固定别名。
# qBittorrent 如果运行在 NAS 宿主机上,下载器地址建议填:
# http://host.docker.internal:8085
- "host.docker.internal:host-gateway"
volumes:
# 程序持久化数据:数据库、JWT secret、运行时配置。
- ${MEDIASTATION_DATA_DIR:-./data}:/data
+10 -3
View File
@@ -107,7 +107,10 @@ func (q *QBitClient) Login(ctx context.Context) error {
return err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Referer", q.cfg.BaseURL)
baseURL := strings.TrimRight(q.cfg.BaseURL, "/")
req.Header.Set("Referer", baseURL)
req.Header.Set("Origin", baseURL)
req.Header.Set("User-Agent", "MediaStationGo/0.1")
resp, err := q.client.Do(req)
if err != nil {
@@ -115,8 +118,12 @@ func (q *QBitClient) Login(ctx context.Context) error {
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 || strings.TrimSpace(string(body)) != "Ok." {
return fmt.Errorf("qbittorrent login failed: %s", strings.TrimSpace(string(body)))
text := strings.TrimSpace(string(body))
if resp.StatusCode == http.StatusForbidden {
return errors.New("qbittorrent login forbidden: check username/password, WebUI IP ban, CSRF/Host header validation, and allowed subnets")
}
if resp.StatusCode >= 400 || text != "Ok." {
return fmt.Errorf("qbittorrent login failed: status=%d body=%s", resp.StatusCode, text)
}
return nil
}
+8 -2
View File
@@ -284,6 +284,8 @@ func (a *QBitAdapter) loginLocked(ctx context.Context) error {
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Referer", baseURL)
req.Header.Set("Origin", baseURL)
req.Header.Set("User-Agent", "MediaStationGo/0.1")
resp, err := a.client.Do(req)
if err != nil {
@@ -291,8 +293,12 @@ func (a *QBitAdapter) loginLocked(ctx context.Context) error {
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 || strings.TrimSpace(string(body)) != "Ok." {
return fmt.Errorf("qbittorrent login failed: %s", strings.TrimSpace(string(body)))
text := strings.TrimSpace(string(body))
if resp.StatusCode == http.StatusForbidden {
return fmt.Errorf("qbittorrent login forbidden: check username/password, WebUI IP ban, CSRF/Host header validation, and allowed subnets")
}
if resp.StatusCode >= 400 || text != "Ok." {
return fmt.Errorf("qbittorrent login failed: status=%d body=%s", resp.StatusCode, text)
}
a.LoggedIn = true
return nil