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

ResourceReaperException: Initialization has been cancelled #449

Closed
HofmeisterAn opened this issue May 1, 2022 · 57 comments
Closed

ResourceReaperException: Initialization has been cancelled #449

HofmeisterAn opened this issue May 1, 2022 · 57 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@HofmeisterAn
Copy link
Collaborator

Describe the bug
It looks like, that in some rare cases .NET Testcontainers can't connect to Ryuk. I got a few times the following error:

DotNet.Testcontainers.Containers.ResourceReaperException : Initialization has been cancelled.

According the log messages, .NET Testcontainers tries to connect a couple of times. It looks like Ryuk is not ready to accept a connection. @PSanetra Do you have any idea? May this relate to the recent changes in the image?

To Reproduce
-

Expected behavior
.NET Testcontainers can connect to Ryuk.

Screenshots
-

Desktop (please complete the following information):

  • Docker Desktop 4.7.1 (77678)

Additional context
Build 2193. May relate to: #423, #441, #443.

Workaround
Disable the ResourceReaper (TestcontainersSettings.ResourceReaperEnabled = false).

@HofmeisterAn HofmeisterAn added the bug Something isn't working label May 1, 2022
@PSanetra
Copy link
Contributor

PSanetra commented May 1, 2022

Hi @HofmeisterAn, the image was not updated since December.

To debug this issue, it would be nice if we could log some information about the current environment.

  • currently available network interfaces in the test environment, which executes the tests
  • expected ryuk endpoint (ip and port)
  • count of connection attempts
  • docker container inspect information of the ryuk container
  • ryuk logs
  • cancellation reason (initTimeout or the external CancellationToken)

A possible cause of this issue might be an occasionally slow download of the ryuk image.

PSanetra added a commit to PSanetra/dotnet-testcontainers that referenced this issue May 1, 2022
… function: ResourceReaper'

{Add diagnostics information to ResourceReaperException.}
HofmeisterAn pushed a commit that referenced this issue May 2, 2022
…ourceReaper'

{Add diagnostic information to ResourceReaperException.}
@PSanetra
Copy link
Contributor

PSanetra commented Jun 3, 2022

@HofmeisterAn did you get new reports regarding this issue recently?

@HofmeisterAn
Copy link
Collaborator Author

No, not lately. Looks stable for my builds, but this is an interesting comment: #443 (reply in thread).

@HofmeisterAn
Copy link
Collaborator Author

Here we go: 2252.

@PSanetra
Copy link
Contributor

PSanetra commented Jun 7, 2022

@HofmeisterAn on first sight it seems odd that there was only a single connection attempt.

The resource reaper session id looks wrong, too:

"dotnet.testcontainers.resource-reaper-session": "00000000-0000-0000-0000-000000000000"

@HofmeisterAn
Copy link
Collaborator Author

HofmeisterAn commented Jun 7, 2022

Yes, I was wondering about the connection attempt as well. I didn't notice the label. The container name looks fine: /testcontainers-ryuk-83eae8ca-15c8-4d9e-bdc0-e25b25179dc3.

It looks like a race condition in DefaultLabels. SkipOnLinuxEngineAttribute sets ResourceReaperEnabled, but that should always be enabled for Linux tests.

@HofmeisterAn
Copy link
Collaborator Author

The session ID (Guid.Empty) is correct. The log shows the Ryuk container inspect result. The cleanup is disabled for the resource reaper (WithCleanUp(false)).

@kron0s19
Copy link

I dont know if this helps.. but the same things was happening to me, trying to use a mariadb database (Logs just like yours.)

Interesting.. while debugging it was working fine, and failing only on some computers.

What seems to fix it was adding ".WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(3306))"

private readonly TestcontainerDatabase _dbContainer = new TestcontainersBuilder<MySqlTestcontainer>() .WithDatabase(new MySqlTestcontainerConfiguration("mariadb:10.5.5") { Database = "mydb", Username = "myuser", Password = "mypass", Port = 3306 }) .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(3306)) .Build();

@HofmeisterAn
Copy link
Collaborator Author

@kron0s19 Do you still have the logs? The resource reaper exception incl. its diagnostic information might be helpful.

@kron0s19
Copy link

error.txt
This is what I was getting.

I can confirm it has not happened again after adding "WithWaitStrategy"

@PSanetra
Copy link
Contributor

PSanetra commented Jun 13, 2022

Interesting detail about the new error log:

{
  [...]
  "ExpectedHost": "localhost",
  "ExpectedPort": 49153,
  "ContainerInspection": {
    [...]
    "NetworkSettings": {
      [...]
      "Ports": {
        "8080/tcp": [
          {
            "HostIP": "0.0.0.0",
            "HostPort": "63127"
          }
        ]
      },
      [...]
    }
  }
}

The expected port does not match with the actual host port binding of the ryuk container.

This is different than in the previous error log we have.

Edit: Another detail which might be important is that the host has IPv6 support (also loopback), but there is only a IPv4 binding for that port on the host. So a connection to localhost might fail if it is resolved to ::1.

@PSanetra
Copy link
Contributor

The session ID (Guid.Empty) is correct. The log shows the Ryuk container inspect result. The cleanup is disabled for the resource reaper (WithCleanUp(false)).

Make sense 👍
I think in that case we should omit the label from the container.

@srollinet
Copy link

Same issue here on Windows. Sometimes it works, sometimes it fails with this exception ResourceReaperException

