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 ```bash
cat > .env <<'EOF' cat > .env <<'EOF'
# 固定版本;需要升级时改成新的 MediaStationGo-vX.Y.Z 后执行 docker compose pull && docker compose up -d # 固定版本;需要升级时改成新的 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 MEDIASTATION_HTTP_PORT=18080
# 程序数据和缓存建议放在 MediaStationGo 部署目录下,便于备份和迁移。 # 程序数据和缓存建议放在 MediaStationGo 部署目录下,便于备份和迁移。
@@ -298,7 +298,7 @@ vim docker-compose.yml
# #
# 镜像版本: # 镜像版本:
# 默认拉取 latest;如需固定版本,创建 .env 并写入: # 默认拉取 latest;如需固定版本,创建 .env 并写入:
# MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8 # MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
# #
# 路径映射总览: # 路径映射总览:
# /data 程序数据目录。保存 SQLite 数据库、JWT secret、系统配置等,必须持久化。 # /data 程序数据目录。保存 SQLite 数据库、JWT secret、系统配置等,必须持久化。
@@ -485,7 +485,7 @@ docker compose up -d
```bash ```bash
cat > .env <<'EOF' cat > .env <<'EOF'
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8 MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
MEDIASTATION_HTTP_PORT=18080 MEDIASTATION_HTTP_PORT=18080
MEDIASTATION_DATA_DIR=./data MEDIASTATION_DATA_DIR=./data
MEDIASTATION_CACHE_DIR=./cache MEDIASTATION_CACHE_DIR=./cache
@@ -587,6 +587,35 @@ MEDIASTATION_DOWNLOAD_DIR=/vol1/1000/qBittorrent/downloads
容器内媒体库建议添加 `/media/电影` 和 `/media/电视剧` 两个根目录;整理后会自动进入 `/media/电影/动画电影`、`/media/电视剧/国产剧` 等分类目录。下载器保存根目录填写 `/downloads`,订阅下载会自动落到 `/downloads/动画电影`、`/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 看到同一份下载目录。 如果 qBittorrent 也运行在 Docker 中,必须让 qBittorrent 与 MediaStationGo 看到同一份下载目录。
@@ -702,26 +731,26 @@ cd MediaStationGo
| 平台 | 包名示例 | | 平台 | 包名示例 |
| --- | --- | | --- | --- |
| Linux x86_64 | `MediaStationGo-v0.0.8-linux-amd64.tar.gz` | | Linux x86_64 | `MediaStationGo-v0.0.9-linux-amd64.tar.gz` |
| Linux ARM64 | `MediaStationGo-v0.0.8-linux-arm64.tar.gz` | | Linux ARM64 | `MediaStationGo-v0.0.9-linux-arm64.tar.gz` |
| Windows x86_64 | `MediaStationGo-v0.0.8-windows-amd64.zip` | | Windows x86_64 | `MediaStationGo-v0.0.9-windows-amd64.zip` |
| macOS Intel | `MediaStationGo-v0.0.8-darwin-amd64.tar.gz` | | macOS Intel | `MediaStationGo-v0.0.9-darwin-amd64.tar.gz` |
| macOS Apple Silicon | `MediaStationGo-v0.0.8-darwin-arm64.tar.gz` | | macOS Apple Silicon | `MediaStationGo-v0.0.9-darwin-arm64.tar.gz` |
部署步骤: 部署步骤:
```bash ```bash
# Linux 示例 # Linux 示例
tar -xzf MediaStationGo-v0.0.8-linux-amd64.tar.gz tar -xzf MediaStationGo-v0.0.9-linux-amd64.tar.gz
cd MediaStationGo-v0.0.8-linux-amd64 cd MediaStationGo-v0.0.9-linux-amd64
MEDIASTATION_APP_PORT=18080 ./mediastation-go MEDIASTATION_APP_PORT=18080 ./mediastation-go
``` ```
Windows: Windows:
```powershell ```powershell
Expand-Archive .\MediaStationGo-v0.0.8-windows-amd64.zip Expand-Archive .\MediaStationGo-v0.0.9-windows-amd64.zip
cd .\MediaStationGo-v0.0.8-windows-amd64 cd .\MediaStationGo-v0.0.9-windows-amd64
$env:MEDIASTATION_APP_PORT = "18080" $env:MEDIASTATION_APP_PORT = "18080"
.\mediastation-go.exe .\mediastation-go.exe
``` ```
+36 -11
View File
@@ -228,7 +228,7 @@ mkdir -p data cache media downloads
```bash ```bash
cat > .env <<'EOF' cat > .env <<'EOF'
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8 MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
MEDIASTATION_HTTP_PORT=18080 MEDIASTATION_HTTP_PORT=18080
MEDIASTATION_DATA_DIR=./data MEDIASTATION_DATA_DIR=./data
MEDIASTATION_CACHE_DIR=./cache MEDIASTATION_CACHE_DIR=./cache
@@ -322,7 +322,7 @@ For production, pin a specific release tag instead of using `latest`. Recommende
```bash ```bash
cat > .env <<'EOF' cat > .env <<'EOF'
MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8 MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
MEDIASTATION_HTTP_PORT=18080 MEDIASTATION_HTTP_PORT=18080
MEDIASTATION_DATA_DIR=./data MEDIASTATION_DATA_DIR=./data
MEDIASTATION_CACHE_DIR=./cache 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/国产剧`. 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 ### Download Client Paths
If qBittorrent also runs in Docker, make sure qBittorrent and MediaStationGo share the same host directory and use consistent container 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 | | Platform | Package example |
| --- | --- | | --- | --- |
| Linux x86_64 | `MediaStationGo-v0.0.8-linux-amd64.tar.gz` | | Linux x86_64 | `MediaStationGo-v0.0.9-linux-amd64.tar.gz` |
| Linux ARM64 | `MediaStationGo-v0.0.8-linux-arm64.tar.gz` | | Linux ARM64 | `MediaStationGo-v0.0.9-linux-arm64.tar.gz` |
| Windows x86_64 | `MediaStationGo-v0.0.8-windows-amd64.zip` | | Windows x86_64 | `MediaStationGo-v0.0.9-windows-amd64.zip` |
| macOS Intel | `MediaStationGo-v0.0.8-darwin-amd64.tar.gz` | | macOS Intel | `MediaStationGo-v0.0.9-darwin-amd64.tar.gz` |
| macOS Apple Silicon | `MediaStationGo-v0.0.8-darwin-arm64.tar.gz` | | macOS Apple Silicon | `MediaStationGo-v0.0.9-darwin-arm64.tar.gz` |
Linux example: Linux example:
```bash ```bash
tar -xzf MediaStationGo-v0.0.8-linux-amd64.tar.gz tar -xzf MediaStationGo-v0.0.9-linux-amd64.tar.gz
cd MediaStationGo-v0.0.8-linux-amd64 cd MediaStationGo-v0.0.9-linux-amd64
MEDIASTATION_APP_PORT=18080 ./mediastation-go MEDIASTATION_APP_PORT=18080 ./mediastation-go
``` ```
Windows example: Windows example:
```powershell ```powershell
Expand-Archive .\MediaStationGo-v0.0.8-windows-amd64.zip Expand-Archive .\MediaStationGo-v0.0.9-windows-amd64.zip
cd .\MediaStationGo-v0.0.8-windows-amd64 cd .\MediaStationGo-v0.0.9-windows-amd64
$env:MEDIASTATION_APP_PORT = "18080" $env:MEDIASTATION_APP_PORT = "18080"
.\mediastation-go.exe .\mediastation-go.exe
``` ```
+7 -1
View File
@@ -12,7 +12,7 @@
# #
# 镜像版本: # 镜像版本:
# 默认拉取 latest;如需固定版本,创建 .env 并写入: # 默认拉取 latest;如需固定版本,创建 .env 并写入:
# MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.8 # MEDIASTATION_IMAGE_TAG=MediaStationGo-v0.0.9
# #
# 路径映射总览: # 路径映射总览:
# /data 程序数据目录。保存 SQLite 数据库、JWT secret、系统配置等,必须持久化。 # /data 程序数据目录。保存 SQLite 数据库、JWT secret、系统配置等,必须持久化。
@@ -63,6 +63,12 @@ services:
# 宿主机端口:容器端口。默认访问 http://<服务器IP>:18080 # 宿主机端口:容器端口。默认访问 http://<服务器IP>:18080
- "${MEDIASTATION_HTTP_PORT:-18080}:8080" - "${MEDIASTATION_HTTP_PORT:-18080}:8080"
extra_hosts:
# Linux / NAS Docker 中访问宿主机服务的固定别名。
# qBittorrent 如果运行在 NAS 宿主机上,下载器地址建议填:
# http://host.docker.internal:8085
- "host.docker.internal:host-gateway"
volumes: volumes:
# 程序持久化数据:数据库、JWT secret、运行时配置。 # 程序持久化数据:数据库、JWT secret、运行时配置。
- ${MEDIASTATION_DATA_DIR:-./data}:/data - ${MEDIASTATION_DATA_DIR:-./data}:/data
+10 -3
View File
@@ -107,7 +107,10 @@ func (q *QBitClient) Login(ctx context.Context) error {
return err return err
} }
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 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) resp, err := q.client.Do(req)
if err != nil { if err != nil {
@@ -115,8 +118,12 @@ func (q *QBitClient) Login(ctx context.Context) error {
} }
defer resp.Body.Close() defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body) body, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 || strings.TrimSpace(string(body)) != "Ok." { text := strings.TrimSpace(string(body))
return fmt.Errorf("qbittorrent login failed: %s", 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 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("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Referer", baseURL) req.Header.Set("Referer", baseURL)
req.Header.Set("Origin", baseURL)
req.Header.Set("User-Agent", "MediaStationGo/0.1")
resp, err := a.client.Do(req) resp, err := a.client.Do(req)
if err != nil { if err != nil {
@@ -291,8 +293,12 @@ func (a *QBitAdapter) loginLocked(ctx context.Context) error {
} }
defer resp.Body.Close() defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body) body, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 || strings.TrimSpace(string(body)) != "Ok." { text := strings.TrimSpace(string(body))
return fmt.Errorf("qbittorrent login failed: %s", 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 a.LoggedIn = true
return nil return nil