Search code examples
dockerdocker-composekeycloak

deploying keycloak in a production ready environement using docker-compose


I am currently trying to deploy keycloak using docker-compose.

I wrote this docker-compose.yml file

version: '3'
services:
  loadBalancer:
    image: nginx:1.19.6
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
  auth:
    image: quay.io/keycloak/keycloak:23.0.4
    environment:
      - 'KEYCLOAK_ADMIN=admin'
      - 'KEYCLOAK_ADMIN_PASSWORD=admin'
      - 'DB_VENDOR=postgres'
      - 'DB_ADDR=database'
      - 'DB_PORT=5432'
      - 'DB_DATABASE=keycloak'
      - 'DB_USER=keycloak'
      - 'DB_PASSWORD=password'
    command:
      - start-dev
      # - start
      # - --import-realm
      # volumes:
      #   - /home/keycloak/realm.json:/opt/keycloak/data/import/realm.json
    depends_on:
      - database

  database:
    image: postgres:13.1
    environment:
      - POSTGRES_DB=keycloak
      - POSTGRES_USER=keycloak
      - POSTGRES_PASSWORD=password
    ports:
      - "5432:5432"
    volumes:
      - /home/keycloak/postgres-data:/var/lib/postgresql/data

I do not see any warning or error, but the problem is that keycloak does not seems to connect to the database, do you have any clue what is going wrong?


Solution

  • You're using the old environment variables for Keycloak. If you take a look this page and go to the db-password section (and then open it), you'll see:

    enter image description here

    I can't find docs to tell me when this changed from DB_PASSWORD but I think it was part of the Quarkus switchover. I have:

    KC_DB: postgres
    KC_DB_URL: jdbc:postgresql://db:5432/keycloak
    KC_DB_USERNAME: ${DATABASE_USERNAME}
    KC_DB_PASSWORD: ${DATABASE_PASSWORD}
    KEYCLOAK_ADMIN:  ${KEYCLOAK_USER}
    KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_PASSWORD}
    KC_HOSTNAME: auth.domain.tld
    KC_PROXY: edge
    

    where db is the name of my Postgresql database service within the docker-compose.yml file.

    My complete docker-compose.yml looks like:

    version: '3.8'
    
    services:
      db:
        image: postgres:latest
        restart: unless-stopped
        environment:
          PGDATA: /var/lib/postgresql/data/pgdata
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
        healthcheck:
          test: [ "CMD-SHELL", "pg_isready -U postgres" ]
          interval: 5s
          timeout: 5s
          retries: 5
        volumes:
          - ./pgdata:/var/lib/postgresql/data
          - ./create_db.sql:/docker-entrypoint-initdb.d/create_db.sql
    
      keycloak:
        image: quay.io/keycloak/keycloak:latest
        depends_on:
          db:
            condition: service_healthy
        environment:
          KC_DB: postgres
          KC_DB_URL: jdbc:postgresql://db:5432/keycloak
          KC_DB_USERNAME: ${DATABASE_USERNAME}
          KC_DB_PASSWORD: ${DATABASE_PASSWORD}
          KEYCLOAK_ADMIN:  ${KEYCLOAK_USER}
          KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_PASSWORD}
    #      KC_HOSTNAME: auth.myserver.tld
          KC_PROXY: edge
    
        restart: unless-stopped
        ports:
          - 8080:8080
        entrypoint: /opt/keycloak/bin/kc.sh start --hostname-url=http://localhost:8080
    

    with my .env file looking like:

    POSTGRES_USER=postgres
    POSTGRES_PASSWORD=postgres
    
    DATABASE_USERNAME=keycloak
    DATABASE_PASSWORD=keycloak
    KEYCLOAK_USER=admin
    KEYCLOAK_PASSWORD=password