sub2api 容器不继承宿主机代理的解决方法
docker exec sub2api curl -4 -sS -A 'Mozilla/5.0' --connect-timeout 10 --max-time 20 https://ifconfig.co/country-iso
或者
docker exec -it sub2api /bin/sh
curl -4 -s -A 'Mozilla/5.0' --max-time 15 https://ifconfig.co/country-iso
在sub2api容器里执行这个命令,返回CN, 而宿主机通过shellcrash配置了代理,返回US,由于部署sub2api的时候没有继承宿主机代理,导致添加账号auth一直失败。
解决方法:
cd /home/sub2api-deploy
vim docker-compose.yml
在sub2api 容器中添加环境变量:
services:
sub2api:
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
- http_proxy=http://host.docker.internal:7890
- https_proxy=http://host.docker.internal:7890
- HTTP_PROXY=http://host.docker.internal:7890
- HTTPS_PROXY=http://host.docker.internal:7890
- no_proxy=localhost,127.0.0.1,::1,postgres,redis,sub2api-postgres,sub2api-redis
- NO_PROXY=localhost,127.0.0.1,::1,postgres,redis,sub2api-postgres,sub2api-redis
7890表示代理的默认端口
确认默认端口:
head -n 20 /tmp/ShellCrash/config.yaml
mixed-port: 7890
redir-port: 7892
tproxy-port: 7893
authentication: [""]
allow-lan: true
mode: Rule
log-level: info
ipv6: true
external-controller: :9999
external-ui: ui
external-ui-url: "https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip"
secret:
tun: {enable: false}
experimental: {ignore-resolve-fail: true, interface-name: en0}
再次重新创建容器,用第一步的命令验证,返回US
在后台管理界面中进行测试

显示错误:
request failed: post "https://chatgpt.com/backend-api/codex/responses": dial tcp 66.220.148.145:443: i/o timeout
容器日志:
2026-11-01T12:17:17.882+0800 INFO middleware/logger.go:82 http request completed {"service": "sub2api", "env": "production", "component": "http", "request_id": "608a6812-e690-4e21-9f7e-ee5a0e17f874", "client_request_id": "", "path": "/api/v1/admin/accounts/1/test", "method": "POST", "component": "http.access", "status_code": 200, "latency_ms": 10008, "client_ip": "172.238.36.221", "protocol": "HTTP/1.1", "method": "POST", "path": "/api/v1/admin/accounts/1/test", "completed_at": "2026-11-01T12:17:17.882+0800"}
2026-11-01T12:17:18.374+0800 INFO middleware/logger.go:82 http request completed {"service": "sub2api", "env": "production", "component": "http", "request_id": "d029a6db-bd7d-4614-9196-d32b50759de7", "client_request_id": "", "path": "/api/v1/auth/me", "method": "GET", "component": "http.access", "status_code": 200, "latency_ms": 5, "client_ip": "172.238.36.221", "protocol": "HTTP/1.1", "method": "GET", "path": "/api/v1/auth/me", "completed_at": "2026-11-01T12:17:18.374+0800"}
2026-11-01T12:18:18.324+0800 INFO middleware/logger.go:82 http request completed {"service": "sub2api", "env": "production", "component": "http", "request_id": "764b0f82-ac24-4d0e-84d2-a57435af599d", "client_request_id": "", "path": "/api/v1/auth/me", "method": "GET", "component": "http.access", "status_code": 200, "latency_ms": 4, "client_ip": "172.238.36.221", "protocol": "HTTP/1.1", "method": "GET", "path": "/api/v1/auth/me", "completed_at": "2026-11-01T12:18:18.324+0800"}
2026-11-01T12:18:29.927+0800 INFO stdlog service/subscription_expiry_service.go:128 [SubscriptionExpiry] SMTP is not configured; skipping expiry reminders {"service": "sub2api", "env": "production", "legacy_stdlog": true}
2026-11-01T12:19:17.953+0800 INFO middleware/logger.go:82 http request completed {"service": "sub2api", "env": "production", "component": "http", "request_id": "635e801c-5365-4f34-b84f-79a307861ca1", "client_request_id": "", "path": "/api/v1/auth/me", "method": "GET", "component": "http.access", "status_code": 200, "latency_ms": 4, "client_ip": "172.238.36.221", "protocol": "HTTP/1.1", "method": "GET", "path": "/api/v1/auth/me", "completed_at": "2026-11-01T12:19:17.953+0800"}
2026-11-01T12:19:41.619+0800 ERROR stdlog service/account_test_service.go:939 Account test error: Request failed: Post "https://chatgpt.com/backend-api/codex/responses": dial tcp 31.13.67.33:443: i/o timeout {"service": "sub2api", "env": "production", "legacy_stdlog": true}
github.com/Wei-Shaw/sub2api/internal/service.(*AccountTestService).testOpenAIAccountConnection
/home/runner/work/sub2api/sub2api/backend/internal/service/account_test_service.go:939
github.com/Wei-Shaw/sub2api/internal/service.(*AccountTestService).TestAccountConnection
/home/runner/work/sub2api/sub2api/backend/internal/service/account_test_service.go:400
github.com/Wei-Shaw/sub2api/internal/handler/admin.(*AccountHandler).Test
/home/runner/work/sub2api/sub2api/backend/internal/handler/admin/account_handler.go:1307
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.AdminComplianceGuard.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/admin_compliance.go:31
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.NewAuditLogMiddleware.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/audit_log.go:208
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.(*PanelRateLimiter).userScoped.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/panel_rate_limit.go:83
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.adminAuth.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/admin_auth.go:72
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/web.(*FrontendServer).Middleware.func1
/home/runner/work/sub2api/sub2api/backend/internal/web/embed_on.go:93
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.ServerTiming.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/server_timing.go:32
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.SecurityHeaders.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/security_headers.go:150
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.CORS.func2
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/cors.go:99
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.Logger.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/logger.go:23
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.SessionBindingContext.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/session_binding.go:29
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/Wei-Shaw/sub2api/internal/server/middleware.RequestLogger.func1
/home/runner/work/sub2api/sub2api/backend/internal/server/middleware/request_logger.go:44
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/recovery.go:102
github.com/gin-gonic/gin.(*Context).Next
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:620
github.com/gin-gonic/gin.(*Engine).ServeHTTP
/home/runner/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:576
net/http.MaxBytesHandler.func1
/opt/hostedtoolcache/go/1.27.0/x64/src/net/http/server.go:4290
net/http.HandlerFunc.ServeHTTP
/opt/hostedtoolcache/go/1.27.0/x64/src/net/http/server.go:2338
net/http.serverHandler.ServeHTTP
/opt/hostedtoolcache/go/1.27.0/x64/src/net/http/server.go:3413
net/http.(*conn).serve
/opt/hostedtoolcache/go/1.27.0/x64/src/net/http/server.go:2137
2026-11-01T12:19:41.620+0800 INFO middleware/logger.go:82 http request completed {"service": "sub2api", "env": "production", "component": "http", "request_id": "12d90874-ae55-43e2-8b17-99e5a3241ae3", "client_request_id": "", "path": "/api/v1/admin/accounts/1/test", "method": "POST", "component": "http.access", "status_code": 200, "latency_ms": 10150, "client_ip": "172.238.36.221", "protocol": "HTTP/1.1", "method": "POST", "path": "/api/v1/admin/accounts/1/test", "completed_at": "2026-11-01T12:19:41.620+0800"}
表示账号请求实际上没有走http_proxy
ai给出的解决方案:
这次日志已经明确定位:Sub2API 的账号测试没有使用代理,而是直接连接:
```text
Post "https://chatgpt.com/backend-api/codex/responses":
dial tcp 31.13.67.33:443: i/o timeout
```
因此:
- 容器里的 `curl` 使用代理是正常的;
- 但 Sub2API 的账号测试请求绕过了容器的 `HTTP_PROXY`;
- `/api/v1/admin/accounts/1/test` 返回 `200` 只是测试接口正常返回,不能代表账号测试成功;
- 实际账号连接在约 10 秒后超时。
优先在 Sub2API 管理后台打开“账号 1”的编辑页面,在“代理/Proxy”字段填写:
```text
http://host.docker.internal:7890
```
如果字段要求拆分填写,则填写:
```text
host: host.docker.internal
port: 7890
protocol: HTTP
```
保存后重新点击“测试账号”。
可以先验证这个代理能访问目标域名:
```bash
docker exec sub2api sh -c \
"curl -4 -sS -o /dev/null -w 'HTTP=%{http_code} IP=%{remote_ip}\n' \
--proxy http://host.docker.internal:7890 \
--connect-timeout 10 --max-time 20 \
https://chatgpt.com/backend-api/codex/responses"
```
返回 `401`、`403` 或其他 HTTP 状态都说明已经通过代理到达目标;如果仍然是 `i/o timeout`,再检查代理软件是否允许来自 Docker 网桥的连接。
`extra_hosts` 仍需保留:
```yaml
extra_hosts:
- "host.docker.internal:host-gateway"
```
当前关键修复是给“账号 1”配置账号级代理。仅在容器环境中设置 `HTTP_PROXY`,不一定会被 Sub2API 的账号请求代码采用。
在后台管理界面, IP管理 快捷添加代理: http://host.docker.internal:7890
账号管理中添加代理,再次测试


那么问题来了,这个问题出现在服务器上。 当我在本机(mac)同样使用docker部署,在外部开启一个vpn,为什么不用配置代理也能正常使用? 且在内网中,可以给其他人使用。

浙公网安备 33010602011771号