bdparrish
bdparrish

Reputation: 2774

Keycloak in docker-compose network

I want to setup a Docker network that contains a keycloak, postgres, and webapp instances.

Is there a way to have network communications between containers but also understand oidc client redirects as well? I am having an issue where containers can talk to each other just fine if i setup OIDC with container names for the docker network, but then I run into issues with the client that cannot connect to the those same URLs outside of the docker network on the host machine.

Can anyone point me to the right docker documentation to look at for possible solutions with DNS or host to container communication?

---- EDIT ----

To clarify. The containers can talk to each other just fine under their container names, but the client (i.e., Chrome) has to use localhost to talk to everything. In my setup for my OIDC connection in the ui web application I have to use container names or localhost. How do I get my client to understand container names in order to make the right request?

version: '2'

services:

  ui:
    container_name: 'ui'
    image: 'bdparrish/ui:0.1'
    build:
      context: .
      dockerfile: ./ui/Dockerfile
    ports:
      - "8085:80"
    depends_on:
      - "postgres"
      - "keycloak"
    networks:
      - auth-network
    environment:
      - ASPNETCORE_ENVIRONMENT=Docker

  postgres:
    container_name: postgres
    image: 'postgres'
    environment:
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    networks:
      - auth-network

  keycloak:
    container_name: keycloak
    image: jboss/keycloak
    ports: 
      - "8080:8080"
    depends_on:
      - postgres
    environment:
      DB_VENDOR: "POSTGRES"
      DB_ADDR: postgres
      DB_PORT: 5432
      DB_USER: keycloak
      DB_PASSWORD: password
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: password
    restart: always
    networks:
      - auth-network

networks:
  auth-network:
    driver: bridge

Upvotes: 18

Views: 20997

Answers (4)

Dzmitry Dranitski
Dzmitry Dranitski

Reputation: 679

I tried both solutions with Bitnami/Keycloak image and had no success. I also tried to set up keycloak frontend_url both in realm settings and in startup arguments like -Dkeycloak.frontendUrl=https://example.com/auth with zero success.

This is my working solution:

services:
  localhost:
    image: alpine:latest
    command: sleep infinity
    ports:
      - "3000:3000"
      - "5432:5432"
      - "8080:8080"

  postgres:
    container_name: keycloak-auth-demo-postgres
    image: postgres:15.6-alpine
    network_mode: "service:localhost"
    volumes:
      - ./postgres:/var/lib/postgresql/data
      - ./create-db.sql:/docker-entrypoint-initdb.d/create-db.sql
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    healthcheck:
      test: [ "CMD", "pg_isready", "-q", "-d", "postgres", "-U", "postgres" ]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s
    restart: unless-stopped

  keycloak:
    container_name: keycloak-auth-demo-keycloak
    image: bitnami/keycloak:23.0.6
    network_mode: "service:localhost"
    environment:
      KEYCLOAK_ENABLE_HEALTH_ENDPOINTS: true
      KEYCLOAK_DATABASE_VENDOR: postgresql
      KEYCLOAK_DATABASE_HOST: localhost
      KEYCLOAK_DATABASE_PORT: 5432
      KEYCLOAK_DATABASE_NAME: keycloak
      KEYCLOAK_DATABASE_USER: postgres
      KEYCLOAK_DATABASE_PASSWORD: postgres
      KEYCLOAK_DATABASE_SCHEMA: public
      KEYCLOAK_ADMIN_USER: keycloak
      KEYCLOAK_ADMIN_PASSWORD: keycloak
      KC_HTTP_ENABLED: 'true'
      KEYCLOAK_EXTRA_ARGS: "--import-realm"
    volumes:
      - ./keycloak.default.realm.json:/opt/bitnami/keycloak/data/import/keycloak.default.realm.json
    restart: unless-stopped
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://0.0.0.0:8080/realms/master" ]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s
    depends_on:
      postgres:
        condition: service_healthy

  service-a:
    container_name: keycloak-auth-demo-service-a
    build: 
      context: ./
      dockerfile: a.Dockerfile
    network_mode: "service:localhost"
    restart: unless-stopped
    depends_on:
      keycloak:
        condition: service_healthy
        restart: true

This method is not recommended for production usage.

Read more:

Upvotes: 0

bjhend
bjhend

Reputation: 1713

You didn't mention on which route your ui service receives the OID configuration, but I assume it is via the internal Docker network like http://keycloak:8080/realms/geoservices/.well-known/openid-configuration.

In my case it helped to use localhost for that as well with the special Docker hostname host.docker.internal, which is an alias for localhost of the Docker host. Note, that you need to set

extra_hosts:
  - "host.docker.internal:host-gateway"

in your docker compose file to make host.docker.internal accessible. Besides I set http://localhost/ also as frontend URL, but opposed to @Patrick Lindner's answer I did that in the realm setup in Keycloak itself.

Upvotes: 0

Patrick Lindner
Patrick Lindner

Reputation: 360

You don't have to modify the etc/hosts file. There is an environment variable for keycloak named KEYCLOAK_FRONTEND_URL especial for this purpose.

Edit your docker compose file to look like this:

version: '2'

services:

  ui:
    container_name: 'ui'
    image: 'bdparrish/ui:0.1'
    build:
      context: .
      dockerfile: ./ui/Dockerfile
    ports:
      - "8085:80"
    depends_on:
      - "postgres"
      - "keycloak"
    networks:
      - auth-network
    environment:
      - ASPNETCORE_ENVIRONMENT=Docker

  postgres:
    container_name: postgres
    image: 'postgres'
    environment:
      POSTGRES_PASSWORD: password
    ports:
      - "5432:5432"
    networks:
      - auth-network

  keycloak:
    container_name: keycloak
    image: jboss/keycloak
    ports: 
      - "8080:8080"
    depends_on:
      - postgres
    environment:
      DB_VENDOR: "POSTGRES"
      DB_ADDR: postgres
      DB_PORT: 5432
      DB_USER: keycloak
      DB_PASSWORD: password
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: password
      KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth
    restart: always
    networks:
      - auth-network

networks:
  auth-network:
    driver: bridge

Then the login should be redirected to that url.

Upvotes: 10

IMRZ
IMRZ

Reputation: 216

All you need to do is add an entry to your hosts file:

  • Windows: C:\Windows\System32\drivers\etc\hosts
  • Linux: /etc/hosts

Append this to the end of the file: 127.0.0.1 keycloak

Then use keycloak:8080 from your UI to talk to your keycloak server instead of localhost:8080. You can still use localhost:8580 to visit the UI in the browser.

Upvotes: 3

Related Questions