Skip to content

Port mapping for ipv4 & ipv6 can cause different ports to be mapped and getMappedPort function will return wrong portΒ #750

@vsamofal

Description

@vsamofal

Expected Behaviour

I want to get a predictable port number and host,

the problem seems to be in this file - https://github.com/testcontainers/testcontainers-node/blob/main/packages/testcontainers/src/utils/bound-ports.ts

method - resolveHostPortBinding
line - return hostPortBindings[0].hostPort;

Actual Behaviour

We have tests that are running in parallel and it was quite hard to identify that issue, because locally on mac os everything is fine, but on latest ubuntu the problem auto assigning port appear

testcontainers/testcontainers-dotnet#825 - same issue for .net

So what happening:

  1. Starting a redis container (doesn't matter which one, it just an example)
  2. withExposedPorts(6389) - let docker to auto assign host port
  3. calling getMappedPort function -> may return ipv4 or ipv6 port, depends on your luck

Testcontainer Logs
...

Steps to Reproduce

  1. In this environment ubuntu 22
  2. With this config.
  3. Run '...'
  const container = await new GenericContainer(
    `${options.imageName}:${options.imageTag}`,
  )
    .withExposedPorts(6379)
    .start();

  // eslint-disable-next-line no-console
  console.timeEnd(`start redis`);

  const redisConfig = {
    port: container.getMappedPort(6379),
    host: 'localhost',
  } satisfies RedisStartedConfig;
  1. Run docker ps, and see that there are 2 ports actually

Environment Information

  • Operating System: ubuntu
  • Docker Version: 24+
  • Node version: 20+
  • Testcontainers version: 10.8.1

we temporary fixed it by retrieving ipv4 port from the docker inspect info:

import { StartedTestContainer } from 'testcontainers/build/test-container';

export function retrievePortFromBinding(
  container: StartedTestContainer,
  sourcePort: number,
): number {
  return Number.parseInt(
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    (container as never as any).inspectResult.NetworkSettings.Ports[
      `${sourcePort}/tcp`
    ].find((p: { HostIp: string; HostPort: string }) => p.HostIp === '0.0.0.0')
      .HostPort,
  );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageInvestigation required

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions