Testcontainer ContainerLaunchException:容器启动失败求助
问题:Testcontainer启动hello-world容器时抛出ContainerLaunchException
测试代码
import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.utility.DockerImageName; @Slf4j public class HelloTest { private final static DockerImageName helloWorld = DockerImageName.parse("hello-world:latest"); @Container private static GenericContainer container = new GenericContainer(helloWorld); @Test void test() { log.warn("Hello ...."); container.start(); } }
依赖配置
testImplementation "org.springframework.boot:spring-boot-starter-test:2.6.6" testImplementation "org.testcontainers:testcontainers:1.17.6"
错误栈信息
Container startup failed org.testcontainers.containers.ContainerLaunchException: Container startup failed at app//org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:349) at app//org.testcontainers.containers.GenericContainer.start(GenericContainer.java:322) at app//de.sick.agency.ordermanagementservice.application.HelloTest.test(HelloTest.java:23) ...(省略中间冗余栈信息) Caused by: java.lang.RuntimeException: Not ready yet at org.rnorth.ducttape.unreliables.Unreliables.lambda$retryUntilTrue$1(Unreliables.java:102) at org.rnorth.ducttape.unreliables.Unreliables.lambda$retryUntilSuccess$0(Unreliables.java:43) ...
排查思路与解决方案
核心原因
hello-world镜像的设计是启动后立即输出信息并退出,而Testcontainers默认的启动检查策略(IsRunningStartupCheckStrategy)会持续等待容器处于运行状态,超时后判定启动失败。同时代码中手动调用container.start(),但@Container注解已经会自动触发容器启动,导致重复启动逻辑冲突。
解决步骤
- 移除手动启动调用:删除
test()方法中的container.start(),@Container配合@Testcontainers注解会自动管理容器的启动与销毁。 - 配置一次性容器启动检查策略:为容器指定
OneShotStartupCheckStrategy,该策略只验证容器是否成功启动过,不要求容器持续运行。 - 添加Testcontainers JUnit 5支持注解:在测试类上添加
@Testcontainers,启用Testcontainers对JUnit 5的集成。
修改后的测试代码
import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; @Slf4j @Testcontainers public class HelloTest { private final static DockerImageName helloWorld = DockerImageName.parse("hello-world:latest"); @Container private static GenericContainer container = new GenericContainer(helloWorld) .withStartupCheckStrategy(new OneShotStartupCheckStrategy()); @Test void test() { log.warn("Hello ...."); // 可通过日志验证容器执行结果 String containerLogs = container.getLogs(); log.info("容器输出: {}", containerLogs); } }
额外检查项
- 验证本地Docker环境:执行
docker run hello-world,确认镜像能正常运行并输出内容。 - 补充JUnit 5依赖(若需要):如果Spring Boot Starter Test未包含相关依赖,添加:
testImplementation "org.testcontainers:junit-jupiter:1.17.6"
内容的提问来源于stack exchange,提问作者emoleumassi
相关产品推荐
相关产品推荐

