Search code examples
dockerdns

How to use the same hostname to access a service from inside and outside of a Docker composition?


I'm using a Docker composition to develop a set of application. Some of them run as Docker container while the one I'm working on is running on my Docker host in an IDE.

Within my composition I have Keycloak running to secure my APIs using OpenID Connect. Additionally there is another container exposing an REST API (interacting with the Keycloak container). Each

services:
   keycloak:
      image: keycloak:latest
      ports:
        - "9080:8080"
   restapi:
      image: restapi:latest
      ports:
        - "10080:8080"
      environment:
        KEYCLOAK: http://keycloak # pointing to keycloak
        KEYCLOAK_REALM: myrealm
        # more OIDC client env vars such as client secret …

As mentioned on my Docker host I develop another application also secured by Keycloak (reachable on Docker host 127.0.0.1:9080). When calling the REST API running on my Docker host and providing a valid JWT as a BEARER token, the request is propagated to restapi including the JWT.

--> Docker Host REST API --> Request to container restapi (with token propagation)

Since the Docker host accesses Keycloak on 127.0.0.1:9080 and restapi reaches Keycloak on keycloak:8080 the token validation fails. Not the same hostname and ports.

Is there a way I can make Keycloak accessible using the same hostname and port from inside AND outside of the Docker composition?

Something like id.mydomain.local that points Docker internally to the keycloak container and outside I put the id.mydomain.local to my /etc/hosts


Solution

  • I have found a way, that works for me setup.

    As mentioned in my question, keycloak container port 8080 is bound to 9080 on my Docker host. All I needed to do is, to have a common hostname for Keycloak that is resolvable for my Docker Host and my Docker containers.

    I chose my.keycloak.local as the domain name.

    Docker Host

    For my Docker host I simply added the following line to my /etc/hosts file.

    127.0.0.1        my.keycloak.local
    

    This make sure, that when application connect to http://my.keycloak.local:9080 it will be routed to 127.0.0.1:9080 and therefore will be connected with my Keycloak container.

    Inside my Docker composition

    Inside the Docker composition I needed to add an addition custom host record so the container is able to resolve my.keycloak.local to the Docker host IP 172.17.0.1. Then I need to tell the restapi container to use the custom hostname my.keycloak.local to connect to Keycloak.

    services:
       keycloak:
          image: keycloak:latest
          ports:
            - "9080:8080"
       restapi:
          image: restapi:latest
          ports:
            - "10080:8080"
          environment:
            KEYCLOAK: http://my.keycloak.local # pointing to keycloak
            KEYCLOAK_REALM: myrealm
          extra_hosts:
            - "my.keycloak.local:172.17.0.1"
            # more OIDC client env vars such as client secret …