使用Testcontainers for Go时Ory Hydra容器间连接被拒绝问题排查
容器内连接Ory Hydra出现Connection Refused问题排查
问题现象
在同一Docker网络test-network下,业务容器连接Hydra容器时始终报错:
Post "http://test-hydra:4445/oauth2/introspect": dial tcp 172.19.0.3:4445: connect: connection refused
尝试HTTPS连接同样失败,Hydra容器无日志输出,但外部通过映射端口可正常访问,且docker network inspect确认两容器在同一网络、IP正确。
相关代码
Hydra容器启动代码
func (c ServiceConfig) StartHydraContainer(ctx context.Context) (url string) { container, err := tc.GenericContainer(ctx, tc.GenericContainerRequest{ ContainerRequest: tc.ContainerRequest{ Image: "oryd/hydra:v1.10.6", Networks: []string{"test-network"}, NetworkAliases: map[string][]string{ networkName: {"test-hydra"}, }, Env: c.env(), ExposedPorts: []string{"4444/tcp", "4445/tcp"}, Cmd: []string{"serve", "all"}, WaitingFor: wait.ForLog("Thank you for using ORY Hydra v1.10.6!"), }, Started: true, }) if err != nil { log.Fatal("Hydra start error:", err) } return fmt.Sprintf("https://test-hydra:4445") }
业务服务容器代码
func (t ServiceConfig) StartContainer(ctx context.Context) string { dir, _ := os.Getwd() _, err := tc.GenericContainer(ctx, tc.GenericContainerRequest{ ContainerRequest: tc.ContainerRequest{ FromDockerfile: tc.FromDockerfile{Context: filepath.Join(dir, "Service")}, Networks: []string{"test-network"}, NetworkAliases: map[string][]string{networkName: {"test-service"}}, Env: t.env(), ExposedPorts: []string{"9000/tcp"}, WaitingFor: wait.ForExposedPort(), }, Started: true, }) if err != nil { log.Fatal(err) } return fmt.Sprintf("test-service:9000") } func (t ServiceConfig) env() map[string]string { return map[string]string{"OIDC_PROVIDER_ADDRESS": "https://test-hydra:4445"} }
排查方向与解决方案
1. Hydra服务监听地址限制(核心原因)
Ory Hydra默认将服务绑定到127.0.0.1,该地址仅容器自身可见,同一网络的其他容器无法通过容器IP或别名访问。必须指定监听所有接口:
- 给Hydra添加环境变量
HYDRA_ADMIN_LISTEN=0.0.0.0:4445(管理端口)和HYDRA_PUBLIC_LISTEN=0.0.0.0:4444(公共端口)。
修改Hydra容器的env()方法补充变量:
func (c ServiceConfig) env() map[string]string { return map[string]string{ // 保留原有环境变量 "HYDRA_ADMIN_LISTEN": "0.0.0.0:4445", "HYDRA_PUBLIC_LISTEN": "0.0.0.0:4444", } }
2. 启动就绪判断逻辑不准确
当前仅通过日志Thank you for using ORY Hydra v1.10.6!判断启动完成,无法保证服务已完成初始化并监听端口。建议改为同时监听端口就绪:
WaitingFor: wait.ForAll( wait.ForLog("Thank you for using ORY Hydra v1.10.6!"), wait.ForListeningPort("4445/tcp"), ),
3. 业务容器启动时机问题
业务容器仅等待自身端口开放,可能早于Hydra服务就绪。可在业务服务中添加连接重试逻辑,或者调整启动顺序,确保Hydra完全就绪后再启动业务容器。
4. HTTPS证书校验问题(针对HTTPS连接场景)
如果使用HTTPS连接,业务容器可能不信任Hydra的自签证书(默认生成),可在测试环境临时禁用证书校验:
func (t ServiceConfig) env() map[string]string { return map[string]string{ "OIDC_PROVIDER_ADDRESS": "https://test-hydra:4445", "OIDC_SKIP_VERIFY": "true", // 仅测试环境使用 } }
总结
最可能的问题是Hydra默认绑定127.0.0.1导致容器间无法访问,添加HYDRA_ADMIN_LISTEN=0.0.0.0:4445即可解决核心问题,同时调整启动等待条件确保服务真正就绪。
内容的提问来源于stack exchange,提问作者Dmitry Malys
相关产品推荐
相关产品推荐

