2

I need my BFF service to wait for keycloak to be fully launched using condition service_health, and then start its launch. I can't set up a health check for keycloak. When searching for an answer, I come across either strange or outdated answers related to curl, which is no longer in the new version of keycloak. How do I set up the healthcheck keycloak correctly?

services:
  gateway:
    image: 'my-service-bff:0.0.1-SNAPSHOT'
    container_name: 'my-service-bff'
    ports:
      - '8080:8080'
    depends_on:
      keycloak:
        condition: service_healthy
  postgres:
    image: 'postgres:latest'
    container_name: 'postgres-db'
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: keycloakdb
      POSTGRES_USER: keycloakuser
      POSTGRES_PASSWORD: keycloakpass
    healthcheck:
      test: pg_isready -U keycloakuser -d keycloakdb
      interval: 10s
      timeout: 3s
      retries: 3
      start_period: 5s
    networks:
      - keycloak-network
  keycloak:
    container_name: keycloak
    image: quay.io/keycloak/keycloak:23.0.4
    environment:
      KC_HEALTH_ENABLED: true
      DB_VENDOR: POSTGRES
      DB_ADDR: postgres
      DB_DATABASE: keycloakdb
      DB_SCHEMA: public
      KEYCLOAK_USER: user
      KEYCLOAK_PASSWORD: user
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
    ports:
      - "9090:8080"
    command:
      - "start-dev"
    networks:
      - 'keycloak-network'
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      # Unsuccessful attempts:
      # test: [ "CMD", "curl", "-f", "http://0.0.0.0:8080/realms/master" ]
      # test: ['CMD-SHELL', '[ -f /tmp/HealthCheck.java ] || echo "public class HealthCheck { public static void main(String[] args) throws java.lang.Throwable { System.exit(java.net.HttpURLConnection.HTTP_OK == ((java.net.HttpURLConnection)new java.net.URI.create(args[0]).toURL().openConnection()).getResponseCode() ? 0 : 1); } }" > /tmp/HealthCheck.java && java /tmp/HealthCheck.java http://localhost:8080/health/live']
      start_period: 10s
      interval: 30s
      retries: 3
      timeout: 5s

networks:
  keycloak-network:
    driver: 'bridge'

volumes:
  postgres_data:
    driver: 'local'

1 Answer 1

3

You could just add Curl by using the KeyCloak image in a Dockerfile and reference that Dockerfile in your docker-compose.yaml file.

To do that I create a directory inside the docker-compose.yaml directory and call it something simple like KeyCloakDockerfile and in that create your `Dockerfile so structure should look like this:

_
 |_ docker-compose.yaml
 |_ KeyCloakDockerfile/
   |_ Dockerfile

You would create the Dockerfile like so (Assuming it's RHEL or some RedHat derivative):


###### Using As Base Image ######
FROM quay.io/keycloak/keycloak:23.0.4

###### Non-Interactive Installations #########
ENV DAEMON_OPTS=-nonat
ENV TERM=xterm-256color

######### Update & Upgrade the Image ##########
RUN yum update -y && yum upgrade -y

###### Install Curl ###### 
RUN yum install -y curl

###### Use The ENTRYPOINT From The Original Images Dockerfile. ######
###### The Original Dockerfile https://quay.io/repository/keycloak/keycloak/manifest/sha256:122ff5badfb88afe1027bc8e1a9c85532148ee813bee30c01173947a445d4fe7 ######

ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

Then in your docker-compose.yaml you can change you KeyCloak service to look like this:

  keycloak:
    container_name: keycloak
    build:
      context: .
      dockerfile: ./KeyCloakDockerfile/Dockerfile
    environment:
      KC_HEALTH_ENABLED: true
      DB_VENDOR: POSTGRES
      DB_ADDR: postgres
      DB_DATABASE: keycloakdb
      DB_SCHEMA: public
      KEYCLOAK_USER: user
      KEYCLOAK_PASSWORD: user
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
    ports:
      - "9090:8080"
    command:
      - "start-dev"
    networks:
      - 'keycloak-network'
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      # Unsuccessful attempts:
      test: [ "CMD", "curl", "-f", "http://0.0.0.0:8080/realms/master" ]
      start_period: 10s
      interval: 30s
      retries: 3
      timeout: 5s

This way when you run docker compose up -d if the image has not been built it will build it then run it with the other Services defined in the docker-compose.yaml.

SECURITY SIDENOTE !

Looking the the repository that Image of KeyCloak we're using has some vulerabilities present as is labeled here:

https://quay.io/repository/keycloak/keycloak/manifest/sha256:122ff5badfb88afe1027bc8e1a9c85532148ee813bee30c01173947a445d4fe7?tab=vulnerabilities

It states that version 3.90.0-4.el9_3 should be upgraded to version 0:3.90.0-6.el9_3. This should be paid attentions to when using KeyCloak as good practise.

2
  • I have almost identical setup but yum is not found inside the Keycloak containers from quay.io. How did you make your Dockerfile work?
    – dimitarvp
    Commented May 2 at 2:18
  • Anyhow, this answer contains what we should do after the images became minimal: stackoverflow.com/a/75660630/285154
    – dimitarvp
    Commented May 2 at 3:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.