Skip to content

How to configure Testcontainers to work with Colima as container runtime? #5034

@codingdiscer

Description

@codingdiscer

In the move away from paid Docker Desktop and towards alternatives, my organization has selected Colima as our official Docker engine for desktop development. After installing Colima via Homebrew on my mac, I'm able to run all my favorite docker commands as-is.

Colima sets up a new docker context, and sets itself as the active context:

> colima status
INFO[0000] colima is running
INFO[0000] runtime: docker
INFO[0000] arch: x86_64

> colima version
colima version 0.3.2
git commit: 272db4732b90390232ed9bdba955877f46a50552

runtime: docker
arch: x86_64
client: v20.10.11
server: v20.10.11

> docker context list
NAME        TYPE      DESCRIPTION                               DOCKER ENDPOINT
colima *    moby      colima                                    unix:///Users/ddowma/.colima/docker.sock
default     moby      Current DOCKER_HOST based configuration   unix:///var/run/docker.sock

As shown in the output above, there is still a default entry, and it points to unix:///var/run/docker.sock. However, I can see that no such file exists at that location:

> ls -l /var/run | grep 'docker.sock'
(empty output)

I noticed a problem when using Testcontainers 1.16.3 (and earlier versions) where Testcontainers can't find the "active" docker socket. Here are the logs when running a test case that tries to spin up a DockerComposeContainer with the scenario that I describe above:

13:53:27.547 [Test worker] INFO  o.s.t.c.s.DefaultTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.spockframework.spring.SpringMockTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.event.ApplicationEventsTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener]
13:53:27.563 [Test worker] DEBUG o.s.t.c.s.DefaultTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [javax/servlet/ServletContext]
13:53:27.577 [Test worker] INFO  o.s.t.c.s.DefaultTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@3d3599dc, org.springframework.test.context.event.ApplicationEventsTestExecutionListener@3375c9fb, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@6a8ea39d, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@71f8f1, org.springframework.test.context.support.DirtiesContextTestExecutionListener@111b6a5a, org.springframework.test.context.transaction.TransactionalTestExecutionListener@cbc4393, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@13b18bd2, org.springframework.test.context.event.EventPublishingTestExecutionListener@1c084f25, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@568bbf44, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@3845dedd, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@27353d1c, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@791a2fb8, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener@72e0ce40, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@64c555f7, org.spockframework.spring.SpringMockTestExecutionListener@6a9659ae]
13:53:27.888 [Test worker] DEBUG o.t.c.ParsedDockerComposeFile - Resolved dependency image for Docker Compose in /Users/ddowma/git/engineering-enablement/cars-publisher/cars-publisher-spring/build/resources/test/compose-kafka-zk-sr.yml: wurstmeister/zookeeper
13:53:27.904 [Test worker] DEBUG o.t.c.ParsedDockerComposeFile - Resolved dependency image for Docker Compose in /Users/ddowma/git/engineering-enablement/cars-publisher/cars-publisher-spring/build/resources/test/compose-kafka-zk-sr.yml: wurstmeister/kafka
13:53:27.904 [Test worker] DEBUG o.t.c.ParsedDockerComposeFile - Resolved dependency image for Docker Compose in /Users/ddowma/git/engineering-enablement/cars-publisher/cars-publisher-spring/build/resources/test/compose-kafka-zk-sr.yml: confluentinc/cp-schema-registry:6.1.0
13:53:27.920 [Test worker] DEBUG o.t.u.TestcontainersConfiguration - Testcontainers configuration overrides will be loaded from file:/Users/ddowma/.testcontainers.properties
13:53:27.943 [Test worker] WARN  o.t.u.TestcontainersConfiguration - Attempted to read Testcontainers configuration file at file:/Users/ddowma/.testcontainers.properties but the file was not found. Exception message: FileNotFoundException: /Users/ddowma/.testcontainers.properties (No such file or directory)
13:53:27.955 [Test worker] DEBUG o.t.d.DockerClientProviderStrategy - Trying out strategy: UnixSocketClientProviderStrategy
13:53:27.957 [Test worker] DEBUG o.t.d.DockerClientProviderStrategy - UnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (Could not find unix domain socket). Root cause NoSuchFileException (/var/run/docker.sock)
13:53:27.960 [Test worker] INFO  o.t.d.DockerMachineClientProviderStrategy - docker-machine executable was not found on PATH ([/Users/ddowma/.sdkman/candidates/java/current/bin, /Users/ddowma/.sdkman/candidates/groovy/current/bin, /usr/local/bin, /usr/bin, /bin, /usr/sbin, /sbin])
13:53:27.961 [Test worker] ERROR o.t.d.DockerClientProviderStrategy - Could not find a valid Docker environment. Please check configuration. Attempted configurations were:
13:53:27.961 [Test worker] ERROR o.t.d.DockerClientProviderStrategy -     UnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (Could not find unix domain socket). Root cause NoSuchFileException (/var/run/docker.sock)
13:53:27.961 [Test worker] ERROR o.t.d.DockerClientProviderStrategy - As no valid configuration was found, execution cannot continue

