Testcontainers-java: getContainerIpAddress always returns localhost

Created on 4 Sep 2017  路  18Comments  路  Source: testcontainers/testcontainers-java

I'm trying to use testcontainers (v1.4.2) for integration testing between a Spring Boot service packed into a GenericContainer and a MysqlContainer.

Unfortunately, getContainerIpAddress will always return "localhost".

Hence, ((MySQLContainer) mysql).getJdbcUrl() will just return garbage: jdbc:mysql://localhost:32821/test

My system: Archlinux x64, Docker version 17.07.0-ce
But same error on colleague's Mac.

The following part of GenericContainer.java doesn't make sense to me

    @Override
    public String getContainerIpAddress() {
        return DockerClientFactory.instance().dockerHostIpAddress();
    }

-> isn't that just returning the mere ip address of the host running docker service?

What I expected here to see is a call returning the IP address of the virtual network interface related to the desired container.... please correct me if I'm wrong...

stale

Most helpful comment

What about adding a API method returning the real host IP address? I think it's needed in some test configurations.

All 18 comments

I encountered exactly the same problem and, unfortunately, couldn't find an acceptable workaround. If there is a solution to this then I'd love to get my hands on it.

In Groovy it would be possible to access the container's IP address like this:

genericContainer.containerInfo.networkSettings.networks.entrySet().first().value.ipAddress

So it's possible in Java as well, using a bit more verbose code, since the information is available in the object.

@fred777
The general idea would be use the mapped port of the MySQLContainer, which you can already see in the JdbcUrl using the port 32821.

@rnorth
I wonder what's the reason in not exposing the container's ip in the public API?

@fred777 getContainerIpAddress returns an IP address you can use to access your container from your tests, not from other containers. For inter-containers communication I recommend you to use Networks (since TestContainers version 1.4+ )

As I tried to explain, getContainerIpAddress just returns the string "localhost". Nada IP.

localhost is an expected behavior here. Just do not pass this as host to the running containers because for them localhost will be something different.

getJdbcUrl returns JDBC URL for the host.

What about adding a API method returning the real host IP address? I think it's needed in some test configurations.

I do have to agree with @fred777. I was confused as well when I saw getting localhost when querying a method that was supposed to return an IP address. If returning localhost is expected behavior, then might be best to change then name of that method. Btw, great work with TestContainers!!! ;)

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe this is a mistake, please reply to this comment to keep it open. If there isn't one already, a PR to fix or at least reproduce the problem in a test case will always help us get back on track to tackle this.

This issue has been automatically closed due to inactivity. We apologise if this is still an active problem for you, and would ask you to re-open the issue if this is the case.

The point of this issue is that localhost is NOT and _IP address_. It is a _hostname_.

Not good that this has been closed. I'd rather have container.getContainerAddress() return the actual address on the docker network and have a getMappedAddress() (as a counterpart to getMappedPort()) for the forwarded network mappings.

@tristantarrant what would be you use case for this?

If you need this value on your host, you may have a problem because Testcontainers supports running the tests with various Docker setups, including the remote ones (even in some Cloud)

If you need it for a communication between the containers, there is a support for networks and network aliases that should be used instead.

The issue was kept closed because it was mostly about the confusion about "getIp returns host" as stated here:
https://github.com/testcontainers/testcontainers-java/issues/452#issuecomment-481223442

Also, it got automatically closed due to inactivity 馃槄

In my use case I have a protocol which sends clients the addresses of all members in the server cluster. While the protocol itself does have a way to remap these addresses, I also want to test its behaviour when the addresses are not remapped.

@tristantarrant such NAT-unfriendly protocols are covered differently in Testcontainers, take a look at KafkaContainer or CouchbaseContainer.

Also, see Kevin's answer:
https://github.com/testcontainers/testcontainers-java/issues/452#issuecomment-331184470

We do expose ContainerInfo object with the information you need, but we don't want to have it as a supported API (getting the internal IP) because it does not work in many cases

Yeah, I'm using that approach.

A recommended read which might be helpful to others googling this issue when trying to connect to their containers: https://www.testcontainers.org/features/networking/

Hello,

I am using testcontainers 1.12.1 and following https://www.testcontainers.org/features/networking/

````
Getting the container IP address

String ipAddress = container.getContainerIpAddress();
````

I am using Docker 1.13.1

I am also getting localhost as output from that method.

I would ask to at least modify the documentation to make this caveat very clear and mention workarounds.

I would also expose a method to retrieve the host IP address of the container. In some scenarios when using Zookeeper, it is necessary to publish that and in a distributed environment there is no way of knowing where will the container be started beforehand.

By the way, using Docker Toolbox, this issue does not appear and the actual IP address is returned instead

I struggle with this problem a lot in last time(I setup GitLab CI) and I found a one decent workaround:

String ipAddress = container.getContainerInfo().getNetworkSettings().getGateway();

for example:

            String ipAddress = mariaDB.getContainerInfo().getNetworkSettings().getGateway();
            TestPropertyValues.of(
                    "spring.datasource.url=" + mariaDB.getJdbcUrl().replace("localhost", ipAddress),
                    "spring.datasource.username=" + mariaDB.getUsername(),
                    "spring.datasource.password=" + mariaDB.getPassword()
            ).applyTo(configurableApplicationContext.getEnvironment());

you can also try with --network="host" in your container or similar configuration on host side, but this above should be enought

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rnorth picture rnorth  路  3Comments

micheal-swiggs picture micheal-swiggs  路  4Comments

itudoben picture itudoben  路  3Comments

vmassol picture vmassol  路  3Comments

michael-simons picture michael-simons  路  3Comments