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

How to network a Docker-Compose Container with a BrowserWebDriverContainer? #856

Closed
lbier001 opened this issue Sep 4, 2018 · 8 comments
Closed

Comments

@lbier001
Copy link

lbier001 commented Sep 4, 2018

Hey all,

i'm tyring to network a Docker Compose Container with a BrowserWebDriverContainer. What is the most idiomatic way for connecting the above mentioned containers.
This is my current configuration:

  @ClassRule
  public static DockerComposeContainer enviroment = new DockerComposeContainer<>(new File("docker-compose.yml"))
    .withExposedService("srv", SERVER_WEB_PORT, Wait.forHttp("/portal").forStatusCode(200).withStartupTimeout(Duration.ofSeconds(160)))
    .withExposedService("srv", SERVER_MANGEMENT_PORT)
    .withExposedService("db", DB_PORT)
    .withLocalCompose(true);

  @ClassRule
  public static BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>()
    .withDesiredCapabilities(DesiredCapabilities.chrome());

This is my docker-compose.yml:

version: '2.3'

services:
  db:
    container_name: db
    image: db:latest
    ports:
      - "3306:3306"
    privileged: true

  srv:
    image: appserv:latest
    ports:
      - "8080:8080"
      - "9990:9990"
    expose:
      - 8080
      - 9990
    links:
      - db
    privileged: true

Or is the only way achieving this to use 2 separate GenericContainers and link them via .withNetwork() method?

@kiview
Copy link
Member

kiview commented Sep 22, 2018

Hi @lbier001, sorry for taking so long to coming back for.

There is currently no official way, to make DockerComposeContainer working with our Testcontainers' Network support. The problem with docker-compose is the fact, that docker-compose manages the networks itself and there are also things like external networks to consider.

However, I can show you a hacky way to access an existing network of an DockerComposeContainer wich you can use for your BrowserWebdriverContainer:
https://github.com/kiview/example-voting-app/blob/d5aabc53256311c2e4b3cf32edd96c9d24bc3881/src/test/groovy/AcceptanceTest.groovy#L93-L104

    private String findNetworkIdOfService(String service) {
        def containerName = compose.ambassadorContainer.linkedContainers.find { k, v ->
            k.contains(service)
        }.value.containerName

        def client = DockerClientFactory.instance().client()

        def containerInfo = client.inspectContainerCmd(containerName).exec()
        def networkName = containerInfo.networkSettings.networks.keySet().first()

        return client.inspectNetworkCmd().withNetworkId(networkName).exec().id
    }

This is Groovy code, but the exactly same use case that you've specified. Getting the network in Java will be a bit more fiddly, but of course also possible.

You can use this network afterwards like this:
https://github.com/kiview/example-voting-app/blob/d5aabc53256311c2e4b3cf32edd96c9d24bc3881/src/test/groovy/AcceptanceTest.groovy#L28-L47

        String network = findNetworkIdOfService("vote")
        Network tcNet = new Network() {
            @Override
            String getId() {
                return network
            }

            @Override
            void close() throws Exception {

            }

            @Override
            Statement apply(Statement base, Description description) {
                return null
            }
        }
        chrome.withNetwork(tcNet)

        chrome.start()

Does this help you?

@kiview
Copy link
Member

kiview commented Oct 1, 2018

I'll close it, since the workaround should work 😉

@iljapavlovs
Copy link

@kiview Would be great to get corresponding workaround example code in Java.

@runarhk
Copy link

runarhk commented Jan 29, 2020

given: #465

How should I go about solving this?

@bsideup
Copy link
Member

bsideup commented Jan 29, 2020

@runarhk does not seem to be related. Links are deprecated, but Networks are not

@bsideup
Copy link
Member

bsideup commented Jan 29, 2020

Also, #2302 should make it easier to get started service instances and eliminate the compose.ambassadorContainer.linkedContainers.find {} part

@runarhk
Copy link

runarhk commented Jan 29, 2020

Thanks for the quick response. My issue was connecting to a docker compose container from a BrowserWebDriverContainer in a Selenium test. I figured out using the approach mentioned in your docs does the trick ;)
https://www.testcontainers.org/features/networking/#exposing-host-ports-to-the-container

@vqrobu
Copy link

vqrobu commented Jul 22, 2021

Example of Java

 private static String findNetworkIdOfService(DockerComposeContainer<? extends Startable> dockerComposeContainer, String service) {
        Optional<ContainerState> opState = dockerComposeContainer.getContainerByServiceName(service);
        if (opState.isPresent()) {
            Optional<ContainerState> containerName = dockerComposeContainer.getContainerByServiceName(service);
            if(containerName.isPresent()) {

                var client = DockerClientFactory.instance().client();
                var containerInfo = containerName.get().getContainerInfo();
                var networkName = containerInfo.getNetworkSettings().getNetworks().keySet().stream().findFirst();
                if(networkName.isPresent()) {
                    return client.inspectNetworkCmd().withNetworkId(networkName.get()).exec().getId();
                }
            }
        }
        return StringUtils.EMPTY;
    }

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

No branches or pull requests

6 participants