DotNet.Testcontainers.Containers.ResourceReaperException
Initialization has been cancelled.
{
  "ConnectionAttempts": 2,
  "LocalNetworkInterfaces": {
    "{65496C37-B14C-4240-80D1-D70919634587}": [
      "fe80::e000:be57:78ca:9016%13",
      "169.254.144.22"
    ],
    "{114419F6-1B1E-4AA0-B45B-6A9DCC8919DB}": [
      "fe80::a9e7:379:9b0a:92e9%3",
      "169.254.146.233"
    ],
    "{468F976F-62B8-4EDA-9810-04434F48CEAC}": [
      "fe80::953c:37e:7a49:3c2b%10",
      "169.254.60.43"
    ],
    "{DA05C777-76CD-490E-B918-658EAB05754F}": [
      "fe80::74dd:6d1f:d41:3525%77",
      "192.168.32.1"
    ],
    "{9DBC6CA6-9146-4ECA-B573-3F5C6788ACED}": [
      "fe80::ad9f:cf38:fa12:a656%24",
      "192.168.50.140"
    ],
    "{35AC8699-8C28-41F8-94B9-8980F0BD7C8C}": [
      "fe80::e16e:4bfa:c172:7f27%8",
      "169.254.127.39"
    ],
    "{407C0181-4D1D-4932-85F1-DB55E0DBA6EF}": [
      "fe80::617d:b3c3:63b8:ad8f%9",
      "169.254.173.143"
    ],
    "{8CF48E01-8038-460B-9049-EFDAA77BDDA0}": [
      "fe80::6997:43fe:9fe5:8803%21",
      "169.254.136.3"
    ],
    "{67CA33D7-7E83-4B6E-8448-52B4718C2066}": [
      "fe80::4ce8:fc74:d188:bf97%15",
      "169.254.191.151"
    ],
    "{C96BABE4-121E-4D6D-8A64-26476F2888DB}": [
      "fe80::f18b:cd26:1ca5:146c%29",
      "169.254.20.108"
    ],
    "{35F0BF58-A867-11EB-86E8-806E6F6E6963}": [
      "::1",
      "127.0.0.1"
    ],
    "{AF1CD63D-F866-48A2-9086-F7DA4A29798A}": [
      "fe80::8c48:6101:ec0:8f48%90",
      "172.31.192.1"
    ]
  },
  "ExpectedHost": "localhost",
  "ExpectedPort": 49227,
  "ContainerInspection": {
    "ID": "d7ad52074af21e747b80f487bf79263288504f6c8759e019afb83bf58a0065c1",
    "Created": "2022-06-15T08:24:06.5377028Z",
    "Path": "/app",
    "Args": [],
    "State": {
      "Status": "running",
      "Running": true,
      "Paused": false,
      "Restarting": false,
      "OOMKilled": false,
      "Dead": false,
      "Pid": 13808,
      "ExitCode": 0,
      "Error": "",
      "StartedAt": "2022-06-15T08:24:06.95581392Z",
      "FinishedAt": "0001-01-01T00:00:00Z",
      "Health": null
    },
    "Image": "sha256:a0a36b674846145de03e245546b041e183f5a47e660fcba0d44f7c5392581f42",
    "ResolvConfPath": "/var/lib/docker/containers/d7ad52074af21e747b80f487bf79263288504f6c8759e019afb83bf58a0065c1/resolv.conf",
    "HostnamePath": "/var/lib/docker/containers/d7ad52074af21e747b80f487bf79263288504f6c8759e019afb83bf58a0065c1/hostname",
    "HostsPath": "/var/lib/docker/containers/d7ad52074af21e747b80f487bf79263288504f6c8759e019afb83bf58a0065c1/hosts",
    "LogPath": "/var/lib/docker/containers/d7ad52074af21e747b80f487bf79263288504f6c8759e019afb83bf58a0065c1/d7ad52074af21e747b80f487bf79263288504f6c8759e019afb83bf58a0065c1-json.log",
    "Node": null,
    "Name": "/testcontainers-ryuk-e7442a19-45fa-4c44-82c3-f704678b4f78",
    "RestartCount": 0,
    "Driver": "overlay2",
    "Platform": "linux",
    "MountLabel": "",
    "ProcessLabel": "",
    "AppArmorProfile": "",
    "ExecIDs": null,
    "HostConfig": {
      "Binds": null,
      "ContainerIDFile": "",
      "LogConfig": {
        "Type": "json-file",
        "Config": {}
      },
      "NetworkMode": "default",
      "PortBindings": {
        "8080/tcp": [
          {
            "HostIP": "0.0.0.0",
            "HostPort": "0"
          }
        ]
      },
      "RestartPolicy": {
        "Name": 0,
        "MaximumRetryCount": 0
      },
      "AutoRemove": true,
      "VolumeDriver": "",
      "VolumesFrom": null,
      "CapAdd": null,
      "CapDrop": null,
      "CgroupnsMode": "host",
      "DNS": null,
      "DNSOptions": null,
      "DNSSearch": null,
      "ExtraHosts": null,
      "GroupAdd": null,
      "IpcMode": "private",
      "Cgroup": "",
      "Links": null,
      "OomScoreAdj": 0,
      "PidMode": "",
      "Privileged": false,
      "PublishAllPorts": false,
      "ReadonlyRootfs": false,
      "SecurityOpt": null,
      "StorageOpt": null,
      "Tmpfs": null,
      "UTSMode": "",
      "UsernsMode": "",
      "ShmSize": 67108864,
      "Sysctls": null,
      "Runtime": "runc",
      "ConsoleSize": [
        0,
        0
      ],
      "Isolation": "",
      "CPUShares": 0,
      "Memory": 0,
      "NanoCPUs": 0,
      "CgroupParent": "",
      "BlkioWeight": 0,
      "BlkioWeightDevice": null,
      "BlkioDeviceReadBps": null,
      "BlkioDeviceWriteBps": null,
      "BlkioDeviceReadIOps": null,
      "BlkioDeviceWriteIOps": null,
      "CPUPeriod": 0,
      "CPUQuota": 0,
      "CPURealtimePeriod": 0,
      "CPURealtimeRuntime": 0,
      "CpusetCpus": "",
      "CpusetMems": "",
      "Devices": null,
      "DeviceCgroupRules": null,
      "DeviceRequests": null,
      "KernelMemory": 0,
      "KernelMemoryTCP": 0,
      "MemoryReservation": 0,
      "MemorySwap": 0,
      "MemorySwappiness": null,
      "OomKillDisable": false,
      "PidsLimit": null,
      "Ulimits": null,
      "CPUCount": 0,
      "CPUPercent": 0,
      "IOMaximumIOps": 0,
      "IOMaximumBandwidth": 0,
      "Mounts": [
        {
          "Type": "bind",
          "Source": "/var/run/docker.sock",
          "Target": "/var/run/docker.sock",
          "ReadOnly": true,
          "Consistency": null,
          "BindOptions": null,
          "VolumeOptions": null,
          "TmpfsOptions": null
        }
      ],
      "MaskedPaths": [
        "/proc/asound",
        "/proc/acpi",
        "/proc/kcore",
        "/proc/keys",
        "/proc/latency_stats",
        "/proc/timer_list",
        "/proc/timer_stats",
        "/proc/sched_debug",
        "/proc/scsi",
        "/sys/firmware"
      ],
      "ReadonlyPaths": [
        "/proc/bus",
        "/proc/fs",
        "/proc/irq",
        "/proc/sys",
        "/proc/sysrq-trigger"
      ],
      "Init": null
    },
    "GraphDriver": {
      "Data": {
        "LowerDir": "/var/lib/docker/overlay2/c1d78ef038ad729582d479de4139b22d36add9b2d3b372ac838fe9f47f7acbb6-init/diff:/var/lib/docker/overlay2/59850a04cb8237e9161ecc6859c1399df5bace2e3c21e8b658285d0e387edb9f/diff:/var/lib/docker/overlay2/5210167bf33795b800d34d3c69bb46d93b85c265a1d8486667a49a724693ee1d/diff:/var/lib/docker/overlay2/58e4b51e6a63798684332b242253150e23cebef003f3a5dbd5901da2b0c0b70f/diff",
        "MergedDir": "/var/lib/docker/overlay2/c1d78ef038ad729582d479de4139b22d36add9b2d3b372ac838fe9f47f7acbb6/merged",
        "UpperDir": "/var/lib/docker/overlay2/c1d78ef038ad729582d479de4139b22d36add9b2d3b372ac838fe9f47f7acbb6/diff",
        "WorkDir": "/var/lib/docker/overlay2/c1d78ef038ad729582d479de4139b22d36add9b2d3b372ac838fe9f47f7acbb6/work"
      },
      "Name": "overlay2"
    },
    "SizeRw": null,
    "SizeRootFs": null,
    "Mounts": [
      {
        "Type": "bind",
        "Name": null,
        "Source": "/var/run/docker.sock",
        "Destination": "/var/run/docker.sock",
        "Driver": null,
        "Mode": "",
        "RW": false,
        "Propagation": "rprivate"
      }
    ],
    "Config": {
      "Hostname": "d7ad52074af2",
      "Domainname": "",
      "User": "",
      "AttachStdin": false,
      "AttachStdout": false,
      "AttachStderr": false,
      "ExposedPorts": {
        "8080/tcp": {}
      },
      "Tty": false,
      "OpenStdin": false,
      "StdinOnce": false,
      "Env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
      ],
      "Cmd": [
        "/app"
      ],
      "Healthcheck": null,
      "ArgsEscaped": false,
      "Image": "ghcr.io/psanetra/ryuk:2021.12.20",
      "Volumes": null,
      "WorkingDir": "",
      "Entrypoint": null,
      "NetworkDisabled": false,
      "MacAddress": null,
      "OnBuild": null,
      "Labels": {
        "dotnet.testcontainers": "True",
        "dotnet.testcontainers.resource-reaper-session": "00000000-0000-0000-0000-000000000000"
      },
      "StopSignal": null,
      "StopTimeout": null,
      "Shell": null
    },
    "NetworkSettings": {
      "Bridge": "",
      "SandboxID": "df8ac43499d1f3ea633e5b830f27c6233a1b5df9e0356546efe678a05ca70f2f",
      "HairpinMode": false,
      "LinkLocalIPv6Address": "",
      "LinkLocalIPv6PrefixLen": 0,
      "Ports": {
        "8080/tcp": [
          {
            "HostIP": "0.0.0.0",
            "HostPort": "56214"
          }
        ]
      },
      "SandboxKey": "/var/run/docker/netns/df8ac43499d1",
      "SecondaryIPAddresses": null,
      "SecondaryIPv6Addresses": null,
      "EndpointID": "56a5139b90262966f2edda89ebfddbbd6294837375bbefa720d5625f0cdbba5c",
      "Gateway": "172.17.0.1",
      "GlobalIPv6Address": "",
      "GlobalIPv6PrefixLen": 0,
      "IPAddress": "172.17.0.2",
      "IPPrefixLen": 16,
      "IPv6Gateway": "",
      "MacAddress": "02:42:ac:11:00:02",
      "Networks": {
        "bridge": {
          "IPAMConfig": null,
          "Links": null,
          "Aliases": null,
          "NetworkID": "301be24d1357a66d63cb26b3c9b0b640d072208f0d33c01410f4aec8a69f3855",
          "EndpointID": "56a5139b90262966f2edda89ebfddbbd6294837375bbefa720d5625f0cdbba5c",
          "Gateway": "172.17.0.1",
          "IPAddress": "172.17.0.2",
          "IPPrefixLen": 16,
          "IPv6Gateway": "",
          "GlobalIPv6Address": "",
          "GlobalIPv6PrefixLen": 0,
          "MacAddress": "02:42:ac:11:00:02",
          "DriverOpts": null
        }
      }
    }
  }
}

docker ps

CONTAINER ID   IMAGE                              COMMAND   CREATED        STATUS                  PORTS                     NAMES
d7ad52074af2   ghcr.io/psanetra/ryuk:2021.12.20   "/app"    1 second ago   Up Less than a second   0.0.0.0:56214->8080/tcp   testcontainers-ryuk-e7442a19-45fa-4c44-82c3-f704678b4f78

At first look, it doesn't seem related to reserved ports as commented here #443 (reply in thread)

@srollinet
Copy link

I wrote a quick "test" to make it easily reproductible

public class ResourceReaperTest
{
    private readonly ITestOutputHelper _testOutputHelper;

    public ResourceReaperTest(ITestOutputHelper testOutputHelper)
    {
        _testOutputHelper = testOutputHelper;
    }

