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.
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
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.
Let’s take a look at the properties configured in the docker-compose-keycloak.yml
file.
The keycloak
service will use the jboss/keycloak image. You can find all available tags on the image page.
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.
Below you’ll find a short explanation for the variables that we’re going to set.
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.
An optional variable for specifying name of the database. Defaults to keycloak
.
An optional variable for specifying a user used to authenticate to the database. Defaults to ''
.
An optional variable for specifying a user password used to authenticate to the database. Defaults to ''
.
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.
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.
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
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.
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.
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:
keycloak
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.
Photo by Anna Shvets from Pexels
Spring Security allows us to use role-based control to restrict access to API resources. However,…
A custom annotation in Spring Boot tests is an easy and flexible way to provide…
Delegating user management to Keycloak allows us to better focus on meeting the business needs…
Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…
Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…
Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…
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,