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

时间:2020-01-03 13:58:18

标签: testcontainers

如何在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 - ping failed with configuration Environment variables, system properties and defaults. Resolved dockerHost=unix:///var/run/docker.sock due to org.rnorth.ducttape.TimeoutException: Timeout waiting for result with exception

处理此案的最佳方法是什么?我想在mvn构建阶段使用docker文件运行组件级集成测试。

以下参考资料对我没有帮助。 https://www.testcontainers.org/supported_docker_environment/continuous_integration/dind_patterns/

1 个答案:

答案 0 :(得分:2)

这不是完整的答案,但是您应该从容器内部启用对docker守护程序的访问。在容器内安装Docker并运行其守护进程非常复杂,因此不建议这样做。可以通过Unix套接字或TCP来控制Docker(我假设主机系统是Linux)。

How Test containers look for Docker: 默认情况下,它尝试连接到Unix套接字/var/run/docker.sock。您可以通过设置环境变量(DOCKER_HOST)指定其他套接字路径或TCP地址。

How docker exposes it's control API: 默认情况下是通过Unix套接字/var/run/docker.sock(在您的主机上)。您可以通过在docker start命令中添加以下参数来公开其他地方的docker API(启动docker的命令位置取决于系统):-H fd:// -H tcp://127.0.0.1:2376。请注意,您可以指定多个选项。 -H fd://-是默认值,tcp://127.0.0.1:2376-告诉Docker在本地主机端口2376上侦听。

How to make Docker available inside your container ("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也将由docker拥有(与主机系统上的uid:gid相同),因此仅当您的容器用户可以连接到时,测试容器才可以工作该插座。那是正在运行进程的用户是root用户,或者您的容器内的组ID与主机系统上的docker组ID完全相同。 我还不知道有什么好的解决方案,因此对于初学者来说,您可以在容器中以root用户身份运行测试,也可以在硬编码容器的用户group-id中运行代码以匹配主机的{{1}}组ID。