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

Cannot define container hostname #883

Open
kyzooghost opened this issue Dec 16, 2024 · 6 comments
Open

Cannot define container hostname #883

kyzooghost opened this issue Dec 16, 2024 · 6 comments
Labels
triage Investigation required

Comments

@kyzooghost
Copy link

kyzooghost commented Dec 16, 2024

I would like to define the container hostname. This is available in the .NET and Java TestContainers frameworks, but not in the NodeJS framework

I understand this is a duplicate of #865 , however on reading the discussion there it is not clear to me what the rationale is for closing that issue :(

My specific use case is that I would like to set up a PostgreSQL container for integration testing in a TypeScript backend. Currently the container.getHost() method resolves to localhost and I am not clear how to change this for the PostgreSQL container. This is especially an issue when I need to orchestrate multiple TestContainers for the E2E tests, and the TypeScript backend app itself is using the localhost:... namespace already.

@kyzooghost
Copy link
Author

kyzooghost commented Dec 17, 2024

To give some further clarification on why customizing the container hostname is needed:

  • To configure a DbConnection for an ORM framework (Entity Framework, TypeORM), the host is a required parameter
  • It is ok to use localhost for the DbConnection host on my local machine - The ORM framework is running on the Docker host (my local machine), and the PostgreSQL container is running with an exposed port:
    • ORM framework will seek to connect to localhost: port
    • Docker host (my local machine) will receive this request
    • Because of port binding, Docker host can route this connection request to the PostgreSQL container
  • However if I run this in a CI pipeline or pod, then localhost may not be an available hostname on the Docker host (not my local machine anymore). Then the ORM framework will fail to connect to the PostgreSQL container running on TestContainers, and we have no available static config to facilitate the DbConnection

@cristianrgreco
Copy link
Collaborator

cristianrgreco commented Jan 8, 2025

Currently the container.getHost() method resolves to localhost and I am not clear how to change this for the PostgreSQL container

However if I run this in a CI pipeline or pod, then localhost may not be an available hostname on the Docker host (not my local machine anymore)

There is a lot of logic that testcontainers does when resolving the host, it doesn't always set it to localhost: https://github.com/testcontainers/testcontainers-node/blob/824cd8dbac0615ae00a83d82e8625a108b885ecb/packages/testcontainers/src/container-runtime/utils/resolve-host.ts

Perhaps I'm misunderstanding something here, but unless there's a bug in that function, setting the host to anything other than what is returned there would be incorrect.

Regardless, there is already support for a TESTCONTAINERS_HOST_OVERRIDE env var, is it not enough?

If there is some more complex networking requirement, you can create your own network via Testcontainers and set network aliases for each container accordingly.

@kyzooghost
Copy link
Author

While making a PR for this issue, I've come to realise that getHost() obtains the hostname of the host (the machine running the Docker Daemon), and not the hostname of the container.

@kyzooghost
Copy link
Author

Re: TESTCONTAINERS_HOST_OVERRIDE, I understand that this sets the return value of resolveHost()

However looking through the references of resolveHost() in the codebase, it doesn't influence the return value of StartedGenericContainer.getHost().

The value of StartedGenericContainer.getHost() seems to be set here

return new StartedGenericContainer(
container,
client.info.containerRuntime.host,
inspectResult,
boundPorts,
inspectResult.Name,
this.waitStrategy
);

All of this to say, not sure that TESTCONTAINERS_HOST_OVERRIDE affects the return value of StartedGenericContainer.getHost()

@kyzooghost
Copy link
Author

kyzooghost commented Jan 9, 2025

Re: creating a custom network and assigning network alias, this unfortunately didn't work for my particular case

Image

Situation

  • I have a Github runner that is running a NodeJS application container.
  • In the NodeJS application container I have integration tests that use TestContainers to spin up a Postgres container
  • The NodeJS application is using the docker daemon of the Github runner - a Docker inside Docker arrangement

Problem

  • The NodeJS container cannot talk to the Postgres container

Proposed Solution 1

  • NodeJS container can set the hostname of the Postgres container, so that it can talk to it

Why creating a custom network isn't feasible (AFAIK)

  • If a separate application was spinning up both the NodeJS and Postgres containers, then the separate application can spin up the custom Docker network and place both containers in there
  • But in this case, the NodeJS application is spinning up the Postgres container. I am unsure how we would get the NodeJS application to recognise it is in a container, and to then connect its containing container to a custom Docker network created within the NodeJS application test code.

@cristianrgreco
Copy link
Collaborator

cristianrgreco commented Jan 10, 2025

All of this to say, not sure that TESTCONTAINERS_HOST_OVERRIDE affects the return value of StartedGenericContainer.getHost()

It does

The situation you're describing should work out of the box. Testcontainers understands that it is running inside a container and set the hostname accordingly. As long as when your NodeJS container is trying to connect to PG it is connecting using the pgContainer.getHost() and pgContainer.getMappedPort(...) it should connect. If not could you share your code where your NodeJS is trying to connect to the PG container, and how each container is started, or some simple repro. Perhaps also the Testcontainers logs DEBUG=testcontainers*

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

2 participants