Not able to access keycloak in browser using host name change

4,712 views
Skip to first unread message

Parth Bhatt

unread,
Feb 21, 2023, 3:31:25 PM2/21/23
to Keycloak User
Hello All,

We have created spring application which is secured using keycloak and it is working fine when we are trying to run it outside docker containers but when we deploy Spring application and Keycloak in two separate docker containers it is not working:

our docker compose file is as follow:


keycloak:
    image: quay.io/keycloak/keycloak:18.0
    hostname: keycloak
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://db:5432/app
      KC_DB_DATABASE: app
      KC_DB_USERNAME: postgres
      KC_DB_SCHEMA: public
      KC_DB_PASSWORD: root
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: password
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: password
      KEYCLOAK_FRONTEND_URL: http://keycloak:8280
      KC_HOSTNAME_STRICT: "false"
      KC_EDGE: proxy
    ports:
      - 8280:8280
    command:
      - start-dev
      - --http-port=8280
    networks:
      - network
security:
    container_name: security
    expose:
      - "9000"
    ports:
      - 9000:9000
    depends_on:
      - keycloak
    environment:
      - KEY_CLOAK=http://keycloak:8280
    networks:
      - network
networks:
  network:
    driver: bridge

But when we try to access it in browser using "http://keycloak:8280/admin" it is not working, it is working using "http://localhost:8280/admin" url in browser. But now spring application is in another container and it requires "http://keycloak:8280/admin" url, so how to make one URL work both side? Please guide me I also tried to set below property but it is also not working.
      PROXY_ADDRESS_FORWARDING: "true"
      KC_HOSTNAME: keycloak
      KC_HOSTNAME_URL: "http://keycloak:8280"
      KEYCLOAK_FRONTEND_URL: "http://keycloak:8280"
      KC_HOSTNAME_STRICT: "false"
Please guide.
Thanks in advance.

Björn Pedersen

unread,
Feb 22, 2023, 4:16:37 AM2/22/23
to Keycloak User
Parth Bhatt schrieb am Dienstag, 21. Februar 2023 um 21:31:25 UTC+1:

But when we try to access it in browser using "http://keycloak:8280/admin" it is not working, it is working using "http://localhost:8280/admin" url in browser. But now spring application is in another container and it requires "http://keycloak:8280/admin" url, so how to make one URL work both side? Please guide me I also tried to set below property but it is also not working.
      PROXY_ADDRESS_FORWARDING: "true"
      KC_HOSTNAME: keycloak
      KC_HOSTNAME_URL: "http://keycloak:8280"
      KEYCLOAK_FRONTEND_URL: "http://keycloak:8280"
      KC_HOSTNAME_STRICT: "false"

This short hostname is fine for communication between containers in a docker-compose setup, but not  for communication with the outside world. As OIDC and SAML both do a 3-way communiction ( app <---> browser <----> keyclokak ) you need a  resolvable external hostname so that the browser knows how to reach keycloak. And this hostname is what you need to configure in your app.

Parth Bhatt

unread,
Feb 22, 2023, 6:22:57 AM2/22/23
to Keycloak User
Thank you for the response.

But how to bind this  resolvable external hostname with keycloak container? Because for internal communication "keycloak" container name is used and for external "localhost".

Gregory Ledray

unread,
Feb 23, 2023, 9:36:00 AM2/23/23
to Keycloak User
Hi.

It sounds like you already understand to use "keycloak:8443" for server client and "localhost:8443" for javascript client. I just set this up a couple months ago and there were a lot of configuration options which caused problems for me - maybe the problem is with a config option. I think it would be easiest to just show how I got things to work to help you. Here is a 4-container setup with Postgres, Keycloak, a server-side app, and a client-side app. I am running in WSL 2 with Docker Compose.

Key things to note:
* If client-side javascript wants to communicate with Keycloak, it does so on localhost:8443, which is keycloak's exposed and mapped port
* If server-side app wants to communicate with Keycloak, it does so on the URL provided by the environment variable "AUTH_ENDPOINT", which is currently set to "https://keycloak:8443/"
* When deploying, all of the containers run on separate EC2 instances. When deployed, AUTH_ENDPOINT is set to the public URL of the keycloak instance and both javascript and the server-side app use the public URL (it's a bit more complicated than that but that's the general idea).

I hope this helps. A simplified version of my docker-compose.yml is below.
--------------------------------------------------------
version: "3"

# docker compose -f ./infra/docker-compose.yml up
#
# Run front end code (frontend service) AND backend (server service) locally (so I can debug them) and run Keycloak and Postgres in Docker with:
# docker compose -f ./infra/docker-compose.yml up keycloak postgres --no-deps

services:
  postgres:
    image: postgres
    volumes:
      - /var/lib/postgres-keycloak-and-ep:/var/lib/postgres-keycloak-and-ep/data
    environment:
      POSTGRES_DB: "postgres"
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "password"
      PGDATA: "/var/lib/postgres-keycloak-and-ep/data"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 5s
    ports:
      - "5432:5432"
    # for debugging statements
    command: ["postgres", "-c", "log_statement=all"]
  keycloak:
    image: [keycloak dockerfile is custom, and is FROM quay.io/keycloak/keycloak:latest]
    depends_on:
      postgres:
        condition: service_healthy
      server:
        condition: service_started
    build:
      context: ../keycloak
      dockerfile: ./keycloak-localhost.dockerfile
    environment:
      KC_DB_URL_DATABASE: "postgres"
      # Many environment variables are set in my custom keycloak-localhost.dockerfile - I have copied them here and simplified a bit. The syntax might not be 100% correct since .dockerfile syntax is a bit different
      ENV KC_DB: "postgres"
      ENV KC_DB_USERNAME: "postgres"
      ENV KC_DB_PASSWORD: "password"
      # ENV KC_DB_SCHEMA: "public"
      # ENV KC_DB_URL_HOST: "postgres"
      # ENV KC_DB_URL_PORT: "5432"
      # ENV KC_HOSTNAME: "localhost"
      # ENV KC_HOSTNAME_PORT: 8443
      # ENV KC_HOSTNAME_STRICT: false
      # ENV KC_HOSTNAME_STRICT_BACKCHANNEL: false
      # ENV KC_HTTP_ENABLED: false
      # ENV KC_HTTPS_PROTOCOLS: "TLSv1.3,TLSv1.2"
      # ENV KC_HEALTH_ENABLED: true
      # ENV KC_LOG: console
      # ENV KEYCLOAK_ADMIN: "admin"
      # ENV KEYCLOAK_ADMIN_PASSWORD: "admin"
    ports:
      - "8443:8443"
  server:
    image: [our app image]
    depends_on:
      postgres:
        condition: service_healthy
    build:
      context: ../../src/server-code
      dockerfile: ./path/to/server/Dockerfile
    environment:
      ISLOCALHOST: true
      ISDOCKER: true
      DBUsername: "postgres"
      DBPassword: "postgres"
      AUTH_ENDPOINT: "https://keycloak:8443/"
    ports:
      - "5000:80"
  frontend:
    image: [our fe image]
    build:
      context: ../../src/client-code
      dockerfile: ./path/to/client/Dockerfile
    ports:
      - "8080:3000"

volumes:
  postgres_data:
    driver: local


Reply all
Reply to author
Forward
0 new messages