-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Accessing containers from other containers and host by using the same hostname #5094
Comments
Hey @OLibutzki, unfortunately, there is only so much we can do here on the Testcontainers side to mix host and container networking. The problem with If you would run your application as a container rather than directly on the host, you could also make use of Docker networks and therefore have a stable network alias for the application. Not sure if this works for your use case. |
You mean there is not much you can do?
It has to be executed on CI (Unix) as well.
Unfortunately, that's not an option, too, because I want to have access to the Spring beans in order to verify some behaviour like "ensure that method xy is called". Al that being said, I'm happy that I found a solution in the meantime. I had to do two things:
With this setup I have been able to execute the test which you can find here: |
Sorry, not sure I understand why can't you use the testcontainers-java/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java Line 67 in 5e016c9
|
The special requirement in this scenario is the need to access Keycloak from the user's browser and from the application's backend using the very same hostname. You pass one Auth-Server-URL to the Spring Boot application. This URL is used to...
The first request is done by the application's backend. The second request is just a redirect in the user's browser... So the browser has to be able to access the redirection target. For both URLs the very same host is used, configured using the Auth-Server-URL. In my scenario the application runs in the host and the browser in a container... That's the reason why both need to access Keycloak using the same host name. Perhaps, I do miss something how this communication with Keycloak (openid-connect) works. Maybe @dasniko can verify or refute that same hostname constraint? |
I understand that having the beans accessible makes writing certain tests easier, but for such setups where you have to set up networking and DNS in a very specific way, considering doing the tests in an out-of-process fashion by running the application as a container as well, is generally the approach I would probably suggest. You say
but a good test of such an end-to-end flow should be able to assess behavior in a closed-box style as well, rather than looking into implementation details. But this is just a rule of thumb, I don't know your code and use case well enough to give an ultimate recommendation on this. I think a diagram of the involved components would also help with understanding the problem better. |
Hi @kiview, here is the diagram with a short explanation.
My main challenge is the following: Keycloak needs to be accessible from the Spring Boot application with the very same hostname as from the browser. I hope that this explanation helps. |
At work we came accross the same problem regarding consistent host names across the docker network boundary, managed by Testcontainers. We solved it by adding a HTTP Proxy Server ot our Docker network, which we connect our browser to which is running normally, i.e. outside Docker. I've tested a couple of proxy servers but Squid was the only one that performed 100% stable using this setup, on our laptops (a lot of M1's) and on CI (Azure Devops Pipelines). The following is the code we've used as a Squid Testcontainer: public class SquidProxyContainer<SELF extends SquidProxyContainer<SELF>> extends GenericContainer<SELF> {
private static final DockerImageName DEFAULT_SQUID_PROXY_IMAGE_NAME = DockerImageName.parse("ubuntu/squid:latest");
public static final Integer PROXY_PORT = 3128;
public SquidProxyContainer() {
super(DEFAULT_SQUID_PROXY_IMAGE_NAME);
this.addExposedPort(PROXY_PORT);
}
public String getProxyUrl() {
return "http://%s:%s".formatted(getHost(), getFirstMappedPort());
}
} Since the proxy server itself is running inside the docker network (network managed by Testcontainers) all hostnames like The only real downside is that the Unit Under Test needs to run as a testcontainer as well, just like @kiview already mentioned briefly,
Our context is obviously that of a more integrated systems test, with the added benefit that we really know our docker images are working (as opposed to e.g. a |
I had the exact same problem and solved it by using the ip address of the keycloak container for communicating from spring boot and selenium with keycloak.
|
I had the same issue where instead of chrome, I'm trying to run a k6 testcontainer. The solution I have is to run the container with host mode network. In this example I'm using the k6 and keycloak Testcontainers modules class K6IntegrationTest {
@Container
static final K6Container k6 = new K6Container("grafana/k6:latest")
.withTestScript(MountableFile.forClasspathResource("k6/main.js"))
.withCopyToContainer(MountableFile.forClasspathResource("k6"), "/home/k6")
.withNetworkMode("host");
@Container
static final KeycloakContainer keycloak = new KeycloakContainer("quay.io/keycloak/keycloak:latest")
.withRealmImportFile(PATH_TO_REALM_JSON);
static String getKeycloakAuthServerUrl() {
return "http://localhost:" + keycloak.getMappedPort(8080);
}
@DynamicPropertySource
static void registerProperties(DynamicPropertyRegistry registry) {
registry.add("keycloak.auth-server-url", K6IntegrationTest::getKeycloakAuthServerUrl);
registry.add(
"spring.security.oauth2.resourceserver.jwt.issuer-uri",
() -> getKeycloakAuthServerUrl() + "/realms/foo_realm");
}
} so now when k6 calls At the moment So on Windows with WSL, you need to enable this feature flag. |
Context
I have a Spring Boot application which uses Keycloak for it's identity management.
I would like to write an UI test which interacts with the application. As the application uses Keycloak the user is redirected to Keycloak in order to login at the first request. After logging in successfully, the user is redirected to the application.
Test setup
I have two containers (Keycloak and Browser). In order to get things working the browser (which runs in a container) needs to access the application (running on the host) and Keycloak (running in a different container).
Moreover, the host needs to access Keycloak using the same hostname as the browser container does...
I tried two approaches to relaize this:
Approach 1
The Browser Container accesses Keycloak using
host.testcontainers.internal
. This works fine, but unfortunately the host cannot resolvehost.testcontainers.internal
in order to access Keycloak.Approach 2
I put the Browser container and the Keycloak container into a dedicated network. The result is almost the same, the host is not part of this network and therefore it cannot access Keycloak.
Conclusion
The most obvious solution might be to make
host.testcontainers.internal
resolvable from the host. Another option is that the host can participate in a certain network. Well, but maybe there are more ways to solve this...Btw. using
host.docker.internal
(on Windows) all over the place works fine as this hostname is available within containers AND on the host.The text was updated successfully, but these errors were encountered: