Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't connect to Docker running in WSL2 VM if Testcontainers runs on Windows and Docker Desktop is not used #4958

Closed
saurabh4studies opened this issue Jan 28, 2022 · 13 comments

Comments

@saurabh4studies
Copy link

Test container failed to start and throws Exception when try to run test case.

Host system: Windows 10
WSL2 based system: Ubuntu App for windows
Docker installed inside: Ubuntu App for windows

Using WSL2 based Ubuntu App on windows and setup docker in it. We are able to connect containers run inside it from host system i.e. Windows 10 through Ubuntu App IP address and port on which containers are running. In case of test containers it fails and throws below exception

Exception:

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

	at org.testcontainers.dockerclient.DockerClientProviderStrategy.lambda$getFirstValidStrategy$7(DockerClientProviderStrategy.java:215)
	at java.util.Optional.orElseThrow(Optional.java:290)
	at org.testcontainers.dockerclient.DockerClientProviderStrategy.getFirstValidStrategy(DockerClientProviderStrategy.java:207)
	at org.testcontainers.DockerClientFactory.getOrInitializeStrategy(DockerClientFactory.java:136)
	at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:178)
	at org.testcontainers.LazyDockerClient.getDockerClient(LazyDockerClient.java:14)
	at org.testcontainers.LazyDockerClient.authConfig(LazyDockerClient.java:12)
	at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:310)
	at infrastructure.DatabaseContainer.start(DatabaseContainer.java:30)
	at com.ecw.hplus.chat.ChannelFeatureShould.before(ChannelFeatureShould.java:70)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

Test case file:

import infrastructure.DatabaseContainer;
import infrastructure.MySqlDatabaseContainer;

import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class AFeatureShould extends SimpleRepositoryTest {

    private static final MySqlDatabaseContainer mysql = new MySqlDatabaseContainer("mysql.sql");
    
    @Parameterized.Parameters
    public static DatabaseContainer[] getDatabaseContainer() {
        return new DatabaseContainer[]{
                mysql
        };
    }

    @BeforeClass
    public static void before() {
        mysql.start();
    }

    @Test
    public void test() {
        // assertions
    }
}

Tried to mitigate this issue by modifying /etc/docker/deamon.json and C:/Users/myuser/.testcontainers.properties files and not succeeded.

/etc/docker/deamon.json:

{
        "hosts": ["unix:///var/run/docker.sock", "tcp://127.0.0.1:2375"]
}

C:/Users/myuser/.testcontainers.properties:

docker.client.strategy=org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy
docker.host=tcp\://<ip-of-ubuntu-app>\:2375
@kiview
Copy link
Member

kiview commented Jan 28, 2022

Thanks for raising this issue @saurabh4studies.
Using Testcontainers from Windows, with manually installed Docker daemon in WSL2 (and without Docker Desktop) is currently not supported.

If you can't use Docker Desktop, I'd suggest running your tests from within WSL2 instead.

There might be ways to manually configure Testcontainers, Windows, Docker, and WSL2 to make your setup work, but we did not yet have time to dive into this topic.

@kiview kiview changed the title test containers failed to start Can't connect to Docker running in WSL2 VM if Testcontainers runs on Windows and Docker Desktop is not used Jan 28, 2022
@saurabh4studies
Copy link
Author

Thanks for raising this issue @saurabh4studies. Using Testcontainers from Windows, with manually installed Docker daemon in WSL2 (and without Docker Desktop) is currently not supported.

If you can't use Docker Desktop, I'd suggest running your tests from within WSL2 instead.

There might be ways to manually configure Testcontainers, Windows, Docker, and WSL2 to make your setup work, but we did not yet have time to dive into this topic.

Thank you @kiview for your insights.

@xa4atur
Copy link

xa4atur commented Feb 2, 2022

@saurabh4studies

Add these dependencies:

testImplementation 'org.testcontainers:testcontainers:1.16.3'
testImplementation 'org.testcontainers:junit-jupiter:1.16.3'
implementation 'com.github.docker-java:docker-java-api:3.2.8'

And change org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy to org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy in .testcontainers.properties

docker.host=tcp\://127.0.0.1\:2375

@kiview
Copy link
Member

kiview commented Feb 8, 2022

Thanks for sharing this workaround @xa4atur. Are you sure you need to define implementation 'com.github.docker-java:docker-java-api:3.2.8'? This should not be necessary.

@artjomka
Copy link
Contributor

artjomka commented Feb 8, 2022

Had similar issue, but with @kiview help was manage to resolve it.
Short summary:

implementation 'com.github.docker-java:docker-java-api:3.2.8' is not necessary

My .testcontainers.properties looks like this

docker.client.strategy=org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy
docker.host=tcp\://127.0.0.1\:2375

Docker socket was located in different folder, so it was necessary to set TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE environment variable, in my case it was
TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/mnt/wsl/shared-docker/docker.sock

@xa4atur
Copy link

xa4atur commented Feb 9, 2022

Thanks for sharing this workaround @xa4atur. Are you sure you need to define implementation 'com.github.docker-java:docker-java-api:3.2.8'? This should not be necessary.

Indeed, it is not necessary as docker-java-api is a transitive dependency: https://mvnrepository.com/artifact/org.testcontainers/testcontainers/1.16.0

@sz763
Copy link

sz763 commented Feb 12, 2022

I had faced with same issue. The following steps fixed it https://gist.github.com/sz763/3b0a5909a03bf2c9c5a057d032bd98b7, I hope it will help you.
UPD: saurabh4studies pay attention, you've incorrect file name deamon.json , it must be daemon.json.

@easterwood
Copy link

@saurabh4studies Which version of testcontainers did you used in this case?

@eddumelendez
Copy link
Member

Closing due to it is resolved.

@mbuchner
Copy link

For me the issue was solved when I stopped using localhost (also tried 127.0.0.1) and used the eth0 address of WSL.

My Powershell script to set the DOCKER_HOST environment variable: (problem is that wsl ip is not static)

$wslip = ((wsl hostname -I) -split " ")[0]
$dockerhost = "tcp://" + $wslip + ":2375"
setx DOCKER_HOST $dockerhost
Write-Host "Set: setx DOCKER_HOST $dockerhost"
#get-childitem env:*
Read-Host -Prompt "Press Enter to exit"

@VVATOR
Copy link

VVATOR commented Mar 7, 2024

Maybe my note might help someone...

How to make WSL Docker accessible from Windows host:

Run with Powershell (as admin):

  $dockerhost = "tcp://" + $wslip + ":2375"
  setx DOCKER_HOST $dockerhost
  Write-Host "Set: setx DOCKER_HOST $dockerhost"
  #get-childitem env:*
  Read-Host -Prompt "Press Enter to exit"

This command returns connection address like tcp://172.25.34.178:2375
Its address we should add to configuration c:\Users<user_name>.testcontainers.properties
that testcontainers used to connection with docker

docker.client.strategy=org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy
docker.host=tcp://172.25.34.178:2375

# docker.host it's internal wsl IP that should be configured to access in WSL 

In WSL terminal you should to add address from the previous step to /etc/docker/daemon.json
with come text editor

{
  "hosts": [
    "unix:///var/run/docker.sock", 
    "tcp://172.25.34.178:2375"
  ]
}

Restart wsl wih help PowerShell:

  wsl --shutdown
  wsl -l

Useful links:

@HnKnA
Copy link

HnKnA commented Aug 26, 2024

What I've done to make WSL Docker accessible from Windows host is:

  • Create a script file (Ex: SetDockerHost.ps1) and run it from Powershell:
# Get the IP address of WSL using ip command
$wslip = wsl ip addr show eth0 | Select-String 'inet ' | ForEach-Object { ($_ -split '\s+')[2] -split '/' } | Select-Object -Index 0

if ($wslip) {
    $dockerhost = "tcp://" + $wslip + ":2375"
    setx DOCKER_HOST $dockerhost
    Write-Host "Set: setx DOCKER_HOST $dockerhost"
} else {
    Write-Host "Could not determine WSL IP address."
}

Read-Host -Prompt "Press Enter to exit"
  • Go to the file's location and run it:
 .\SetDockerHost.ps1
  • The command returns connection address like tcp://your_wsl_ip_address:2375. (Ex: tcp://172.25.198.85:2375)
  • Use the address obtained from above and configure this file C:\Users\<user_name>\.testcontainers.properties (Create one if not existed):
docker.client.strategy=org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy
docker.host=tcp://your_wsl_ip_address:2375                # tcp://172.25.34.178:2375 (Mine)

  • Configure /etc/docker/daemon.json in WSL terminal:
 sudo nano /etc/docker/daemon.json
  • Make change to the file:
{
  "hosts": [
    "unix:///var/run/docker.sock", 
    "tcp://172.25.34.178:2375"
  ]
}
  • Restart and check for WSL with PowerShell:
  wsl --shutdown
  wsl -l
  • After that, open WSL terminal and run docker daemon manually (I don't know why the sudo systemctl restart docker do not run):
sudo dockerd
  • Open another WSL terminal and work with your Docker. Good luck!

@renedupont
Copy link

renedupont commented Jan 2, 2025

All I needed to do to get it working was to add:

  • {"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]} to my /etc/docker/daemon.json
  • and this to my WSL ~/.bashrc: cmd.exe /c "setx DOCKER_HOST tcp://$(ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'):2375" > /dev/null 2>&1. This sets the eth0 ip address to DOCKER_HOST env var in Win every time I open WSL.
  • Restart wsl instance

I'm still not sure why Testcontainers requires the specific eth0 address, everything else worked with just setting DOCKER_HOST to localhost.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

12 participants