    [Fact]
    public async Task ResourceReaperStressTest()
    {
        var expectedPortRegex = new Regex("\"ExpectedPort\": (\\d+)");
        var hostPortRegex = new Regex("\"HostPort\": \"(\\d+)\"");
        
        var i = 0;
        while (i++ < 100)
        {
            try
            {
                await using var reaper = await ResourceReaper.GetAndStartNewAsync(Guid.NewGuid(), initTimeout: TimeSpan.FromSeconds(2));
                _testOutputHelper.WriteLine($"{i} : success");
            }
            catch (ResourceReaperException ex)
            {
                try
                {
                    var message = ex.Message;
                    var expectedPort = int.Parse(expectedPortRegex.Match(message).Groups[1].Value,
                        CultureInfo.InvariantCulture);
                    var hostPort = int.Parse(hostPortRegex.Matches(message)[1].Groups[1].Value,
                        CultureInfo.InvariantCulture);
                    _testOutputHelper.WriteLine($"{i} : fail - expectedPort: {expectedPort}, hostPort: {hostPort}");
                }
                catch (Exception)
                {
                    //NetworkSettings HostPort is missing usually
                    _testOutputHelper.WriteLine($"{i} : fail");
                }
            }
        }
    }
}

As you can see, it fails a lot!

1 : success
2 : fail - expectedPort: 49527, hostPort: 59414
3 : fail
4 : fail - expectedPort: 49529, hostPort: 59418
5 : fail
6 : success
7 : fail - expectedPort: 49532, hostPort: 59424
8 : fail
9 : fail
10 : fail
11 : fail
12 : fail - expectedPort: 49537, hostPort: 59438
13 : fail
14 : fail - expectedPort: 49539, hostPort: 59446
15 : fail - expectedPort: 49540, hostPort: 59449
16 : fail
17 : fail
18 : success
19 : fail
20 : fail
21 : fail
22 : fail
23 : fail
24 : fail - expectedPort: 49549, hostPort: 59470
25 : fail
26 : success
27 : fail - expectedPort: 49552, hostPort: 59478
28 : fail
29 : fail
30 : fail - expectedPort: 49555, hostPort: 59486
31 : fail

@HofmeisterAn
Copy link
Collaborator Author

HofmeisterAn commented Jun 15, 2022

I wrote a quick "test" to make it easily reproductible

That's nice - thanks. That should help to fix the issue finally. The ports don't match somehow.

@srollinet
Copy link

Also, I checked on a Linux computer. I have 100% success rate.

@HofmeisterAn
Copy link
Collaborator Author

HofmeisterAn commented Jun 15, 2022

Also, I checked on a Linux computer. I have 100% success rate.

100% success that it fails 😂?

I tried something similar in the past. I was not able to break it on my machine... Even now. I attached the log file (xUnit.log) from your test (Docker Desktop 4.9.0 (80466)).

Can you maybe add some more logging to (or debug into it):

public ushort GetMappedPublicPort(string privatePort)

It would be interesting how the container object looks like in your case.

@srollinet
Copy link

Your proposition here is a good idea #443 (reply in thread)

Or maybe a way to define it for the default reaper. For example in TestcontainersSettings

Also, I tested this naive approach and it works well in my case (but may probably not be suitable for everyone)

I replaced

by
.WithPortBinding(GetFreePort(), RyukPort)

    private static int GetFreePort()
    {
      var listener = new TcpListener(IPAddress.Loopback, 0);
      listener.Start();
      var port = ((IPEndPoint)listener.LocalEndpoint).Port;
      listener.Stop();
      return port;
    }

@HofmeisterAn
Copy link
Collaborator Author

HofmeisterAn commented Jun 15, 2022

It would be also interesting if something like this improves it:

diff --git a/src/DotNet.Testcontainers/Containers/ResourceReaper.cs b/src/DotNet.Testcontainers/Containers/ResourceReaper.cs
index a36bf88..31e3181 100644
--- a/src/DotNet.Testcontainers/Containers/ResourceReaper.cs
+++ b/src/DotNet.Testcontainers/Containers/ResourceReaper.cs
@@ -48,6 +48,7 @@ namespace DotNet.Testcontainers.Containers
         .WithExposedPort(RyukPort)
         .WithPortBinding(RyukPort, true)
         .WithBindMount("/var/run/docker.sock", "/var/run/docker.sock", AccessMode.ReadOnly)
+        .WithStartupCallback((resourceReaper, ct) => Task.Delay(TimeSpan.FromSeconds(5), ct))
         .Build();
 
       this.SessionId = sessionId;

Maybe the container field (value) is not up-to-date, and we return a value that's obsolete in the meantime. You need to remove the timeout in your test then.

Your proposition here is a good idea #443 (reply in thread)

I prefer to find the root cause. The resource reaper must run reliable.

@srollinet
Copy link

I will try to add the callback and check if it improves

And for the container state:

This one was working

[13:07:35 INF] Start Docker container c1fb6ed8b0fbdfe3d9824737b36234e5462661d80c4c1535ae622c8195074ae1
[13:07:36 INF] Container: {"ID":"c1fb6ed8b0fbdfe3d9824737b36234e5462661d80c4c1535ae622c8195074ae1","Names":["/testcontainers-ryuk-3d70d8c2-e26d-461e-92b3-ebb3104343b9"],"Image":"ghcr.io/psanetra/ryuk:2021.12.20","ImageID":"sha256:a0a36b674846145de03e245546b041e183f5a47e660fcba0d44f7c5392581f42","Command":"/app","Created":"2022-06-15T11:07:35.0000000Z","Ports":[{"IP":"0.0.0.0","PrivatePort":8080,"PublicPort":62084,"Type":"tcp","$type":"Port"}],"SizeRw":0,"SizeRootFs":0,"Labels":{"desktop.docker.io/mounts/0/Source":"/var/run/docker.sock","desktop.docker.io/mounts/0/SourceKind":"dockerSocketProxied","desktop.docker.io/mounts/0/Target":"/var/run/docker.sock","desktop.docker.io/ports/8080/tcp":"0.0.0.0:0","dotnet.testcontainers":"True","dotnet.testcontainers.resource-reaper-session":"00000000-0000-0000-0000-000000000000"},"State":"running","Status":"Up Less than a second","NetworkSettings":{"Networks":{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"301be24d1357a66d63cb26b3c9b0b640d072208f0d33c01410f4aec8a69f3855","EndpointID":"f01247950c5aef9643ff22e96c9eac152ba10e6eb89318455deafb001906c725","Gateway":"172.17.0.1","IPAddress":"172.17.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:03","DriverOpts":null,"$type":"EndpointSettings"}},"$type":"SummaryNetworkSettings"},"Mounts":[{"Type":"bind","Name":null,"Source":"/run/host-services/docker.proxy.sock","Destination":"/var/run/docker.sock","Driver":null,"Mode":"","RW":false,"Propagation":"rprivate","$type":"MountPoint"}],"$type":"ContainerListResponse"}

this one not

