Testcontainers;在Docker中运行@Testcontainers测试[在Docker容器内运行Docker]

8
如何在 Docker 容器内运行基于 @Testcontainers 的测试用例?
我有一个简单的 Spring Boot 应用程序,具有与容器交互的集成测试(组件级别),使用 Testcontainers。从容器外部(本地机器)运行测试用例时一切正常。
我们正在容器中运行所有内容,并且构建正在运行 docker jenkins 图像上。Docker 文件创建 jar,然后创建镜像。@Testcontainers 无法找到已安装的 Docker。 以下是我的 Docker 文件。
FROM maven:3.6-jdk-11-openj9
VOLUME ["/var/run/docker.sock"]
RUN apt-get update
RUN apt-get -y install docker.io
COPY . /usr/src/app
WORKDIR /usr/src/app
RUN mvn -Dmaven.repo.local=/root/m2 --batch-mode -f pom.xml clean package
EXPOSE 8080
CMD ["/bin/bash"]

在进行构建时,我遇到了以下错误: org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy - 使用环境变量、系统属性和默认值配置失败。由于 org.rnorth.ducttape.TimeoutException: Timeout waiting for result with exception,因此确定 dockerHost=unix:///var/run/docker.sock。 最好的解决方法是什么?我想在 mvn 构建阶段使用 Dockerfile 运行组件级别的集成测试。
以下参考资料并没有帮助我。 https://www.testcontainers.org/supported_docker_environment/continuous_integration/dind_patterns/

这应该怎么工作?这意味着您需要在Docker容器内部安装Docker。您不应该在此场景中使用TestContainers。 - Simon Martinelli
对于我的集成测试,我依赖于一些容器化应用程序(例如数据库和其他一些),'Testcontainers本身可以从容器内部使用' - > 这是来自他们的网站。 - Niraj Sonawane
1个回答

3
这不是完整的答案,但您应该启用容器内部对Docker守护程序的访问。在容器内安装Docker并运行其守护程序很复杂,因此不建议这样做。 Docker可以通过Unix套接字或TCP进行控制(我假设主机系统是Linux)。 Test containers如何查找Docker: 默认情况下,它尝试连接Unix套接字/var/run/docker.sock。您可以通过设置环境变量(DOCKER_HOST)来指定其他套接字路径或TCP地址。 Docker如何公开其控制API: 默认情况下,通过Unix套接字/var/run/docker.sock(在主机上)公开。您可以通过向docker start命令添加以下参数来在其他位置公开docker API: -H fd:// -H tcp://127.0.0.1:2376。请注意,您可以指定多个选项。 -H fd:// 是默认值,tcp://127.0.0.1:2376 告诉Docker侦听本地主机的端口2376。 如何在容器内部使用Docker(" Docker in Docker"):如果启用了网络访问,则无需进行其他配置,只需像上面提到的那样将Testcontaners指向它即可。如果要使用默认Unix套接字,则可以通过volume选项将其映射(挂载)到容器中。
docker run --volume /var/run/docker.sock:/var/run/docker.sock your-image-id-here

剩下的问题是,容器内挂载的docker.sock文件也将由root:docker所有(与主机系统相同的uid:gid),因此Testcontainers只能在您的容器用户可以连接到该套接字的情况下工作。也就是说,运行进程的用户为root或恰好具有与主机上docker组的组ID相同的组ID。 我还不知道如何解决这个问题,所以首先您可以将测试作为root在容器内运行,或者硬编码容器的用户组ID来匹配主机上的docker组ID。

我尝试过运行命令 docker run --volume /var/run/docker.sock:/var/run/docker.sock your-image-id-here,但没有帮助...最终只能删除 Docker 内部的 Docker。感谢详细的答案。 - Niraj Sonawane
3
不需要(也不应该)在容器内安装“docker”包。Testcontainers具有自己的(基于JVM的)Docker API客户端实现。为了使Testcontainers在容器内正常工作,唯一需要的是访问Docker API(可以通过套接字或TCP进行访问)。 - Petr Gladkikh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接