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

HostPortWaitStrategy strategy does not work for localhost bound ports #686

Open
jalaziz opened this issue Dec 7, 2023 · 4 comments
Open
Labels
triage Investigation required

Comments

@jalaziz
Copy link
Contributor

jalaziz commented Dec 7, 2023

Expected Behaviour

When launching a container with a port bound to localhost, the wait strategy should work.

Actual Behaviour

The HostPortWaitStrategy fails to recognize the open port and eventually times out. This issue seems to only occur on Linux machines. MacOS works fine.

Testcontainer Logs

Error: Port 4566 not bound after 60000ms

   at globalSetup.ts:38

  36 |   console.log(`Starting docker compose environment...`);
  37 |   const composeFilePath = path.resolve(__dirname, '../');
> 38 |   const environment = await new DockerComposeEnvironment(
     |                       ^
  39 |     composeFilePath,
  [40](https://github.com/bastionplatforms/monorepo/actions/runs/7124569757/job/19400552961?pr=553#step:12:41) |     'docker-compose.yml',
  [41](https://github.com/bastionplatforms/monorepo/actions/runs/7124569757/job/19400552961?pr=553#step:12:42) |   )

    at /home/runner/work/monorepo/monorepo/node_modules/testcontainers/src/wait-strategies/host-port-wait-strategy.ts:52:15
    at IntervalRetry.retryUntil (/home/runner/work/monorepo/monorepo/node_modules/testcontainers/src/common/retry.ts:49:16)
    at HostPortWaitStrategy.waitForPort (/home/runner/work/monorepo/monorepo/node_modules/testcontainers/src/wait-strategies/host-port-wait-strategy.ts:[46](https://github.com/bastionplatforms/monorepo/actions/runs/7124569757/job/19400552961?pr=553#step:12:47):5)
    at HostPortWaitStrategy.waitForHostPorts (/home/runner/work/monorepo/monorepo/node_modules/testcontainers/src/wait-strategies/host-port-wait-strategy.ts:27:7)
    at HostPortWaitStrategy.waitUntilReady (/home/runner/work/monorepo/monorepo/node_modules/testcontainers/src/wait-strategies/host-port-wait-strategy.ts:14:5)
    at waitForContainer (/home/runner/work/monorepo/monorepo/node_modules/testcontainers/src/wait-strategies/wait-for-container.ts:17:5)
    at /home/runner/work/monorepo/monorepo/node_modules/testcontainers/src/docker-compose-environment/docker-compose-environment.ts:1[50](https://github.com/bastionplatforms/monorepo/actions/runs/7124569757/job/19400552961?pr=553#step:12:51):13
    at DockerComposeEnvironment.up (/home/runner/work/monorepo/monorepo/node_modules/testcontainers/src/docker-compose-environment/docker-compose-environment.ts:128:7)
    at globalSetup (/home/runner/work/monorepo/monorepo/e2e-tests/globalSetup.ts:38:23)

Steps to Reproduce

  1. Setup a GitHub Actions workflow to launch a compose project through testcontainers.
  2. The compose file:
    services:
      localstack:
        image: localstack/localstack
        ports:
          - "127.0.0.1:4566:4566"            # LocalStack Gateway
        environment:
          - DEBUG=${DEBUG-}
          - DOCKER_HOST=unix:///var/run/docker.sock
          - DYNAMODB_SHARE_DB=1
          - DYNAMODB_IN_MEMORY=1
        healthcheck:
          test: "curl --silent --fail localstack:4566/_localstack/health"
          interval: 1s
          retries: 5
          start_period: 20s
          timeout: 10s
        volumes:
          - "./.localstack/init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh"  # ready hook
          - "./.localstack-volume:/var/lib/localstack"
          - "/var/run/docker.sock:/var/run/docker.sock"
    
  3. Run 'await new DockerComposeEnvironment(composeFilePath, 'docker-compose.yml').up();`
  4. See error...

Environment Information

  • Operating System: Ubuntu 22.04
  • Docker Version: 24.0.7
  • Node version: 18.18.2
  • Testcontainers version: 10.3.2
@cristianrgreco cristianrgreco added the triage Investigation required label Dec 8, 2023
@sneko
Copy link

sneko commented Feb 20, 2024

@jalaziz @cristianrgreco any solution for this?

I was in a previous project using:

  const environment = await new DockerComposeEnvironment(composeFilePath, composeFile)
    .withEnvironment({
      ...
    })
    .withWaitStrategy(serviceName, Wait.forHealthCheck())
    .up([serviceName]);

But now for a new project with lot of dependencies updated (ESM modules, different Node version...), it times out saying Port 52670 not bound after 60000ms (it seems to come from

private async waitForPort(container: Dockerode.Container, port: number, portCheck: PortCheck): Promise<void> {
await new IntervalRetry<boolean, Error>(100).retryUntil(
() => portCheck.isBound(port),
(isBound) => isBound,
() => {
const message = `Port ${port} not bound after ${this.startupTimeout}ms`;
log.error(message, { containerId: container.id });
throw new Error(message);
},
this.startupTimeout
);
}
}
).

Note I tried to use testcontainers with the latest version and also v9.6.0 that is on the other project.

Thank you,

EDIT: I'm on a MacOS Intel

EDIT2: I did other attempts to run the test without ESM settings into my Jest setup, but it's the same error. It's so weird...

EDIT3: On my side I'm using the strategy Wait.forHealthCheck() for both the working and failing projects

@sneko
Copy link

sneko commented Feb 20, 2024

After spending some time on it, it seems my old way of bindings ports to make them random on the list:

    ports:
      - '127.0.0.1::5432'

is not working for any reason on the new project.

Switching to:

    ports:
      - '5432'

Don't tell why... the old way is working in a project with direct dependencies versions aligned (also I don't remember why I had to use the 127.0.0.1 at that time). Hope it helps 👍

@jalaziz
Copy link
Contributor Author

jalaziz commented Feb 21, 2024

@jalaziz @cristianrgreco any solution for this?

Unfortunately no solution. I've switched to Wait.forHealthCheck() with custom healtchecks for the time being.

@t3hmrman
Copy link

I think I just ran into this -- except I can't actually get the custom health check to pass either, even with test: ["CMD-SHELL", "exit 0"] it just fails for however long.

It would be nice if there wasn't a default healthcheck (or it could be disbaled) that tried to use the ports -- it's helpful but a way to disable that logic would be nice

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

No branches or pull requests

4 participants