Testcontainers.MsSql在Docker构建时无法检测Docker主机配置的问题
问题详情
我在ASP.NET项目中使用Testcontainers.MsSql 3.0.0做集成测试,在Visual Studio测试运行器里能正常执行,但用Docker Desktop 20.10.7通过docker build命令运行测试时,报错:
Auto discovery did not detect a Docker host configuration Cannot detect the Docker endpoint. Use either the environment variables or the ~/.testcontainers.properties file to customize your configuration
容器创建代码:
var dbContainer = new MsSqlBuilder() .WithImage(imageName) .WithCleanUp(true) .Build();
Dockerfile内容:
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env ARG buildVersion WORKDIR /app COPY . ./ RUN dotnet restore ./Test.sln RUN dotnet test ./Test.sln /p:CollectCoverage=true RUN dotnet publish ./Test/ -c Release -o out FROM mcr.microsoft.com/dotnet/aspnet:7.0 WORKDIR /app COPY --from=build-env /app/out . ENV TZ=Asia/Tehran RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN dpkg-reconfigure -f noninteractive tzdata EXPOSE 80 80/tcp ENTRYPOINT ["dotnet", "Test.dll"]
试过用docker-compose运行但也没解决,配置如下:
version: "3" services: docker_compose_test: build: dockerfile: Dockerfile context: . entrypoint: dotnet command: test environment: - TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal volumes: - $PWD:$PWD - /var/run/docker.sock:/var/run/docker.sock
核心原因
Testcontainers需要访问Docker主机来创建子容器,但docker build的构建阶段是完全隔离的,无法直接访问宿主机的Docker守护进程;同时原docker-compose配置没有正确传递必要的环境变量和权限。
解决方案
方案1:不在Docker构建阶段执行测试
把测试步骤从构建流程中剥离,用独立的测试容器运行:
修改Dockerfile(移除构建阶段的测试命令)
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env ARG buildVersion WORKDIR /app COPY . ./ RUN dotnet restore ./Test.sln RUN dotnet publish ./Test/ -c Release -o out FROM mcr.microsoft.com/dotnet/aspnet:7.0 WORKDIR /app COPY --from=build-env /app/out . ENV TZ=Asia/Tehran RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN dpkg-reconfigure -f noninteractive tzdata EXPOSE 80 80/tcp ENTRYPOINT ["dotnet", "Test.dll"]
调整docker-compose.yml,单独运行测试容器
version: "3" services: docker_compose_test: image: mcr.microsoft.com/dotnet/sdk:7.0 working_dir: /app entrypoint: dotnet command: test ./Test.sln /p:CollectCoverage=true environment: - DOCKER_HOST=tcp://host.docker.internal:2375 - TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal - TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock volumes: - .:/app - /var/run/docker.sock:/var/run/docker.sock
运行命令:docker-compose up docker_compose_test
方案2:在测试代码中显式指定Docker主机
如果必须在容器内运行测试,可在Testcontainers构建时直接指定Docker端点:
var dbContainer = new MsSqlBuilder() .WithImage(imageName) .WithCleanUp(true) .WithDockerEndpoint("tcp://host.docker.internal:2375") // 对应Docker Desktop的端口 .Build();
同时确保测试容器挂载了/var/run/docker.sock并设置了方案1中的环境变量。
方案3:Docker Desktop特殊配置(Windows/macOS)
如果是Windows或macOS环境,需要先开启Docker Desktop的TCP访问:
- 打开Docker Desktop设置 -> Docker Engine
- 启用"Expose daemon on tcp://localhost:2375 without TLS"选项
- 重启Docker Desktop
确保测试容器的DOCKER_HOST环境变量设置为tcp://host.docker.internal:2375。
内容的提问来源于stack exchange,提问作者vahid tajari

