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

featured image

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:

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:

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

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:

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:

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:

Keycloak logs from it's Docker container

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

Keycloak Welcome page

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:

login form to master realm

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:

keycloak master realm

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

One thought on “Keycloak in Docker #1 – How to run Keycloak in a Docker container

  1. 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,
     

Leave a Reply

Your email address will not be published. Required fields are marked *