Run Quarkus Keycloak with docker-compose
Attention: snippets in this post are intended to be used for development ONLY.
Keycloak, the powerful, open source Identity solution released its latest version (19) recently. Wildfly was previously the de-facto application server for keycloak, but this has changed. Wildfly has been dropped in favour of quarkus; and this has brought about some configuration changes, as quarkus is more than just an application server.
All files needed for this demonstration can be found here
How to run keycloak
There are two ways you can run keycloak:
- Head over to the downloads section of the keycloak homepage, download the appropriate binary file. Extract and launch the kc.sh script. By default, keycloak uses an in-memory Database (H2)
2. Docker. With this option, you can either run the image directly or build your own image. In this post, we are interested in running keycloak with docker-compose.
a. The docker-compose.yml file: 2 services are declared in this file. postgres and keycloak. The postgres service simply pulls a postgres image from the remote docker repository and launches a container with the service exposed on the system port 5432. The content of ./initdb directory (which is a bash script) would eventually be copied into the container in the specified path /docker-entrypoint-initdb.d. As long as the database is empty, this script would get executed; ensuring it is run only once. We take advantage of this and drop our database creation scripts here. (for brevity, I won't be discussing all about docker, and docker-compose in this post)
version: '3.9'
services:
postgres:
image: postgres:13.2
restart: unless-stopped
container_name: cards_postgres
volumes:
# - ./db-data:/var/lib/postgresql/data/
- ./initdb:/docker-entrypoint-initdb.d
- ./postgres/conf:/var/lib/lib/postgresql/data
env_file:
- ./database.dev.env
ports:
- "5432:5432"
networks:
- backend
keycloak:
container_name: local_keycloak
image: quay.io/keycloak/keycloak:latest
# env_file:
# - ./keycloak.dev.env
environment:
KC_FEATURES:
authorization
token-exchange
docker
impersonation
scripts
upload-scripts
web-authn
client-policies
dynamic-scopes
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: password
entrypoint: /opt/keycloak/bin/kc.sh --config-file=/opt/keycloak/conf/keycloak.conf start-dev
volumes:
- ./keycloak-data:/opt/keycloak/conf
ports:
- "8080:8080"
- "8443:8443"
# restart: on-failure
networks:
- backend
depends_on:
postgres:
condition: service_started
networks:
backend:
name: backend
driver: bridge
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER keycloak with PASSWORD 'kc';
CREATE DATABASE keycloak;
GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;
CREATE DATABASE db;
EOSQL
The database environment variables are also read in from a .env file
POSTGRES_USER="postgres"
POSTGRES_PASSWORD="postgres"
PGADMIN_DEFAULT_EMAIL="user@domain.local"
PGADMIN_DEFAULT_PASSWORD="admin"
Keycloak Guides section details the available configurations and how they are to be used. The all configuration section also details the features. We have chosen to enable only a subset in our docker-compose.
Notice that the other keycloak configuation properties are read in using an environment file, except KEYCLOAK_ADMIN and KEYCLOAK_ADMIN_PASSWORD. I have only been able to get these 2 configuration properties in by explicit environments inside the docker-compose, and not from a .env or .conf file.
Also, while the documentation mentions that configuration can be read via command line, environment variables, or configuration file, the configurations were only read successfully from a .conf file and environment in the docker-compose, but not from .env file.
Keycloak loads the configuration from four different configuration sources:command-line parameters, environment variables, user-created.conf
file,keycloak.conf
file located in theconf
directory.
db=postgres
db-username=keycloak
db-password=kc
db-url=jdbc:postgresql://cards_postgres:5432/keycloak
db-schema=public
db-url-database=keycloak
db-url-host=cards_postgres
db-url-port=5432
# hostname=localhost:8080
hostname-strict=false
https-client-auth=request
https-certificate-file=/opt/keycloak/conf/server.crt.pem
https-certificate-key-file=/opt/keycloak/conf/server.key.pem
https-port=8443
https-protocols=TLSv1.3,TLSv1.2
http-enabled="true"
http-port=8080
metrics-enabled=true
proxy=edge
proxy-address-forwarding=true
postgres-user=postgres
postgres-password=postgres
pgdata=/var/lib/postgresql/data/pgdata
If you're interested in the self-signed certificate for the keycloak authorisation server, I have included the script below.
#script generates a keystore and uses this to generate a self-signed certificate to use in keycloak
keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore server.keystore
keytool -export -alias server -keystore server.keystore -file public.der
openssl x509 -inform der -in public.cert -out certificate.pem
keytool -importkeystore -srckeystore server.keystore -destkeystore keystore.p12 -deststoretype PKCS12
openssl pkcs12 -in keystore.p12 -nodes -nocerts -out server.key
And with that, we're in:
Cheers !!!