Testcontainers-Java在TeamCity/Docker中超时,MacOS本地运行正常
解决TestContainers Schema Registry在Linux TeamCity代理上的启动检测超时问题
问题核心
本地MacOS(含Docker环境)下,TestContainers结合Schema Registry的Kafka Streams集成测试运行正常,但在Linux的TeamCity代理上启动Schema Registry容器时,会卡在SCHEMA_REGISTRY.withKafka(KAFKA).start()步骤,日志提示超时等待http://172.17.0.1:xxxx/subjects返回200,但容器本身实际已正常运行,推测是跨容器/主机的网络连通性或检测逻辑问题。
具体修复方案
1. 替换Schema Registry的启动检测逻辑,改用容器内部自检
原来的Wait.forHttp("/subjects")是从主机访问容器映射端口,在Linux代理上可能因防火墙、端口映射规则等配置导致访问失败。直接改成在容器内部检测服务状态:
public SchemaRegistryContainer(String version) { super(SCHEMA_REGISTRY_IMAGE + ":" + version); // 先等待服务启动日志,再在容器内通过curl检测接口可用性 waitingFor(Wait.forLogMessage(".*Server started.*", 1) .andThen(Wait.forExecInContainer("curl", "-f", "http://localhost:8081/subjects") .withStartupTimeout(Duration.ofMinutes(3)))); withExposedPorts(SCHEMA_REGISTRY_PORT); // 给镜像安装curl(部分cp-schema-registry镜像默认未预装) withCommand("sh", "-c", "apt-get update && apt-get install -y curl && /etc/confluent/docker/run"); }
2. 调整Schema Registry的环境变量配置
将SCHEMA_REGISTRY_HOST_NAME设为0.0.0.0,避免绑定到特定主机名导致访问限制,同时添加网络别名确保Kafka容器能正常访问:
public SchemaRegistryContainer withKafka(Network network, String bootstrapServers) { withNetwork(network); withEnv("SCHEMA_REGISTRY_HOST_NAME", "0.0.0.0"); withEnv("SCHEMA_REGISTRY_LISTENERS", "http://0.0.0.0:8081"); withEnv("SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS", "PLAINTEXT://" + bootstrapServers); withNetworkAliases("schema-registry"); // 为容器添加网络别名,方便Kafka容器识别 return self(); }
3. 修正TeamCity代理的TestContainers配置
- Linux环境下不要设置
TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal,这会导致Ryuk无法找到Docker daemon; - 如果TeamCity代理本身运行在Docker容器中,需确保代理容器挂载了
/var/run/docker.sock,并且启用了特权模式(--privileged),否则TestContainers创建的子容器无法正常通信; - 检查TeamCity代理的系统用户是否拥有Docker操作权限,避免因权限不足导致网络配置失败。
4. 按需禁用Ryuk(仅遇Ryuk相关错误时)
如果仍出现Ryuk无法连接的问题,可在TeamCity代理的环境变量中添加TESTCONTAINERS_RYUK_DISABLED=true(注意:禁用后需确保测试完成后容器能被自动清理,或手动处理残留容器)。
内容的提问来源于stack exchange,提问作者Matt Allwood
相关产品推荐
相关产品推荐

