Tools

Keycloak in Docker #1 – How to run Keycloak in a Docker container

Keycloak is an open source project that is a convenient option for delegating authentication and user management. It allows us to focus more on delivering business value to our projects. A proper Docker configuration for this service will come in handy whenever we need to run it locally.

Prerequsites

  • Docker installed on your machine. You can check the installed version with the docker --version command. The command’s output on my environment at the moment of writing this post is as follows:
Docker version 20.10.7

How to configure Docker containers for Keycloak

We’re going to create two services: keycloak from the jboss/keycloak image and keycloakdb from the postgres image. First, we need to create the docker-compose-keycloak.yml file:

version: '3.3'
services:
  keycloak:
    image: jboss/keycloak:${KEYCLOAK_VERSION}
    ports:
      - "8024:8080"
    environment:
      - KEYCLOAK_USER=${KEYCLOAK_USER}
      - KEYCLOAK_PASSWORD=${KEYCLOAK_PASSWORD}
      - DB_DATABASE=${KEYCLOAK_DATABASE_NAME}
      - DB_USER=${KEYCLOAK_DATABASE_USER}
      - DB_PASSWORD=${KEYCLOAK_DATABASE_PASSWORD}
      - DB_ADDR=${KEYCLOAK_DATABASE_HOST}
      - DB_VENDOR=${KEYCLOAK_DATABASE_VENDOR}
    networks:
      internal:
    depends_on:
      - keycloakdb

  keycloakdb:
    image: postgres:${POSTGRES_VERSION}
    ports:
      - "5433:5432"
    environment:
      - POSTGRES_USER=${KEYCLOAK_DATABASE_USER}
      - POSTGRES_PASSWORD=${KEYCLOAK_DATABASE_PASSWORD}
      - POSTGRES_DB=${KEYCLOAK_DATABASE_NAME}
    volumes:
      - keycloak-postgres:/var/lib/postgresql/data
    networks:
      internal:

volumes:
  keycloak-postgres:

networks:
  internal:

Below you’ll find the content of my .env file specifying the default environment variables for those services:

COMPOSE_PROJECT_NAME=keycloakindocker

POSTGRES_VERSION=14.1-alpine

KEYCLOAK_VERSION=15.0.2
KEYCLOAK_USER=keycloak
KEYCLOAK_PASSWORD=keycloak

KEYCLOAK_DATABASE_NAME=keycloakdb
KEYCLOAK_DATABASE_USER=keycloakdb
KEYCLOAK_DATABASE_PASSWORD=keycloakdb
KEYCLOAK_DATABASE_HOST=keycloakdb
KEYCLOAK_DATABASE_VENDOR=postgres

The COMPOSE_PROJECT_NAME variable holds a prefix for the services names. You’ll see the resulting names later in this post. You can provide the name of your project as a value for this variable.

Keycloak container configuration explained

Let’s take a look at the properties configured in the docker-compose-keycloak.yml file.

image

The keycloak service will use the jboss/keycloak image. You can find all available tags on the image page.

ports

On my machine, the port 8080 is already taken by another service. Therefore, I’m going to expose the keycloak service on port 8024 using the HOST:CONTAINER format.

environment

Below you’ll find a short explanation for the variables that we’re going to set.

KEYCLOAK_USER and KEYCLOAK_PASSWORD

We’re specifying credentials to create an admin account in the keycloak service. As we can read in the image documentation:

By default there is no admin user created so you won’t be able to login to the admin console. To create an admin account you need to use environment variables to pass in an initial username and password.

https://hub.docker.com/r/jboss/keycloak

An alternative to passing the credentials directly as environment variables is to provide them via files. Use the KEYCLOAK_USER_FILE and KEYCLOAK_PASSWORD_FILE variables if you want to keep the values in files.

DB_DATABASE

An optional variable for specifying name of the database. Defaults to keycloak.

DB_USER

An optional variable for specifying a user used to authenticate to the database. Defaults to ''.

DB_PASSWORD

An optional variable for specifying a user password used to authenticate to the database. Defaults to ''.

DB_ADDR

An optional variable for specifying a hostname for the database. Because we’re going to run the keycloakdb and keycloak services in a common internal network in Docker, we need to provide the service name here – keycloakdb in my example. Keycloak will add the default port 5432 to that hostname. So the resulting host will be keycloakdb:5432. On the other hand, you can specify a custom port by setting the DB_PORT variable as well.

DB_VENDOR

An optional variable for specifying a database vendor. If absent, Keycloak tries to determine the database on its own. If this process fails, Keycloak defaults to using H2. Consult the image documentation to see what values are supported. For our PostgreSQL database I’m going to use the postgres value.

Database container

You can find a detailed explanation on how to run a PostgreSQL database as a dockerized service in the Set up a PostgreSQL database with Docker post. Therefore, I won’t be repeating the configuration and variables description in this article. It’s important to realize that you’re not limited to the PostgreSQL database. As we can read in the image documentation:

Database

This image supports using H2, MySQL, PostgreSQL, MariaDB, Oracle or Microsoft SQL Server as the database.

(…) If the DB can’t be detected it will default to the embedded H2 database.

https://hub.docker.com/r/jboss/keycloak

ports

On my machine, the port 5432 is already taken by another service. Therefore, I’m going to expose the keycloak database on port 5433 using the HOST:CONTAINER format.

volumes

We’re going to create the named keycloak-postgres volume on our machine that will store content of the /var/lib/postgresql/data directory in the container.

Start Keycloak service as Docker containers

Finally, we’re going to run the following command:

docker-compose -f docker-compose-keycloak.yml up -d

The -f option for docker-compose is for specifying an alternate compose file (default: docker-compose.yml). The -d option for docker-compose up is for running the containers in the background.

As a result, we can see two Docker services running on our machine:

docker ps
CONTAINER ID   IMAGE                      PORTS                                                 NAMES
774a1d259bf9   jboss/keycloak:15.0.2      8443/tcp, 0.0.0.0:8024->8080/tcp, :::8024->8080/tcp   keycloakindocker_keycloak_1
6f10181d012b   postgres:14.1-alpine       0.0.0.0:5433->5432/tcp, :::5433->5432/tcp             keycloakindocker_keycloakdb_1

Moreover, we’ll see that the keycloakindocker specified in the COMPOSE_PROJECT_NAME variable was added as a name prefix.

Additionally, in the keycloak container logs, we’ll see that the service is using our PostgreSQL database and not the default H2:

First, we’re going to visit the http://localhost:8024/auth/ url where we’ll find the Keycloak Welcome screen:

Next, we’re going to select the Administration Console option. In order to log in, we’ll need to enter our default credentials in the following form:

According to the default environment variables from my .env file, my credentials are:

  • username: keycloak
  • password: keycloak

Finally, after a successful authentication, Keycloak redirects us to the master realm, a pre-defined realm that Keycloak created for us:

In summary, the work presented in this article is contained in the 05e4c72e4a01f33304b45e8410352060e1a17044 commit.

Learn more on running Keycloak in Docker

Photo by Anna Shvets from Pexels

little_pinecone

View Comments

  • thanks for this article. Could you please help me on save the logs in a file instead of using 'docker logs'. I would like to save the log on server.log and mount it on a folder on the host. So I will have log history.
    thanks,
     

Recent Posts

Simplify the management of user roles in Spring Boot

Spring Security allows us to use role-based control to restrict access to API resources. However,…

3 years ago

Create a custom annotation to configure Spring Boot tests

A custom annotation in Spring Boot tests is an easy and flexible way to provide…

3 years ago

Keycloak with Spring Boot #4 – Simple guide for roles and authorities

Delegating user management to Keycloak allows us to better focus on meeting the business needs…

3 years ago

Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI

Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…

3 years ago

Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests

Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…

3 years ago

Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak

Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…

3 years ago