Running Keycloak in a container

Learn how to run Keycloak from a container image

Keycloak handles containerized environments such as Kubernetes or OpenShift as first-class citizens. This guide describes how to optimize and run the Keycloak container image to provide the best experience running a Keycloak container.

Creating a customized and optimized container image

The default Keycloak container image ships ready to be configured and optimized.

For the best start up of your Keycloak container, build an image by running the build step during the container build. This step will save time in every subsequent start phase of the container image.

Building your optimized Keycloak docker image

The following Dockerfile creates a pre-configured Keycloak image that enables the health and metrics endpoints, enables the token exchange feature, and uses a PostgreSQL database.

Dockerfile:
FROM quay.io/keycloak/keycloak:latest as builder

ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
ENV KC_FEATURES=token-exchange
ENV KC_DB=postgres
# Install custom providers
RUN curl -sL https://github.com/aerogear/keycloak-metrics-spi/releases/download/2.5.3/keycloak-metrics-spi-2.5.3.jar -o /opt/keycloak/providers/keycloak-metrics-spi-2.5.3.jar
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak:latest
COPY --from=builder /opt/keycloak/ /opt/keycloak/
WORKDIR /opt/keycloak
# for demonstration purposes only, please make sure to use proper certificates in production instead
RUN 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 conf/server.keystore
# change these values to point to a running postgres instance
ENV KC_DB_URL=<DBURL>
ENV KC_DB_USERNAME=<DBUSERNAME>
ENV KC_DB_PASSWORD=<DBPASSWORD>
ENV KC_HOSTNAME=localhost
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

The build process includes multiple stages:

  • The build command applies options and includes custom providers to create an optimized image.

  • The files generated by the build stage are copied into a new image.

  • In this runner image, the specific run configuration is applied. That configuration contains a keystore, the environment-specific hostname configuration, and database configuration.

  • In the entrypoint, the kc.sh enables access to all the distribution sub-commands.

This example uses a multi-staged build to demonstrate the build and run steps. However, you can also build a single-staged docker image by removing the following two lines:

FROM quay.io/keycloak/keycloak:latest
COPY --from=builder /opt/keycloak/ /opt/keycloak/

Building the docker image

To build the actual docker image, run the following command from the directory containing your Dockerfile:

podman|docker build . -t prebuilt_keycloak

Starting the optimized Keycloak docker image

To start the image, run:

podman|docker run --name optimized_keycloak -p 8443:8443 \
        -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=change_me \
        prebuilt_keycloak \
        start --optimized

Keycloak starts in production mode, using only secured HTTPS communication, and is available on https://localhost:8443. Notice that the startup log contains the following line:

INFO  [org.key.com.Profile] (main) Preview feature enabled: token_exchange

This message shows the desired feature is enabled.

Opening up https://localhost:8443/metrics leads to a page containing operational metrics that could be used by your monitoring solution.

Trying Keycloak in development mode

The easiest way to try Keycloak from a container for development or testing purposes is to use the Development mode. You use the start-dev command:

podman|docker run --name keycloak_test -p 8080:8080 \
        -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=change_me \
        quay.io/keycloak/keycloak:latest \
        start-dev

Invoking this command starts the Keycloak server in development mode.

This mode should be strictly avoided in production environments because it has insecure defaults. For more information about running Keycloak in production, take a look at the Configuring Keycloak for production guide.

Running a standard keycloak container

In keeping with concepts such as immutable infrastructure, containers need to be re-provisioned routinely. In these environments, you need containers that start fast, therefore you need to create an optimized image as described in the preceding section. However, if your environment has different requirements, you can run a standard Keycloak image by just running the start command. For example:

podman|docker run --name keycloak_unoptimized -p 8080:8080 \
        -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=change_me \
        quay.io/keycloak/keycloak:latest \
        start \
        --db=postgres --features=token-exchange \
        --db-url=<JDBC-URL> --db-username=<DB-USER> --db-password=<DB-PASSWORD> \
        --https-key-store-file=<file> --https-key-store-password=<password>

Running this command starts a Keycloak server that detects and applies the build options first. In the example, the line --db=postgres --features=token-exchange sets the database vendor to PostgreSQL and enables the token exchange feature.

Keycloak then starts up and applies the configuration for the specific environment. This approach significantly increases startup time and creates an image that is mutable, which is not the best practice.

Provide initial admin credentials when running in a container

Keycloak only allows to create the initial admin user from a local network connection. This is not the case when running in a container, so you have to provide the following environment variables when you run the image:

# setting the admin username
-e KEYCLOAK_ADMIN=<admin-user-name>

# setting the initial password
-e KEYCLOAK_ADMIN_PASSWORD=change_me

Feel free to join the open GitHub Discussion around enhancements of the admin bootstrapping process.

Relevant options

Type Default

db

The database vendor.

Possible values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres.

CLI: --db

Env: KC_DB

dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres

dev-file

db-password

The password of the database user.

CLI: --db-password

Env: KC_DB_PASSWORD

db-url

The full database JDBC URL.

If not provided, a default URL is set based on the selected database vendor. For instance, if using 'postgres', the default JDBC URL would be 'jdbc:postgresql://localhost/keycloak'.

CLI: --db-url

Env: KC_DB_URL

db-username

The username of the database user.

CLI: --db-username

Env: KC_DB_USERNAME

features

Enables a set of one or more features.

CLI: --features

Env: KC_FEATURES

authorization, account2, account-api, admin-fine-grained-authz, admin2, docker, impersonation, openshift-integration, scripts, token-exchange, web-authn, client-policies, ciba, map-storage, par, declarative-user-profile, dynamic-scopes, client-secret-rotation, step-up-authentication, recovery-codes, update-email, preview

health-enabled

If the server should expose health check endpoints.

If enabled, health checks are available at the '/health', '/health/ready' and '/health/live' endpoints.

CLI: --health-enabled

Env: KC_HEALTH_ENABLED

true, false

false

hostname

Hostname for the Keycloak server.

CLI: --hostname

Env: KC_HOSTNAME

https-key-store-file

The key store which holds the certificate information instead of specifying separate files.

CLI: --https-key-store-file

Env: KC_HTTPS_KEY_STORE_FILE

https-key-store-password

The password of the key store file.

CLI: --https-key-store-password

Env: KC_HTTPS_KEY_STORE_PASSWORD

password

metrics-enabled

If the server should expose metrics.

If enabled, metrics are available at the '/metrics' endpoint.

CLI: --metrics-enabled

Env: KC_METRICS_ENABLED

true, false

false

On this page