Shiro, Keycloak und Docker -> warum nur mit expliziter IP Adresse?

internet

Top Contributor
Ich befasse mich gerade mit Docker.
Hierzu habe ich eine docker-compose - Datei angelegt, die folgende Container startet:

  • Keycloak
  • Wildfly mit JAVA EE App
  • MySQL

Das passt auch soweit alles.
Mein Problem ist aber der Zugriff auf Keycloak.

Die URL muss ich in der shiro.ini angeben:
Gebe ich die IP Adresse von der Hostmaschine an, funktioniert der Zugriff:
Java:
oidcConfig.baseUri = http://192.168.178.93:9009/auth
Aber ich hätte das gerne dynamisch.

Eigentlich hätte ich erwartet, dass innerhalb dem Docker Container auch localhost funktioniert?

Ich habe auch schon das probiert:
Code:
oidcConfig.baseUri = http://keycloak_myapp:9009/auth

Ebenfalls habe ich probiert:
Code:
oidcConfig.baseUri = http://host.docker.internal:9009/auth

Wenn ich im Browser (auf der lokalen Maschine) folgendes aufrufe:
-> Dann funktioniert es ebenfalls.

Hat noch jemand eine Idee?

Hier meine docker-compose.yaml
Code:
version: '3.8'

services:
  keycloak:
    image: quay.io/keycloak/keycloak:23.0.5
    container_name: keycloak_myapp
    environment:
      - KEYCLOAK_ADMIN=admin
      - KEYCLOAK_ADMIN_PASSWORD=admin
      - KEYCLOAK_IMPORT=/opt/keycloak/data/import/realm-export.json -Dkeycloak.profile.feature.upload_scripts=enabled
    volumes:
      - ./keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json
    command:
      #- "start"
      - start-dev
      - --import-realm
      - --http-port=9009
      - --http-enabled=true
      - --http-relative-path=auth
     #command:
     # -v start-dev --import-realm
    ports:
      - "9009:9009"
    depends_on:
      - mysql
    networks:
      - app-network

  wildfly:
    #image: quay.io/wildfly/wildfly:31.0.0.Final-jdk11
    build:
      context: ./wildfly
      dockerfile: Dockerfile
    container_name: wildfly_myapp
    ports:
      - "8080:8080"
    volumes:
      - ./wildfly/configuration/standalone.xml:/opt/jboss/wildfly/standalone/configuration/standalone.xml
      - ./wildfly/lib/mysql/mysql-connector-java-8.0.12.jar:/opt/jboss/wildfly/modules/system/layers/base/com/mysql/main/mysql-connector-java-8.0.12.jar
      - ./wildfly/lib/mysql/module.xml:/opt/jboss/wildfly/modules/system/layers/base/com/mysql/main/module.xml 
      - ./wildfly/myapp.war:/opt/jboss/wildfly/standalone/deployments/myapp.war         
    environment:
      #- "start"
      - JAVA_OPTS=-server
      - --Xms512m -Xmx2048m
      - --XX:MetaspaceSize=96M
      - --XX:MaxMetaspaceSize=256m
      - --XX:+UseAdaptiveSizePolicy
      - --XX:MaxMetaspaceSize=1024m
      - --Djava.net.preferIPv4Stack=true
      - --Djboss.modules.system.pkgs=org.jboss.byteman
      - --Djava.awt.headless=true-Djava.net.preferIPv4Stack=true
    depends_on:
      - mysql
    networks:
      - app-network

  mysql:
    image: mysql:8.2.0
    container_name: mysql_myapp
    environment:
      MYSQL_ROOT_PASSWORD: test1234
      MYSQL_DATABASE: myapp
    ports:
      - "3306:3306"
    volumes:
      - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - app-network

networks:
  app-network:
    driver: bridge
 

LimDul

Top Contributor
Der Hostname ist "keycloak_myapp". Innerhalb eines Docker-Netzwerks reden die Anwendungen mit ihrem Container-Namen miteinander. Dafür muss (und solltest) du auch keine Ports weiterleiten.

Ports Weiterleitungen sollten nur da sein, wenn man von außen, also außerhalb des Docker Kontext, auf die Container zugreifen will. Das heißt z.B. bei MYSQL macht man im Idealfall nie Port-Weiterleitungen.
 

internet

Top Contributor
Der Hostname ist "keycloak_myapp". Innerhalb eines Docker-Netzwerks reden die Anwendungen mit ihrem Container-Namen miteinander. Dafür muss (und solltest) du auch keine Ports weiterleiten.

Ports Weiterleitungen sollten nur da sein, wenn man von außen, also außerhalb des Docker Kontext, auf die Container zugreifen will. Das heißt z.B. bei MYSQL macht man im Idealfall nie Port-Weiterleitungen.
d.h. jetzt konkret? Was muss ich anpassen in der shiro.ini / in der docker-compose?
 

LimDul

Top Contributor
oidcConfig.baseUri = http://keycloak_myapp:9009/auth
oder
oidcConfig.baseUri = http://keycloak:9009/auth
Bin mir nicht 100% sicher, ob er den Service oder den Containernamen nimmt.

In der docker-compose kann eigentlich jeder ports Block raus, es sei denn es soll von außerhalb drauf zugegriffen werden.
 

LimDul

Top Contributor
Natürlich kommst du von außen nicht drauf. Ich glaube du wirfst gerade Dinger durcheinander.

  • Für Container zu Container Kommunikation werden die Service-Namen verwendet
  • Für alles, was von außen (also vom User) erreichbar ist, muss man den Port weiterleiten und die externe IP Adresse des Hosts verwenden

Diese beiden Dinge muss man klar trennen.
Wer redet da gerade mit wem in deinem Fall? Wenn es im Browser genutzt werden soll - dann muss die externe IP-Adresse des Hosts verwendet werden und der Port weitergeleitet sein.
 

internet

Top Contributor
ok, also wenn der Wildfly nur mit dem Keycloak kommuniziert, dann würde vermutlich http://keycloak:9009/auth klappen.

Aber es ist ja so, dass der User diese Seite aufruft:
localhost:8080/portal/dashboard.jsf

Dann wird geprüft, ob der User authentifiziert ist, wenn nein, dann wird Keycloak (Loginmaske) aufgerufen und der User muss sich anmelden bzw. u.U. registrieren. Also Aufruf nach http://192.168.178.93:9009/auth

Wie ich es verstehe, geht dies dann nur über die explizite IP?
Gibt es aber auch eine Möglichkeit das dynamisch zu haben?
Ich möchte ungern in dem shiro.ini immer eine statische IP Adresse angeben?
 
Zuletzt bearbeitet:

LimDul

Top Contributor
Das Vorgehen bei Docker ist, das sowas nicht in irgendwelche INI-Dateien hart verdrahtet wird. Sondern das dort auf Umgangsvariablen referenziert wird, die dann wiederum im Docker-Compose definiert werden. Das heißt in deiner shiro.ini steht dann sowas drin:

Code:
oidcConfig.baseUri = ${KEYCLOAK_URL}

Und im environment Block im docker-compose steht dan:

Code:
KEYCLOAK_URL: externeIp:9090/auth

Oder in der Docker-Compose wiederum verweist man auf eine weitere Variable:
Code:
KEYCLOAK_URL: ${KEYCLOAK_URL}
Und die wiederum wird beim Deployment des compose Files in einer .env Datei definiert.

Siehe auch hier: https://docs.docker.com/compose/environment-variables/set-environment-variables/
 

LimDul

Top Contributor
Mal als Beispiel, wie bookstack bei mir aussieht:

Code:
services:
  bookstack:
    image: lscr.io/linuxserver/bookstack
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
      - APP_URL=....
      - DB_HOST=bookstack_db
      - DB_PORT=3306
      - DB_USER=bookstack
      - DB_PASS=....
      - DB_DATABASE=bookstackapp
      - AUTH_METHOD=oidc
      - AUTH_AUTO_INITIATE=false
      - OIDC_NAME=Authentik
      - OIDC_DISPLAY_NAME_CLAIMS=name
      - OIDC_ISSUER_DISCOVER=true
      - OIDC_CLIENT_ID=....
      - OIDC_CLIENT_SECRET=..
      - OIDC_ISSUER=https://auth.local....
    volumes:
      - bookstack:/config
    restart: unless-stopped
    networks:
      - proxy
      - bookstack
    depends_on:
      - bookstack_db

  bookstack_db:
    image: lscr.io/linuxserver/mariadb
    container_name: bookstack_db
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
      - MYSQL_ROOT_PASSWORD=...
      - MYSQL_DATABASE=bookstackapp
      - MYSQL_USER=bookstack
      - MYSQL_PASSWORD=...
    volumes:
      - bookstackdb:/config
    restart: unless-stopped
    networks:
      - bookstack
networks:
  bookstack:
  proxy:
    external: true
volumes:
  bookstack:
  bookstackdb:
 

internet

Top Contributor
Und im environment Block im docker-compose steht dan:

Du meinst dann vom Wildfly?

Java:
  wildfly:
    #image: quay.io/wildfly/wildfly:31.0.0.Final-jdk11
    build:
      context: ./wildfly
      dockerfile: Dockerfile
    container_name: wildfly_myapp
    ports:
      - "8080:8080"
    volumes:
      - ./wildfly/configuration/standalone.xml:/opt/jboss/wildfly/standalone/configuration/standalone.xml
      - ./wildfly/lib/mysql/mysql-connector-java-8.0.12.jar:/opt/jboss/wildfly/modules/system/layers/base/com/mysql/main/mysql-connector-java-8.0.12.jar
      - ./wildfly/lib/mysql/module.xml:/opt/jboss/wildfly/modules/system/layers/base/com/mysql/main/module.xml
      - ./wildfly/gixxjobsharing.war:/opt/jboss/wildfly/standalone/deployments/gixxjobsharing.war       
    environment:
      #- "start"
      - KEYCLOAK_URL=http://192.168.178.93:9009/auth
      - JAVA_OPTS=-server
      - --Xms512m -Xmx2048m
      - --XX:MetaspaceSize=96M
      - --XX:MaxMetaspaceSize=256m
      - --XX:+UseAdaptiveSizePolicy
      - --XX:MaxMetaspaceSize=1024m
      - --Djava.net.preferIPv4Stack=true
      - --Djboss.modules.system.pkgs=org.jboss.byteman
      - --Djava.awt.headless=true-Djava.net.preferIPv4Stack=true
    depends_on:
      - mysql
    networks:
      - app-network

Shiro.ini habe ich so angepasst:
Code:
oidcConfig.baseUri = ${KEYCLOAK_URL}
oidcConfig.discoveryURI = ${KEYCLOAK_URL}/realms/myapp/.well-known/openid-configuration

Beim Hochfahren bekomme ich aber die Meldung:

Code:
The object with id [{KEYCLOAK_URL}] has not yet been defined and therefore cannot be referenced.  Please ensure objects are defined in the order in which they should be created and made available for future reference.
 

internet

Top Contributor
Der Hostname ist "keycloak_myapp". Innerhalb eines Docker-Netzwerks reden die Anwendungen mit ihrem Container-Namen miteinander. Dafür muss (und solltest) du auch keine Ports weiterleiten.

Ports Weiterleitungen sollten nur da sein, wenn man von außen, also außerhalb des Docker Kontext, auf die Container zugreifen will. Das heißt z.B. bei MYSQL macht man im Idealfall nie Port-Weiterleitungen.
was meinst du damit genau?

Meinst du damit, dass ich eig. die ganzen Configs in der docker-compose löschen sollte?

ports:
- "9009:9009"
 

LimDul

Top Contributor
was meinst du damit genau?

Meinst du damit, dass ich eig. die ganzen Configs in der docker-compose löschen sollte?

ports:
- "9009:9009"
Wenn nur Docker Container über den Port reden würden ja - da es aber auch von außen (Browser) erreichbar sein soll, den nicht.

Der Mysql Port sollte (spätestens in einer produktiven Umgebung) raus
 

internet

Top Contributor
Wenn nur Docker Container über den Port reden würden ja - da es aber auch von außen (Browser) erreichbar sein soll, den nicht.

Der Mysql Port sollte (spätestens in einer produktiven Umgebung) raus
ich verwende gerne eine GUI (MYSQL Workbench) bpsw. um Daten mir anzeigen zu lassen (nicht zu manipulieren).

Wie kann ich das machen, wenn der Port blockiert ist? Ich würde ja von meinem lokalen Rechner dann nicht mehr darauf zugreifen können?
 

Ähnliche Java Themen

Neue Themen


Oben