Could not find a valid Docker environment. Please see logs and check configuration
java.lang.IllegalStateException: Could not find a valid Docker environment. Please see logs and check configuration

I found a work-around that solves this problem, but it isn't a global solution. I have sudo rights on my workstation, so when I manually create a symlink from /var/run/docker.sock to /Users/ddowma/.colima/docker.sock, it works.

Thus, after running this command:

> sudo ln -s /Users/ddowma/.colima/docker.sock /var/run/docker.sock
Password:

> ls -l /var/run | grep 'docker.sock'
lrwxr-xr-x  1 root             daemon             33 Feb  8 14:00 docker.sock -> /Users/ddowma/.colima/docker.sock

Then my test case works fine. Here's the relevant output from the test case immediately after creating that symlink that shows the docker environment startup working as expected. I filtered some DEBUG statements that didn't add value, but left all the INFO statements in.

14:01:56.364 [Test worker] DEBUG o.t.c.ParsedDockerComposeFile - Resolved dependency image for Docker Compose in /Users/ddowma/git/engineering-enablement/cars-publisher/cars-publisher-spring/build/resources/test/compose-kafka-zk-sr.yml: wurstmeister/zookeeper
14:01:56.380 [Test worker] DEBUG o.t.c.ParsedDockerComposeFile - Resolved dependency image for Docker Compose in /Users/ddowma/git/engineering-enablement/cars-publisher/cars-publisher-spring/build/resources/test/compose-kafka-zk-sr.yml: wurstmeister/kafka
14:01:56.380 [Test worker] DEBUG o.t.c.ParsedDockerComposeFile - Resolved dependency image for Docker Compose in /Users/ddowma/git/engineering-enablement/cars-publisher/cars-publisher-spring/build/resources/test/compose-kafka-zk-sr.yml: confluentinc/cp-schema-registry:6.1.0
14:01:56.396 [Test worker] DEBUG o.t.u.TestcontainersConfiguration - Testcontainers configuration overrides will be loaded from file:/Users/ddowma/.testcontainers.properties
14:01:56.420 [Test worker] WARN  o.t.u.TestcontainersConfiguration - Attempted to read Testcontainers configuration file at file:/Users/ddowma/.testcontainers.properties but the file was not found. Exception message: FileNotFoundException: /Users/ddowma/.testcontainers.properties (No such file or directory)
14:01:56.433 [Test worker] DEBUG o.t.d.DockerClientProviderStrategy - Trying out strategy: UnixSocketClientProviderStrategy
14:01:56.894 [ducttape-0] DEBUG o.t.d.DockerClientProviderStrategy - Pinging docker daemon...
14:01:57.422 [Test worker] INFO  o.t.d.DockerClientProviderStrategy - Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
14:01:57.422 [Test worker] DEBUG o.t.d.DockerClientProviderStrategy - Transport type: 'httpclient5', Docker host: 'unix:///var/run/docker.sock'
14:01:57.423 [Test worker] DEBUG o.t.d.DockerClientProviderStrategy - Checking Docker OS type for local Unix socket (unix:///var/run/docker.sock)
14:01:57.428 [Test worker] INFO  o.testcontainers.DockerClientFactory - Docker host IP address is localhost
14:01:57.470 [Test worker] INFO  o.testcontainers.DockerClientFactory - Connected to docker: 
  Server Version: 20.10.11
  API Version: 1.41
  Operating System: Alpine Linux v3.14
  Total Memory: 1988 MB
14:01:57.470 [Test worker] DEBUG o.testcontainers.DockerClientFactory - Ryuk is enabled
14:01:57.475 [Test worker] INFO  o.t.utility.ImageNameSubstitutor - Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
14:01:57.478 [Test worker] DEBUG o.t.u.PrefixingImageNameSubstitutor - No prefix is configured
14:01:57.478 [Test worker] DEBUG o.t.utility.ImageNameSubstitutor - Did not find a substitute image for testcontainers/ryuk:0.3.3 (using image substitutor: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor'))
14:01:57.479 [Test worker] DEBUG o.t.s.c.g.d.c.command.AbstrDockerCmd - Cmd: testcontainers/ryuk:0.3.3
14:01:57.523 [Test worker] DEBUG o.t.utility.RegistryAuthLocator - Looking up auth config for image: testcontainers/ryuk:0.3.3 at registry: index.docker.io
14:01:57.523 [Test worker] DEBUG o.t.utility.RegistryAuthLocator - RegistryAuthLocator has configFile: /Users/ddowma/.docker/config.json (exists) and commandPathPrefix: 
14:01:57.524 [Test worker] DEBUG o.t.utility.RegistryAuthLocator - registryName [index.docker.io] for dockerImageName [testcontainers/ryuk:0.3.3]
14:01:57.525 [Test worker] DEBUG o.t.utility.RegistryAuthLocator - No matching Auth Configs - falling back to defaultAuthConfig [null]
14:01:57.525 [Test worker] DEBUG o.t.d.AuthDelegatingDockerClientConfig - Effective auth config [null]
14:01:57.538 [Test worker] DEBUG o.t.s.c.g.d.c.command.AbstrDockerCmd - Cmd: org.testcontainers.shaded.com.github.dockerjava.core.command.CreateContainerCmdImpl@1ea5f0de[name=testcontainers-ryuk-156612ea-886b-4884-a157-50e191f885a9,hostName=<null>,domainName=<null>,user=<null>,attachStdin=<null>,attachStdout=<null>,attachStderr=<null>,portSpecs=<null>,tty=<null>,stdinOpen=<null>,stdInOnce=<null>,env=<null>,cmd=<null>,healthcheck=<null>,argsEscaped=<null>,entrypoint=<null>,image=testcontainers/ryuk:0.3.3,volumes=Volumes(volumes=[]),workingDir=<null>,macAddress=<null>,onBuild=<null>,networkDisabled=<null>,exposedPorts=ExposedPorts(exposedPorts=[8080/tcp]),stopSignal=<null>,stopTimeout=<null>,hostConfig=HostConfig(binds=[/var/run/docker.sock:/var/run/docker.sock:rw], blkioWeight=null, blkioWeightDevice=null, blkioDeviceReadBps=null, blkioDeviceWriteBps=null, blkioDeviceReadIOps=null, blkioDeviceWriteIOps=null, memorySwappiness=null, nanoCPUs=null, capAdd=null, capDrop=null, containerIDFile=null, cpuPeriod=null, cpuRealtimePeriod=null, cpuRealtimeRuntime=null, cpuShares=null, cpuQuota=null, cpusetCpus=null, cpusetMems=null, devices=null, deviceCgroupRules=null, deviceRequests=null, diskQuota=null, dns=null, dnsOptions=null, dnsSearch=null, extraHosts=null, groupAdd=null, ipcMode=null, cgroup=null, links=[], logConfig=LogConfig(type=null, config=null), lxcConf=null, memory=null, memorySwap=null, memoryReservation=null, kernelMemory=null, networkMode=null, oomKillDisable=null, init=null, autoRemove=true, oomScoreAdj=null, portBindings={8080/tcp=[Lcom.github.dockerjava.api.model.Ports$Binding;@bfeaa61}, privileged=false, publishAllPorts=null, readonlyRootfs=null, restartPolicy=null, ulimits=null, cpuCount=null, cpuPercent=null, ioMaximumIOps=null, ioMaximumBandwidth=null, volumesFrom=null, mounts=null, pidMode=null, isolation=null, securityOpts=null, storageOpt=null, cgroupParent=null, volumeDriver=null, shmSize=null, pidsLimit=null, runtime=null, tmpFs=null, utSMode=null, usernsMode=null, sysctls=null, consoleSize=null),labels={org.testcontainers=true},shell=<null>,networkingConfig=<null>,ipv4Address=<null>,ipv6Address=<null>,aliases=<null>,authConfig=<null>,platform=<null>]
14:01:58.022 [Test worker] DEBUG o.t.s.c.g.d.c.e.InspectContainerCmdExec - GET: DefaultWebTarget{path=[/containers/3d81f73b9b4365657236d017aa32d0d4945e2c1eb0993d09e64e06e4591ab3d0/json], queryParams={}}
14:01:58.096 [testcontainers-ryuk] DEBUG o.t.utility.ResourceReaper - Sending 'label=org.testcontainers%3Dtrue&label=org.testcontainers.sessionId%3D156612ea-886b-4884-a157-50e191f885a9' to Ryuk
14:01:58.099 [testcontainers-ryuk] DEBUG o.t.utility.ResourceReaper - Received 'ACK' from Ryuk
14:01:58.101 [Test worker] INFO  o.testcontainers.DockerClientFactory - Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
14:01:58.101 [Test worker] DEBUG o.testcontainers.DockerClientFactory - Checks are enabled
14:01:58.101 [Test worker] INFO  o.testcontainers.DockerClientFactory - Checking the system...
14:01:58.102 [Test worker] INFO  o.testcontainers.DockerClientFactory - ✔︎ Docker server version should be at least 1.6.0
14:01:58.230 [Test worker] INFO  o.testcontainers.DockerClientFactory - ✔︎ Docker environment should have more than 2GB free disk space
14:01:58.234 [testcontainers-ryuk] DEBUG o.t.utility.ResourceReaper - Sending 'label=com.docker.compose.project%3Dn9eh7nsc2dkm' to Ryuk
14:01:58.234 [Test worker] INFO  o.t.c.DockerComposeContainer - Preemptively checking local images for 'confluentinc/cp-schema-registry:6.1.0', referenced via a compose file or transitive Dockerfile. If not available, it will be pulled.
14:01:58.234 [Test worker] DEBUG o.t.s.c.g.d.c.command.AbstrDockerCmd - Cmd: confluentinc/cp-schema-registry:6.1.0
14:01:58.236 [testcontainers-ryuk] DEBUG o.t.utility.ResourceReaper - Received 'ACK' from Ryuk
14:01:58.239 [Test worker] INFO  o.t.c.DockerComposeContainer - Preemptively checking local images for 'wurstmeister/zookeeper:latest', referenced via a compose file or transitive Dockerfile. If not available, it will be pulled.
14:01:58.239 [Test worker] DEBUG o.t.s.c.g.d.c.command.AbstrDockerCmd - Cmd: wurstmeister/zookeeper:latest
14:01:58.243 [Test worker] INFO  o.t.c.DockerComposeContainer - Preemptively checking local images for 'wurstmeister/kafka:latest', referenced via a compose file or transitive Dockerfile. If not available, it will be pulled.
14:01:58.243 [Test worker] DEBUG o.t.s.c.g.d.c.command.AbstrDockerCmd - Cmd: wurstmeister/kafka:latest
14:01:58.254 [Test worker] DEBUG o.t.u.PrefixingImageNameSubstitutor - No prefix is configured
14:01:58.254 [Test worker] DEBUG o.t.utility.ImageNameSubstitutor - Did not find a substitute image for docker/compose:1.29.2 (using image substitutor: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor'))
14:01:58.257 [Test worker] DEBUG o.t.s.c.g.d.c.command.AbstrDockerCmd - Cmd: ListImagesCmdImpl[imageNameFilter=<null>,showAll=false,filters=org.testcontainers.shaded.com.github.dockerjava.core.util.FiltersBuilder@0]
14:01:58.266 [Test worker] DEBUG o.t.images.AbstractImagePullPolicy - Using locally available and not pulling image: docker/compose:1.29.2
14:01:58.266 [Test worker] DEBUG 🐳 [docker/compose:1.29.2] - Set env COMPOSE_FILE=/Users/ddowma/git/engineering-enablement/cars-publisher/cars-publisher-spring/build/resources/test/compose-kafka-zk-sr.yml
14:01:58.269 [Test worker] DEBUG 🐳 [docker/compose:1.29.2] - Starting container: docker/compose:1.29.2
14:01:58.269 [Test worker] DEBUG 🐳 [docker/compose:1.29.2] - Trying to start container: docker/compose:1.29.2 (attempt 1/1)
14:01:58.269 [Test worker] DEBUG 🐳 [docker/compose:1.29.2] - Starting container: docker/compose:1.29.2
14:01:58.269 [Test worker] INFO  🐳 [docker/compose:1.29.2] - Creating container for image: docker/compose:1.29.2
14:01:59.036 [Test worker] INFO  🐳 [docker/compose:1.29.2] - Container docker/compose:1.29.2 is starting: 19d5b5146235a3528adabaed4837f43d4c18302b1261f8e3167ed74f49d5040c
14:02:02.180 [Test worker] DEBUG o.t.c.w.s.HostPortWaitStrategy - Liveness check ports of /great_albattani is empty. Not waiting.
14:02:02.180 [Test worker] INFO  🐳 [docker/compose:1.29.2] - Container docker/compose:1.29.2 started in PT3.911682S
14:02:02.184 [Test worker] INFO  🐳 [docker/compose:1.29.2] - Docker Compose container is running for command: up -d
14:02:02.188 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: The Docker Engine you're using is running in swarm mode.
14:02:02.188 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: 
14:02:02.188 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
14:02:02.189 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: 
14:02:02.189 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: To deploy your application across the swarm, use `docker stack deploy`.
14:02:02.189 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: 
14:02:02.189 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: Creating network "n9eh7nsc2dkm_default" with the default driver
14:02:02.189 [Test worker] INFO  🐳 [docker/compose:1.29.2] - Docker Compose has finished running
14:02:02.189 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: Creating n9eh7nsc2dkm_zookeeper_1 ... 
14:02:02.189 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: Creating n9eh7nsc2dkm_zookeeper_1 ... done
14:02:02.190 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: Creating n9eh7nsc2dkm_schemaregistry_1 ... 
14:02:02.190 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: Creating n9eh7nsc2dkm_kafka_1          ... 
14:02:02.190 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: Creating n9eh7nsc2dkm_kafka_1          ... done
14:02:02.190 [docker-java-stream--579305284] INFO  🐳 [docker/compose:1.29.2] - STDERR: Creating n9eh7nsc2dkm_schemaregistry_1 ... done

What I glean from this exercise is that Testcontainers is taking the default docker context (or maybe not checking at all), and isn't looking at the active context. If my assessment of the problem is correct, can that situation be addressed?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions