I am trying to run Java TestContainers from GitLab-CI, using Docker-in-Docker. For security reasons, I am only allowed to use images replicated to internal enterprise container registry.
When I run the job with the following configuration:
test:
image: internalregistry.azurecr.io/maven:3.9-eclipse-temurin-17
services:
- docker:24.0.5-dind
stage: test
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
DOCKER_DRIVER: overlay2
before_script:
- echo "hub.image.name.prefix=internalregistry.azurecr.io/" > $HOME/.testcontainers.properties
script:
- mvn clean test
the job works, tests are successfully executed and pass.
However, I created an internal variation of the image:
docker pull docker:24.0.5-dind
docker tag docker:24.0.5-dind internalregistry.azurecr.io/docker:24.0.5-dind
docker push internalregistry.azurecr.io/docker:24.0.5-dind
and when I change the docker service to point to internal registry:
services:
- internalregistry.azurecr.io/docker:24.0.5-dind
the pipeline no longer suceeds and fails with the following error:
Could not find a valid Docker environment. Please check configuration. Attempted configurations were:\n\tUnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (Could not find unix domain socket). Root cause NoSuchFileException (/var/run/docker.sock)As no valid configuration was found, execution cannot continue.\nSee https://www.testcontainers.org/on_failure.html for more details.
During valid execution I noticed the following TestContainers strategy is used:
logger":"org.testcontainers.dockerclient.DockerClientProviderStrategy","message":"Found Docker environment with Environment variables, system properties and defaults. Resolved dockerHost=tcp://docker:2375"
I tried configuring the same strategy for the GitLab-CI:
before_script:
- echo "hub.image.name.prefix=internalregistry.azurecr.io/" > $HOME/.testcontainers.properties
- echo "docker.client.strategy=org.testcontainers.dockerclient.DockerClientProviderStrategy" >> $HOME/.testcontainers.properties
Unfortunatelly, even this configuration fails with the following error:
logger":"org.testcontainers.dockerclient.DockerClientProviderStrategy","message":"Can't instantiate a strategy from org.testcontainers.dockerclient.DockerClientProviderStrategy"
with the following underlying message:
{"timestamp":"2023-12-19T09:02:21.104Z","level":"WARN","thread":"main","logger":"org.testcontainers.dockerclient.DockerClientProviderStrategy","message":"DOCKER_HOST tcp://docker:2375 is not listening","context":"default"}
{"timestamp":"2023-12-19T09:02:21.280Z","level":"INFO","thread":"main","logger":"org.testcontainers.dockerclient.DockerMachineClientProviderStrategy","message":"docker-machine executable was not found on PATH ([/opt/java/openjdk/bin, /usr/local/sbin, /usr/local/bin, /usr/sbin, /usr/bin, /sbin, /bin])","context":"default"}
{"timestamp":"2023-12-19T09:02:21.281Z","level":"ERROR","thread":"main","logger":"org.testcontainers.dockerclient.DockerClientProviderStrategy","message":"Could not find a valid Docker environment. Please check configuration. Attempted configurations were:\n\tUnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (Could not find unix domain socket). Root cause NoSuchFileException (/var/run/docker.sock)As no valid configuration was found, execution cannot continue.\nSee https://www.testcontainers.org/on_failure.html for more details.","context":"default"}
The problem
As per official documentation, when defining services, a service is registered after a name is automatically inferred from the provided image:
This means, when you used the
docker:24.0.5-dindfrom public hub, the created alias wasdocker. However, when you started service from image within your internal registry, the created aliases were the following:internalregistry.azurecr.io-docker,internalregistry.azurecr.io__docker.Now, when you define the
DOCKER_HOSTvariable:you are trying to access a service named
docker, but in your case, the only service names available are those mentioned above:internalregistry.azurecr.io-docker,internalregistry.azurecr.io__docker.The solution
You can either reconfigure your
DOCKER_HOSTvariable to use the automatically inferred alias:or (and I would recommend this solution) set an alias,
docker, that way theDOCKER_HOSTremains the same and the service created from image pulled from your internal registry is registered under the value provided in thealiasdirective:Naturally, the value specified in
aliasneeds to match the host specified in theDOCKER_HOST(or any for that matter) env variable, and vice versa.Also ensure the image is actually the same (i.e. same SHA256 digest) as
docker:24.0.5-dind