Reputation: 2774
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
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
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
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
Reputation: 216
All you need to do is add an entry to your hosts file:
C:\Windows\System32\drivers\etc\hosts
/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