[13:07:36 INF] Start Docker container 2480b574b290358fe9b79a0b25582fb73e603ce6da079006965ec9b062599a67
[13:07:36 INF] Container: {"ID":"2480b574b290358fe9b79a0b25582fb73e603ce6da079006965ec9b062599a67","Names":["/testcontainers-ryuk-ec08b371-52df-45c3-b307-6ca696ebda1c"],"Image":"ghcr.io/psanetra/ryuk:2021.12.20","ImageID":"sha256:a0a36b674846145de03e245546b041e183f5a47e660fcba0d44f7c5392581f42","Command":"/app","Created":"2022-06-15T11:07:36.0000000Z","Ports":[{"IP":"127.0.0.1","PrivatePort":8080,"PublicPort":49580,"Type":"tcp","$type":"Port"}],"SizeRw":0,"SizeRootFs":0,"Labels":{"desktop.docker.io/mounts/0/Source":"/var/run/docker.sock","desktop.docker.io/mounts/0/SourceKind":"dockerSocketProxied","desktop.docker.io/mounts/0/Target":"/var/run/docker.sock","desktop.docker.io/ports/8080/tcp":"0.0.0.0:0","dotnet.testcontainers":"True","dotnet.testcontainers.resource-reaper-session":"00000000-0000-0000-0000-000000000000"},"State":"running","Status":"Up Less than a second","NetworkSettings":{"Networks":{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"301be24d1357a66d63cb26b3c9b0b640d072208f0d33c01410f4aec8a69f3855","EndpointID":"c07b36501df77bca293a6ee45d26041ac1bfeb5ecf8122420ba66160b8ed2d86","Gateway":"172.17.0.1","IPAddress":"172.17.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:03","DriverOpts":null,"$type":"EndpointSettings"}},"$type":"SummaryNetworkSettings"},"Mounts":[{"Type":"bind","Name":null,"Source":"/run/host-services/docker.proxy.sock","Destination":"/var/run/docker.sock","Driver":null,"Mode":"","RW":false,"Propagation":"rprivate","$type":"MountPoint"}],"$type":"ContainerListResponse"}
[13:07:40 ERR] Can not connect to resource reaper "ec08b371-52df-45c3-b307-6ca696ebda1c" at localhost:49580
System.Net.Sockets.SocketException (10061): No connection could be made because the target machine actively refused it.
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
--- End of stack trace from previous location ---
   at System.Net.Sockets.TcpClient.CompleteConnectAsync(Task task)
   at DotNet.Testcontainers.Containers.ResourceReaper.MaintainRyukConnection(TaskCompletionSource`1 ryukInitializedTaskSource, CancellationToken ct) in C:\Users\sro\Projects\OpenSource\testcontainers-dotnet\src\DotNet.Testcontainers\Containers\ResourceReaper.cs:line 274

What I have seen is that when the PublicPort is in the 60K range, it works. When it is in the 40K range it fails. (and docker ps reports a port that is always in the 60K range)

@srollinet
Copy link

You are right! :)
Delaying the startup, even with a 50ms callback make it more reliable (no failure with my test)

@HofmeisterAn
Copy link
Collaborator Author

As soon as I finished the left tasks regarding the repository transfer, I can add a fix. Even, I'm not sure what the fix will be 😀.

@HofmeisterAn HofmeisterAn self-assigned this Jun 15, 2022
@srollinet
Copy link

Great! Let me know if I can help.

@dshlezin
Copy link

Refreshing TestcontainersContainer.container before getting the mapped port, may also work.

diff --git a/src/Testcontainers/Containers/TestcontainersContainer.cs b/src/Testcontainers/Containers/TestcontainersContainer.cs
--- src/Testcontainers/Containers/TestcontainersContainer.cs
+++ src/Testcontainers/Containers/TestcontainersContainer.cs
@@ -145,8 +145,11 @@
     public ushort GetMappedPublicPort(string privatePort)
     {
       this.ThrowIfContainerHasNotBeenCreated();
 
+      this.container = await this.client.GetContainer(this.Id);
+        .ConfigureAwait(false);
+
       var mappedPort = this.container.Ports.FirstOrDefault(port => Convert.ToString(port.PrivatePort, CultureInfo.InvariantCulture).Equals(privatePort, StringComparison.Ordinal));
 
       if (mappedPort != null)
       {

@HofmeisterAn
Copy link
Collaborator Author

Refreshing TestcontainersContainer.container before getting the mapped port, may also work.

Yes, that will work too. It looks like that the state after the wait strategy is done is not final (UntilContainerIsRunning):

this.container = await this.client.GetContainer(id, ct)

Probably it's already enough to assign it afterwards (or return GetContainer).

@HofmeisterAn
Copy link
Collaborator Author

It's included in 2.0.1 🤞.

@pellared
Copy link
Contributor

@HofmeisterAn The problem remains on 2.0.1 😭

@HofmeisterAn
Copy link
Collaborator Author

Can you share the test (log)?

@pellared
Copy link
Contributor

17:39:11 [ERR] [xUnit.net 00:00:12.93]     IntegrationTests.MongoDB.MongoDbTests.SubmitsTraces [FAIL]
17:39:11 [DBG]   Failed IntegrationTests.MongoDB.MongoDbTests.SubmitsTraces [1 ms]
17:39:11 [DBG]   Error Message:
17:39:11 [DBG]    DotNet.Testcontainers.Containers.ResourceReaperException : Initialization has been cancelled.
17:39:11 [DBG] {
17:39:11 [DBG]   "ConnectionAttempts": 2,
17:39:11 [DBG]   "LocalNetworkInterfaces": {
17:39:11 [DBG]     "{FC32DD25-4738-4300-ABC5-2BD889516C11}": [
17:39:11 [DBG]       "fe80::58fb:7b12:3d51:263e%29",
17:39:11 [DBG]       "172.28.80.1"
17:39:11 [DBG]     ],
17:39:11 [DBG]     "{F67764C1-F13C-47A3-ADCD-BD722BBF893B}": [
17:39:11 [DBG]       "fe80::7040:c391:c5a:cd57%63",
17:39:11 [DBG]       "192.168.80.1"
17:39:11 [DBG]     ],
17:39:11 [DBG]     "{2ABF0BAC-ADED-4412-B367-9C12FAAA16F0}": [
17:39:11 [DBG]       "fe80::dd88:2f5c:9a9e:d090%7",
17:39:11 [DBG]       "169.254.208.144"
17:39:11 [DBG]     ],
17:39:11 [DBG]     "{B396A16F-3E6B-490E-8209-3F519D06A4E0}": [
17:39:11 [DBG]       "fe80::3427:4af3:e9a:3a53%17",
17:39:11 [DBG]       "169.254.58.83"
17:39:11 [DBG]     ],
17:39:11 [DBG]     "{3F22978D-F989-4B34-9EBE-711A6CA6196C}": [
17:39:11 [DBG]       "2a02:a31d:a042:4f80:1816:91de:ad5c:9c32",
17:39:11 [DBG]       "2a02:a31d:a042:4f80:a54c:d71c:ff4d:ca5b",
17:39:11 [DBG]       "fe80::1816:91de:ad5c:9c32%10",
17:39:11 [DBG]       "192.168.0.59"
17:39:11 [DBG]     ],
17:39:11 [DBG]     "{A7E7C157-85A5-41D8-B78C-272B82B59846}": [
17:39:11 [DBG]       "fe80::9c1a:4245:1f64:6fae%16",
17:39:11 [DBG]       "169.254.111.174"
17:39:11 [DBG]     ],
17:39:11 [DBG]     "{6D1FEDD8-8FD0-11EA-8351-806E6F6E6963}": [
17:39:11 [DBG]       "::1",
17:39:11 [DBG]       "127.0.0.1"
17:39:11 [DBG]     ],
17:39:11 [DBG]     "{ADC62029-D113-4D42-B8D1-DFF81F9A1E18}": [
17:39:11 [DBG]       "fe80::c83e:73f1:b29d:9782%15",
17:39:11 [DBG]       "172.26.16.1"
17:39:11 [DBG]     ],
17:39:11 [DBG]     "{6389991A-38F1-4699-A0AE-D12D3B07AD7E}": [
17:39:11 [DBG]       "fe80::c5d4:d1c4:b5be:641a%68",
17:39:11 [DBG]       "10.1.1.1"
17:39:11 [DBG]     ]
17:39:11 [DBG]   },
17:39:11 [DBG]   "ExpectedHost": "localhost",
17:39:11 [DBG]   "ExpectedPort": 49156,
17:39:11 [DBG]   "ContainerInspection": {
17:39:11 [DBG]     "ID": "875c660564263b59e35377fc134b35e3c0df28f6b5bdd33d282719889085755e",
17:39:11 [DBG]     "Created": "2022-06-22T15:38:23.9138401Z",
17:39:11 [DBG]     "Path": "/app",
17:39:11 [DBG]     "Args": [],
17:39:11 [DBG]     "State": {
17:39:11 [DBG]       "Status": "running",
17:39:11 [DBG]       "Running": true,
17:39:11 [DBG]       "Paused": false,
17:39:11 [DBG]       "Restarting": false,
17:39:11 [DBG]       "OOMKilled": false,
17:39:11 [DBG]       "Dead": false,
17:39:11 [DBG]       "Pid": 1831,
17:39:11 [DBG]       "ExitCode": 0,
17:39:11 [DBG]       "Error": "",
17:39:11 [DBG]       "StartedAt": "2022-06-22T15:38:24.4476622Z",
17:39:11 [DBG]       "FinishedAt": "0001-01-01T00:00:00Z",
17:39:11 [DBG]       "Health": null
17:39:11 [DBG]     },
17:39:11 [DBG]     "Image": "sha256:a0a36b674846145de03e245546b041e183f5a47e660fcba0d44f7c5392581f42",
17:39:11 [DBG]     "ResolvConfPath": "/var/lib/docker/containers/875c660564263b59e35377fc134b35e3c0df28f6b5bdd33d282719889085755e/resolv.conf",
17:39:11 [DBG]     "HostnamePath": "/var/lib/docker/containers/875c660564263b59e35377fc134b35e3c0df28f6b5bdd33d282719889085755e/hostname",
17:39:11 [DBG]     "HostsPath": "/var/lib/docker/containers/875c660564263b59e35377fc134b35e3c0df28f6b5bdd33d282719889085755e/hosts",
17:39:11 [DBG]     "LogPath": "/var/lib/docker/containers/875c660564263b59e35377fc134b35e3c0df28f6b5bdd33d282719889085755e/875c660564263b59e35377fc134b35e3c0df28f6b5bdd33d282719889085755e-json.log",
17:39:11 [DBG]     "Node": null,
17:39:11 [DBG]     "Name": "/testcontainers-ryuk-9b192cd9-e26c-4d1a-8304-ac4ad9850c92",
17:39:11 [DBG]     "RestartCount": 0,
17:39:11 [DBG]     "Driver": "overlay2",
17:39:11 [DBG]     "Platform": "linux",
17:39:11 [DBG]     "MountLabel": "",
17:39:11 [DBG]     "ProcessLabel": "",
17:39:11 [DBG]     "AppArmorProfile": "",
17:39:11 [DBG]     "ExecIDs": null,
17:39:11 [DBG]     "HostConfig": {
17:39:11 [DBG]       "Binds": null,
17:39:11 [DBG]       "ContainerIDFile": "",
17:39:11 [DBG]       "LogConfig": {
17:39:11 [DBG]         "Type": "json-file",
17:39:11 [DBG]         "Config": {}
17:39:11 [DBG]       },
17:39:11 [DBG]       "NetworkMode": "default",
17:39:11 [DBG]       "PortBindings": {
17:39:11 [DBG]         "8080/tcp": [
17:39:11 [DBG]           {
17:39:11 [DBG]             "HostIP": "",
17:39:11 [DBG]             "HostPort": "0"
17:39:11 [DBG]           }
17:39:11 [DBG]         ]
17:39:11 [DBG]       },
17:39:11 [DBG]       "RestartPolicy": {
17:39:11 [DBG]         "Name": 0,
17:39:11 [DBG]         "MaximumRetryCount": 0
17:39:11 [DBG]       },
17:39:11 [DBG]       "AutoRemove": true,
17:39:11 [DBG]       "VolumeDriver": "",
17:39:11 [DBG]       "VolumesFrom": null,
17:39:11 [DBG]       "CapAdd": null,
17:39:11 [DBG]       "CapDrop": null,
17:39:11 [DBG]       "CgroupnsMode": "host",
17:39:11 [DBG]       "DNS": null,
17:39:11 [DBG]       "DNSOptions": null,
17:39:11 [DBG]       "DNSSearch": null,
17:39:11 [DBG]       "ExtraHosts": null,
17:39:11 [DBG]       "GroupAdd": null,
17:39:11 [DBG]       "IpcMode": "private",
17:39:11 [DBG]       "Cgroup": "",
17:39:11 [DBG]       "Links": null,
17:39:11 [DBG]       "OomScoreAdj": 0,
17:39:11 [DBG]       "PidMode": "",
17:39:11 [DBG]       "Privileged": false,
17:39:11 [DBG]       "PublishAllPorts": false,
17:39:11 [DBG]       "ReadonlyRootfs": false,
17:39:11 [DBG]       "SecurityOpt": null,
17:39:11 [DBG]       "StorageOpt": null,
17:39:11 [DBG]       "Tmpfs": null,
17:39:11 [DBG]       "UTSMode": "",
17:39:11 [DBG]       "UsernsMode": "",
17:39:11 [DBG]       "ShmSize": 67108864,
17:39:11 [DBG]       "Sysctls": null,
17:39:11 [DBG]       "Runtime": "runc",
17:39:11 [DBG]       "ConsoleSize": [
17:39:11 [DBG]         0,
17:39:11 [DBG]         0
17:39:11 [DBG]       ],
17:39:11 [DBG]       "Isolation": "",
17:39:11 [DBG]       "CPUShares": 0,
17:39:11 [DBG]       "Memory": 0,
17:39:11 [DBG]       "NanoCPUs": 0,
17:39:11 [DBG]       "CgroupParent": "",
17:39:11 [DBG]       "BlkioWeight": 0,
17:39:11 [DBG]       "BlkioWeightDevice": null,
17:39:11 [DBG]       "BlkioDeviceReadBps": null,
17:39:11 [DBG]       "BlkioDeviceWriteBps": null,
17:39:11 [DBG]       "BlkioDeviceReadIOps": null,
17:39:11 [DBG]       "BlkioDeviceWriteIOps": null,
17:39:11 [DBG]       "CPUPeriod": 0,
17:39:11 [DBG]       "CPUQuota": 0,
17:39:11 [DBG]       "CPURealtimePeriod": 0,
17:39:11 [DBG]       "CPURealtimeRuntime": 0,
17:39:11 [DBG]       "CpusetCpus": "",
17:39:11 [DBG]       "CpusetMems": "",
17:39:11 [DBG]       "Devices": null,
17:39:11 [DBG]       "DeviceCgroupRules": null,
17:39:11 [DBG]       "DeviceRequests": null,
17:39:11 [DBG]       "KernelMemory": 0,
17:39:11 [DBG]       "KernelMemoryTCP": 0,
17:39:11 [DBG]       "MemoryReservation": 0,
17:39:11 [DBG]       "MemorySwap": 0,
17:39:11 [DBG]       "MemorySwappiness": null,
17:39:11 [DBG]       "OomKillDisable": false,
17:39:11 [DBG]       "PidsLimit": null,
17:39:11 [DBG]       "Ulimits": null,
17:39:11 [DBG]       "CPUCount": 0,
17:39:11 [DBG]       "CPUPercent": 0,
17:39:11 [DBG]       "IOMaximumIOps": 0,
17:39:11 [DBG]       "IOMaximumBandwidth": 0,
17:39:11 [DBG]       "Mounts": [
17:39:11 [DBG]         {
17:39:11 [DBG]           "Type": "bind",
17:39:11 [DBG]           "Source": "/var/run/docker.sock",
17:39:11 [DBG]           "Target": "/var/run/docker.sock",
17:39:11 [DBG]           "ReadOnly": true,
17:39:11 [DBG]           "Consistency": null,
17:39:11 [DBG]           "BindOptions": null,
17:39:11 [DBG]           "VolumeOptions": null,
17:39:11 [DBG]           "TmpfsOptions": null
17:39:11 [DBG]         }
17:39:11 [DBG]       ],
17:39:11 [DBG]       "MaskedPaths": [
17:39:11 [DBG]         "/proc/asound",
17:39:11 [DBG]         "/proc/acpi",
17:39:11 [DBG]         "/proc/kcore",
17:39:11 [DBG]         "/proc/keys",
17:39:11 [DBG]         "/proc/latency_stats",
17:39:11 [DBG]         "/proc/timer_list",
17:39:11 [DBG]         "/proc/timer_stats",
17:39:11 [DBG]         "/proc/sched_debug",
17:39:11 [DBG]         "/proc/scsi",
17:39:11 [DBG]         "/sys/firmware"
17:39:11 [DBG]       ],
17:39:11 [DBG]       "ReadonlyPaths": [
17:39:11 [DBG]         "/proc/bus",
17:39:11 [DBG]         "/proc/fs",
17:39:11 [DBG]         "/proc/irq",
17:39:11 [DBG]         "/proc/sys",
17:39:11 [DBG]         "/proc/sysrq-trigger"
17:39:11 [DBG]       ],
17:39:11 [DBG]       "Init": null
17:39:11 [DBG]     },
17:39:11 [DBG]     "GraphDriver": {
17:39:11 [DBG]       "Data": {
17:39:11 [DBG]         "LowerDir": "/var/lib/docker/overlay2/b883eea772b5bab2e1c6752b6ce9d679b7f9007fd5e8acac510713040d671f12-init/diff:/var/lib/docker/overlay2/ee006e573c315bce767762e3a9d15333636a4106e0388ded377c606ce0738906/diff:/var/lib/docker/overlay2/950b9770200e32db8ca318805421d101958fadbb55222d9ac4c94cb7c9d01923/diff:/var/lib/docker/overlay2/0bd9d0121100fed492d64f01420e63852fb40a55fff4c36847e7bdd6fb09abcb/diff",
17:39:11 [DBG]         "MergedDir": "/var/lib/docker/overlay2/b883eea772b5bab2e1c6752b6ce9d679b7f9007fd5e8acac510713040d671f12/merged",
17:39:11 [DBG]         "UpperDir": "/var/lib/docker/overlay2/b883eea772b5bab2e1c6752b6ce9d679b7f9007fd5e8acac510713040d671f12/diff",
17:39:11 [DBG]         "WorkDir": "/var/lib/docker/overlay2/b883eea772b5bab2e1c6752b6ce9d679b7f9007fd5e8acac510713040d671f12/work"
17:39:11 [DBG]       },
17:39:11 [DBG]       "Name": "overlay2"
17:39:11 [DBG]     },
17:39:11 [DBG]     "SizeRw": null,
17:39:11 [DBG]     "SizeRootFs": null,
17:39:11 [DBG]     "Mounts": [
17:39:11 [DBG]       {
17:39:11 [DBG]         "Type": "bind",
17:39:11 [DBG]         "Name": null,
17:39:11 [DBG]         "Source": "/var/run/docker.sock",
17:39:11 [DBG]         "Destination": "/var/run/docker.sock",
17:39:11 [DBG]         "Driver": null,
17:39:11 [DBG]         "Mode": "",
17:39:11 [DBG]         "RW": false,
17:39:11 [DBG]         "Propagation": "rprivate"
17:39:11 [DBG]       }
17:39:11 [DBG]     ],
17:39:11 [DBG]     "Config": {
17:39:11 [DBG]       "Hostname": "875c66056426",
17:39:11 [DBG]       "Domainname": "",
17:39:11 [DBG]       "User": "",
17:39:11 [DBG]       "AttachStdin": false,
17:39:11 [DBG]       "AttachStdout": false,
17:39:11 [DBG]       "AttachStderr": false,
17:39:11 [DBG]       "ExposedPorts": {
17:39:11 [DBG]         "8080/tcp": {}
17:39:11 [DBG]       },
17:39:11 [DBG]       "Tty": false,
17:39:11 [DBG]       "OpenStdin": false,
17:39:11 [DBG]       "StdinOnce": false,
17:39:11 [DBG]       "Env": [
17:39:11 [DBG]         "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
17:39:11 [DBG]       ],
17:39:11 [DBG]       "Cmd": [
17:39:11 [DBG]         "/app"
17:39:11 [DBG]       ],
17:39:11 [DBG]       "Healthcheck": null,
17:39:11 [DBG]       "ArgsEscaped": false,
17:39:11 [DBG]       "Image": "ghcr.io/psanetra/ryuk:2021.12.20",
17:39:11 [DBG]       "Volumes": null,
17:39:11 [DBG]       "WorkingDir": "",
17:39:11 [DBG]       "Entrypoint": null,
17:39:11 [DBG]       "NetworkDisabled": false,
17:39:11 [DBG]       "MacAddress": null,
17:39:11 [DBG]       "OnBuild": null,
17:39:11 [DBG]       "Labels": {
17:39:11 [DBG]         "testcontainers": "True",
17:39:11 [DBG]         "testcontainers.resource-reaper-session": "00000000-0000-0000-0000-000000000000"
17:39:11 [DBG]       },
17:39:11 [DBG]       "StopSignal": null,
17:39:11 [DBG]       "StopTimeout": null,
17:39:11 [DBG]       "Shell": null
17:39:11 [DBG]     },
17:39:11 [DBG]     "NetworkSettings": {
17:39:11 [DBG]       "Bridge": "",
17:39:11 [DBG]       "SandboxID": "cf85e72c4ab0aee414c8a8e5603a9a7292b742476b29f13390d32ac7ccd7cebf",
17:39:11 [DBG]       "HairpinMode": false,
17:39:11 [DBG]       "LinkLocalIPv6Address": "",
17:39:11 [DBG]       "LinkLocalIPv6PrefixLen": 0,
17:39:11 [DBG]       "Ports": {
17:39:11 [DBG]         "8080/tcp": [
17:39:11 [DBG]           {
17:39:11 [DBG]             "HostIP": "0.0.0.0",
17:39:11 [DBG]             "HostPort": "49156"
17:39:11 [DBG]           }
17:39:11 [DBG]         ]
17:39:11 [DBG]       },
17:39:11 [DBG]       "SandboxKey": "/var/run/docker/netns/cf85e72c4ab0",
17:39:11 [DBG]       "SecondaryIPAddresses": null,
17:39:11 [DBG]       "SecondaryIPv6Addresses": null,
17:39:11 [DBG]       "EndpointID": "9b100e6cc6dfc18b3569f2fad4a6014ef0017bc2179482be3651eba482a9e85d",
17:39:11 [DBG]       "Gateway": "172.17.0.1",
17:39:11 [DBG]       "GlobalIPv6Address": "",
17:39:11 [DBG]       "GlobalIPv6PrefixLen": 0,
17:39:11 [DBG]       "IPAddress": "172.17.0.2",
17:39:11 [DBG]       "IPPrefixLen": 16,
17:39:11 [DBG]       "IPv6Gateway": "",
17:39:11 [DBG]       "MacAddress": "02:42:ac:11:00:02",
17:39:11 [DBG]       "Networks": {
17:39:11 [DBG]         "bridge": {
17:39:11 [DBG]           "IPAMConfig": null,
17:39:11 [DBG]           "Links": null,
17:39:11 [DBG]           "Aliases": null,
17:39:11 [DBG]           "NetworkID": "6081adc825fcb9455b484ff32119875896156d0796813ab4ad349506b3b22108",
17:39:11 [DBG]           "EndpointID": "9b100e6cc6dfc18b3569f2fad4a6014ef0017bc2179482be3651eba482a9e85d",
17:39:11 [DBG]           "Gateway": "172.17.0.1",
17:39:11 [DBG]           "IPAddress": "172.17.0.2",
17:39:11 [DBG]           "IPPrefixLen": 16,
17:39:11 [DBG]           "IPv6Gateway": "",
17:39:11 [DBG]           "GlobalIPv6Address": "",
17:39:11 [DBG]           "GlobalIPv6PrefixLen": 0,
17:39:11 [DBG]           "MacAddress": "02:42:ac:11:00:02",
17:39:11 [DBG]           "DriverOpts": null
17:39:11 [DBG]         }
17:39:11 [DBG]       }
17:39:11 [DBG]     }
17:39:11 [DBG]   }
17:39:11 [DBG] }
17:39:11 [DBG]   Stack Trace:
17:39:11 [DBG]      at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartNewAsync(Guid sessionId, IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, String ryukImage, TimeSpan initTimeout, CancellationToken ct)
17:39:11 [DBG]    at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartNewAsync(Guid sessionId, IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, String ryukImage, TimeSpan initTimeout, CancellationToken ct)
17:39:11 [DBG]    at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartDefaultAsync(IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, CancellationToken ct)
17:39:11 [DBG]    at DotNet.Testcontainers.Clients.TestcontainersClient.RunAsync(ITestcontainersConfiguration configuration, CancellationToken ct)
17:39:11 [DBG]    at DotNet.Testcontainers.Containers.TestcontainersContainer.Create(CancellationToken ct)
17:39:11 [DBG]    at DotNet.Testcontainers.Containers.TestcontainersContainer.StartAsync(CancellationToken ct)
17:39:11 [DBG]    at IntegrationTests.MongoDB.MongoDbFixture.LaunchMongoContainerAsync(Int32 port) in C:\Users\rpajak\repos\opentelemetry-dotnet-instrumentation\test\integration-tests\IntegrationTests.MongoDB\MongoDbCollection.cs:line 71
17:39:11 [DBG]    at IntegrationTests.MongoDB.MongoDbFixture.InitializeAsync() in C:\Users\rpajak\repos\opentelemetry-dotnet-instrumentation\test\integration-tests\IntegrationTests.MongoDB\MongoDbCollection.cs:line 47

@HofmeisterAn
Copy link
Collaborator Author

HofmeisterAn commented Jun 22, 2022

This time the log file looks good. The resource reaper gets the right port (49156). I double-checked your sources (refactor-async-code) and noticed a few flaws. For instance:

var waitOS = EnvironmentTools.IsWindows()
    ? Wait.ForWindowsContainer()
    : Wait.ForUnixContainer();

Doesn't make sense. Even if you're running on Windows, it's still a Linux container. It should be Wait.ForUnixContainer().UntilPortIsAvailable(MongoDbPort) instead. Take a look into the MongoDB example in this repository.

Maybe you can figure out with ResourceReaper.GetAndStartNewAsync() why Testcontainers can't connect to the resource reaper on your machine.


Configure the logger and set the level to debug. That should help to identify the issue.

@pellared
Copy link
Contributor

Doesn't make sense.

You are totally correct. Unfortunately, it does not solve the issue 😉

Maybe you can figure out with ResourceReaper.GetAndStartNewAsync() why Testcontainers can't connect to the resource reaper on your machine.

I will try to look at it this week.

@pellared
Copy link
Contributor

pellared commented Jun 23, 2022

For all of my colleagues, everything is working fine. It only fails in my environment. I will look at it once I have a little more time. You can assign this issue to me if you want.

However, it may be possible to fix as I do not have any problems using docker, docker-compose, or https://github.com/ory/dockertest.

@srollinet
Copy link

I tested with the Develop branch. It seems it fixes the issue with port mismatches. But now I have the issue with the reserved ports in Windows 😢.

Note: I updated to Docker Desktop 4.9.1 (81317), and performed a factory reset

DotNet.Testcontainers.Containers.ResourceReaperException
Initialization has been cancelled.
{
  "ConnectionAttempts": 2,
  "LocalNetworkInterfaces": {
    "{65496C37-B14C-4240-80D1-D70919634587}": [
      "fe80::e000:be57:78ca:9016%12",
      "169.254.144.22"
    ],
    "{114419F6-1B1E-4AA0-B45B-6A9DCC8919DB}": [
      "fe80::a9e7:379:9b0a:92e9%3",
      "169.254.146.233"
    ],
    "{468F976F-62B8-4EDA-9810-04434F48CEAC}": [
      "fe80::953c:37e:7a49:3c2b%8",
      "169.254.60.43"
    ],
    "{58CD309E-0D76-4B61-8A53-7FEBB0B3C27F}": [
      "fe80::1cae:a794:8a6e:d20b%77",
      "172.24.16.1"
    ],
    "{9DBC6CA6-9146-4ECA-B573-3F5C6788ACED}": [
      "fe80::ad9f:cf38:fa12:a656%22",
      "192.168.50.140"
    ],
    "{407C0181-4D1D-4932-85F1-DB55E0DBA6EF}": [
      "fe80::617d:b3c3:63b8:ad8f%7",
      "169.254.173.143"
    ],
    "{8CF48E01-8038-460B-9049-EFDAA77BDDA0}": [
      "fe80::6997:43fe:9fe5:8803%20",
      "169.254.136.3"
    ],
    "{67CA33D7-7E83-4B6E-8448-52B4718C2066}": [
      "fe80::4ce8:fc74:d188:bf97%14",
      "169.254.191.151"
    ],
    "{C96BABE4-121E-4D6D-8A64-26476F2888DB}": [
      "fe80::f18b:cd26:1ca5:146c%27",
      "169.254.20.108"
    ],
    "{35F0BF58-A867-11EB-86E8-806E6F6E6963}": [
      "::1",
      "127.0.0.1"
    ],
    "{35AC8699-8C28-41F8-94B9-8980F0BD7C8C}": [
      "fe80::e16e:4bfa:c172:7f27%6",
      "169.254.127.39"
    ],
    "{B9EBE5DB-E763-453A-842F-52CD117B5683}": [
      "fe80::5d05:1cfb:4f7a:41ea%90",
      "172.28.96.1"
    ]
  },
  "ExpectedHost": "localhost",
  "ExpectedPort": 49406,
  "ContainerInspection": {
    "ID": "e552fdd851b2ac91ad092fa0b94c664046d14711452bdf64bde887b3eed11b66",
    "Created": "2022-06-24T16:33:44.6260413Z",
    "Path": "/app",
    "Args": [],
    "State": {
      "Status": "running",
      "Running": true,
      "Paused": false,
      "Restarting": false,
      "OOMKilled": false,
      "Dead": false,
      "Pid": 28976,
      "ExitCode": 0,
      "Error": "",
      "StartedAt": "2022-06-24T16:33:45.041670767Z",
      "FinishedAt": "0001-01-01T00:00:00Z",
      "Health": null
    },
    "Image": "sha256:a0a36b674846145de03e245546b041e183f5a47e660fcba0d44f7c5392581f42",
    "ResolvConfPath": "/var/lib/docker/containers/e552fdd851b2ac91ad092fa0b94c664046d14711452bdf64bde887b3eed11b66/resolv.conf",
    "HostnamePath": "/var/lib/docker/containers/e552fdd851b2ac91ad092fa0b94c664046d14711452bdf64bde887b3eed11b66/hostname",
    "HostsPath": "/var/lib/docker/containers/e552fdd851b2ac91ad092fa0b94c664046d14711452bdf64bde887b3eed11b66/hosts",
    "LogPath": "/var/lib/docker/containers/e552fdd851b2ac91ad092fa0b94c664046d14711452bdf64bde887b3eed11b66/e552fdd851b2ac91ad092fa0b94c664046d14711452bdf64bde887b3eed11b66-json.log",
    "Node": null,
    "Name": "/testcontainers-ryuk-cc041806-7ddc-46cd-82b0-150ba41547ea",
    "RestartCount": 0,
    "Driver": "overlay2",
    "Platform": "linux",
    "MountLabel": "",
    "ProcessLabel": "",
    "AppArmorProfile": "",
    "ExecIDs": null,
    "HostConfig": {
      "Binds": null,
      "ContainerIDFile": "",
      "LogConfig": {
        "Type": "json-file",
        "Config": {}
      },
      "NetworkMode": "default",
      "PortBindings": {
        "8080/tcp": [
          {
            "HostIP": "",
            "HostPort": "0"
          }
        ]
      },
      "RestartPolicy": {
        "Name": 0,
        "MaximumRetryCount": 0
      },
      "AutoRemove": true,
      "VolumeDriver": "",
      "VolumesFrom": null,
      "CapAdd": null,
      "CapDrop": null,
      "CgroupnsMode": "host",
      "DNS": null,
      "DNSOptions": null,
      "DNSSearch": null,
      "ExtraHosts": null,
      "GroupAdd": null,
      "IpcMode": "private",
      "Cgroup": "",
      "Links": null,
      "OomScoreAdj": 0,
      "PidMode": "",
      "Privileged": false,
      "PublishAllPorts": false,
      "ReadonlyRootfs": false,
      "SecurityOpt": null,
      "StorageOpt": null,
      "Tmpfs": null,
      "UTSMode": "",
      "UsernsMode": "",
      "ShmSize": 67108864,
      "Sysctls": null,
      "Runtime": "runc",
      "ConsoleSize": [
        0,
        0
      ],
      "Isolation": "",
      "CPUShares": 0,
      "Memory": 0,
      "NanoCPUs": 0,
      "CgroupParent": "",
      "BlkioWeight": 0,
      "BlkioWeightDevice": null,
      "BlkioDeviceReadBps": null,
      "BlkioDeviceWriteBps": null,
      "BlkioDeviceReadIOps": null,
      "BlkioDeviceWriteIOps": null,
      "CPUPeriod": 0,
      "CPUQuota": 0,
      "CPURealtimePeriod": 0,
      "CPURealtimeRuntime": 0,
      "CpusetCpus": "",
      "CpusetMems": "",
      "Devices": null,
      "DeviceCgroupRules": null,
      "DeviceRequests": null,
      "KernelMemory": 0,
      "KernelMemoryTCP": 0,
      "MemoryReservation": 0,
      "MemorySwap": 0,
      "MemorySwappiness": null,
      "OomKillDisable": false,
      "PidsLimit": null,
      "Ulimits": null,
      "CPUCount": 0,
      "CPUPercent": 0,
      "IOMaximumIOps": 0,
      "IOMaximumBandwidth": 0,
      "Mounts": [
        {
          "Type": "bind",
          "Source": "/var/run/docker.sock",
          "Target": "/var/run/docker.sock",
          "ReadOnly": true,
          "Consistency": null,
          "BindOptions": null,
          "VolumeOptions": null,
          "TmpfsOptions": null
        }
      ],
      "MaskedPaths": [
        "/proc/asound",
        "/proc/acpi",
        "/proc/kcore",
        "/proc/keys",
        "/proc/latency_stats",
        "/proc/timer_list",
        "/proc/timer_stats",
        "/proc/sched_debug",
        "/proc/scsi",
        "/sys/firmware"
      ],
      "ReadonlyPaths": [
        "/proc/bus",
        "/proc/fs",
        "/proc/irq",
        "/proc/sys",
        "/proc/sysrq-trigger"
      ],
      "Init": null
    },
    "GraphDriver": {
      "Data": {
        "LowerDir": "/var/lib/docker/overlay2/7d76e33e3a437733e2c20729589f2cff284c2b2d40c2759e41b2761b8dfd37bc-init/diff:/var/lib/docker/overlay2/393f10f7f91f006a1f1b59c9f798e5acf6ed957348d1dd7991627262198c2078/diff:/var/lib/docker/overlay2/50b689cb03766fbd488fe0ed1013038f0779344a277c4ec980bd6f549203aa8c/diff:/var/lib/docker/overlay2/aee892719acb15ef6ddfdb591cb78f75ad05b6c5227b1c1a52837040dda342f9/diff",
        "MergedDir": "/var/lib/docker/overlay2/7d76e33e3a437733e2c20729589f2cff284c2b2d40c2759e41b2761b8dfd37bc/merged",
        "UpperDir": "/var/lib/docker/overlay2/7d76e33e3a437733e2c20729589f2cff284c2b2d40c2759e41b2761b8dfd37bc/diff",
        "WorkDir": "/var/lib/docker/overlay2/7d76e33e3a437733e2c20729589f2cff284c2b2d40c2759e41b2761b8dfd37bc/work"
      },
      "Name": "overlay2"
    },
    "SizeRw": null,
    "SizeRootFs": null,
    "Mounts": [
      {
        "Type": "bind",
        "Name": null,
        "Source": "/var/run/docker.sock",
        "Destination": "/var/run/docker.sock",
        "Driver": null,
        "Mode": "",
        "RW": false,
        "Propagation": "rprivate"
      }
    ],
    "Config": {
      "Hostname": "e552fdd851b2",
      "Domainname": "",
      "User": "",
      "AttachStdin": false,
      "AttachStdout": false,
      "AttachStderr": false,
      "ExposedPorts": {
        "8080/tcp": {}
      },
      "Tty": false,
      "OpenStdin": false,
      "StdinOnce": false,
      "Env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
      ],
      "Cmd": [
        "/app"
      ],
      "Healthcheck": null,
      "ArgsEscaped": false,
      "Image": "ghcr.io/psanetra/ryuk:2021.12.20",
      "Volumes": null,
      "WorkingDir": "",
      "Entrypoint": null,
      "NetworkDisabled": false,
      "MacAddress": null,
      "OnBuild": null,
      "Labels": {
        "testcontainers": "True",
        "testcontainers.resource-reaper-session": "00000000-0000-0000-0000-000000000000"
      },
      "StopSignal": null,
      "StopTimeout": null,
      "Shell": null
    },
    "NetworkSettings": {
      "Bridge": "",
      "SandboxID": "8a437c8f0a6348a855d395af2e3eac1227efc1c1dc34d1d8ad935a1490905ace",
      "HairpinMode": false,
      "LinkLocalIPv6Address": "",
      "LinkLocalIPv6PrefixLen": 0,
      "Ports": {
        "8080/tcp": [
          {
            "HostIP": "0.0.0.0",
            "HostPort": "49406"
          }
        ]
      },
      "SandboxKey": "/var/run/docker/netns/8a437c8f0a63",
      "SecondaryIPAddresses": null,
      "SecondaryIPv6Addresses": null,
      "EndpointID": "1e6cf9cb13b34bd2505ed33d3f93ba3569b124944cc93f661a7055606d19cb63",
      "Gateway": "172.17.0.1",
      "GlobalIPv6Address": "",
      "GlobalIPv6PrefixLen": 0,
      "IPAddress": "172.17.0.2",
      "IPPrefixLen": 16,
      "IPv6Gateway": "",
      "MacAddress": "02:42:ac:11:00:02",
      "Networks": {
        "bridge": {
          "IPAMConfig": null,
          "Links": null,
          "Aliases": null,
          "NetworkID": "b9cc49a1eea84fbe3582cb0c9c02ea7fddaf122c8be82e1a253445ae789c0576",
          "EndpointID": "1e6cf9cb13b34bd2505ed33d3f93ba3569b124944cc93f661a7055606d19cb63",
          "Gateway": "172.17.0.1",
          "IPAddress": "172.17.0.2",
          "IPPrefixLen": 16,
          "IPv6Gateway": "",
          "GlobalIPv6Address": "",
          "GlobalIPv6PrefixLen": 0,
          "MacAddress": "02:42:ac:11:00:02",
          "DriverOpts": null
        }
      }
    }
  }
}
   at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartNewAsync(Guid sessionId, IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, String ryukImage, TimeSpan initTimeout, CancellationToken ct) in C:\Users\sro\Projects\OpenSource\testcontainers-dotnet\src\Testcontainers\Containers\ResourceReaper.cs:line 172
   at DotNet.Testcontainers.Containers.ResourceReaper.GetAndStartNewAsync(Guid sessionId, IDockerEndpointAuthenticationConfiguration dockerEndpointAuthConfig, String ryukImage, TimeSpan initTimeout, CancellationToken ct) in C:\Users\sro\Projects\OpenSource\testcontainers-dotnet\src\Testcontainers\Containers\ResourceReaper.cs:line 183
   at DotNet.Testcontainers.ResourceReaper.Tests.StressTest.StartReaper(Int32 i) in C:\Users\sro\Projects\OpenSource\testcontainers-dotnet\tests\Testcontainers.ResourceReaper.Tests\StressTest.cs:line 38
   at DotNet.Testcontainers.ResourceReaper.Tests.StressTest.ResourceReaperStressTest() in C:\Users\sro\Projects\OpenSource\testcontainers-dotnet\tests\Testcontainers.ResourceReaper.Tests\StressTest.cs:line 30
   at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass48_1.<<InvokeTestMethodAsync>b__1>d.MoveNext() in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\Runners\TestInvoker.cs:line 264
--- End of stack trace from previous location ---
   at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\ExecutionTimer.cs:line 48
   at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in C:\Dev\xunit\xunit\src\xunit.core\Sdk\ExceptionAggregator.cs:line 90


0 : fail - expectedPort: 49406, hostPort: 49406

In Powershell : netsh interface ipv4 show excludedportrange protocol=tcp

Protocol tcp Port Exclusion Ranges

Start Port    End Port
----------    --------
     49398       49497
     49498       49597
     49668       49767
     49868       49967
     50000       50059     *
     50060       50159
     50160       50259
     59036       59135
     59136       59235
     59341       59440
     59546       59645
     60076       60175
     60176       60275
     60276       60375
     60376       60475
     60476       60575
     60576       60675
     60676       60775
     60776       60875
     60876       60975
     60976       61075

* - Administered port exclusions.

As you can see, the chosen port is within the first excluded range. This is an issue with Docker for Windows and you probably cannot do anything.
docker/for-win#11584
docker/for-win#3171

@pellared If you still have failures, maybe check the port exclusion as well

@HofmeisterAn
Copy link
Collaborator Author

Thanks for the feedback. At least we were able to fix the mismatching ports. I think we can add something like this as a workaround? I hope this won't produce race-conditions. @srollinet , you already tried something like this, right?

diff --git a/src/Testcontainers/Containers/ResourceReaper.cs b/src/Testcontainers/Containers/ResourceReaper.cs
index 48b0da5..27baae6 100644
--- a/src/Testcontainers/Containers/ResourceReaper.cs
+++ b/src/Testcontainers/Containers/ResourceReaper.cs
@@ -2,6 +2,7 @@ namespace DotNet.Testcontainers.Containers
 {
   using System;
   using System.IO;
+  using System.Net;
   using System.Net.Sockets;
   using System.Text;
   using System.Threading;
@@ -44,7 +45,7 @@ namespace DotNet.Testcontainers.Containers
         .WithAutoRemove(true)
         .WithCleanUp(false)
         .WithExposedPort(RyukPort)
-        .WithPortBinding(RyukPort, true)
+        .WithPortBinding(RyukPort, GetNextTcpPort())
         .WithBindMount("/var/run/docker.sock", "/var/run/docker.sock", AccessMode.ReadOnly)
         .Build();
 
@@ -378,5 +379,14 @@ namespace DotNet.Testcontainers.Containers
         ryukInitializedTaskSource.SetException(new ResourceReaperException("Initialization failed.", this.diagnostics));
       }
     }
+
+    private static ushort GetNextTcpPort()
+    {
+      using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+      {
+        socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+        return (ushort)((IPEndPoint)socket.LocalEndPoint).Port;
+      }
+    }
   }
 }

@srollinet
Copy link

@HofmeisterAn Yes, this is the method I used until now with https://github.com/isen-ng/testcontainers-dotnet, and I also tested it with your lib.
I am testing it right now with my "stress test" with 10'000 iterations and concurrent container creations. So far, so good! it failed after a while listen tcp4 0.0.0.0:50270: bind: address already in use I will try again with non-concurrent creations

But you have to inverse the parameters order 😉 .WithPortBinding(GetNextTcpPort(), RyukPort)

Maybe you could add something to opt in/out this workaround? or to use it only on Windows?

@srollinet
Copy link

Even sequentially, it fails sometimes, but not very frequently... But in practice I never had any problem with this method, on multiple projects, whereas I had frequent failures with the port exclusion issue and the mismatching ports.

Unfortunately, I think there is no magic solution that will work 100% for everyone

@HofmeisterAn
Copy link
Collaborator Author

Published in 2.1.0-beta.2561986470. I'll create another issue tomorrow to track the Docker for Windows issues.

@pellared
Copy link
Contributor

Published in 2.1.0-beta.2561986470

Using 2.1.0-beta.2561986470 helps 👍

Even sequentially, it fails sometimes, but not very frequently

@srollinet If it occurs very problematic, you can consider making some thread-safe dictionary to "reserve" the ports returned by

using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return (ushort)((IPEndPoint)socket.LocalEndPoint).Port;
}
and "release" them once the docker container is disposed. Of course, it may still race with any other application (and even code in the same process) that will try to bind a new TCP port.

@HofmeisterAn
Copy link
Collaborator Author

@srollinet If it occurs very problematic, you can consider making some thread-safe dictionary to "reserve" the ports returned by

I was thinking about a similar idea. You could return a port from your own excluded port range, but dunno if you run into the same issue again if you explicit assign an excluded port 😅.

@pellared
Copy link
Contributor

dunno if you run into the same issue again if you explicit assign an excluded port

It could. Therefore, it would be better if the caller just "retry" if ResourceReaperException is thrown.

@HofmeisterAn
Copy link
Collaborator Author

It could.

Did you try it? I prefer fixing the root cause instead of adding another workaround for Docker Desktop for Windows.

@pellared
Copy link
Contributor

pellared commented Jun 27, 2022

I do not say "explicitly assign an excluded port" but some other thread may already have concurrently reserved the same port in parallel. See:

Even sequentially, it fails sometimes, but not very frequently... But in practice I never had any problem with this method, on multiple projects, whereas I had frequent failures with the port exclusion issue and the mismatching ports.

Unfortunately, I think there is no magic solution that will work 100% for everyone

You are just trying to get a free port but someone can already take it in the meanwhile. For instance we are using similar approach in our integration tests and it is possible to have a race if they would be run in parallel.

I prefer fixing the root cause instead of adding another workaround for Docker Desktop for Windows.

Still, I do not say we should do any more workarounds in Testcontainers. The caller can always "retry" running a new container and there is a high chance that the new port will not be occupied. Do you know if other Testcontainer implementations (e.g. in Java) have the same issue?

@srollinet
Copy link

srollinet commented Jun 27, 2022

Even sequentially, it fails sometimes, but not very frequently

@srollinet If it occurs very problematic, you can consider making some thread-safe dictionary to "reserve" the ports returned by

using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return (ushort)((IPEndPoint)socket.LocalEndPoint).Port;
}

and "release" them once the docker container is disposed. Of course, it may still race with any other application (and even code in the same process) that will try to bind a new TCP port.

@pellared It was just a stress test to make the problem appear quickly. So I don't have real issues about that. But thanks for the tip 😉

@HofmeisterAn
Copy link
Collaborator Author

You are just trying to get a free port but someone can already take it in the meanwhile. For instance we are using similar approach in our integration tests and it is possible to have a race if they would be run in parallel.

Yes, it's not just the tests that may run into a race condition. Other processes can use the port in the meantime too.

Do you know if other Testcontainer implementations (e.g. in Java) have the same issue?

I'll ask. Let's see how others deal with it.

@swybraniec
Copy link

Not sure if this helps but I also encountered this problem. I investigated and found that I had the following, potential problems:

  • WSL was enabled but I had two versions of the Ubuntu distro installed.
  • I had installed Rancher desktop and set Docker as the container platform, but had previously installed Podman.
  • Kubernetes was installed as part of Rancher desktop

I solved the problem by:

  • Uninstalling Rancher desktop
  • Uninstalling both Ubuntu distros
  • Uninstalling Podman
  • Reinstalling WSL, but disassociating it with Ubuntu, to allow me to redownload it (it thought it was installed, but it wasn't)
  • Reinstalling Rancher desktop and setting docker as the container engine.

HTH!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

8 participants