Setting up Keycloak in a Docker Container
Introduction
Keycloak is a popular open-source identity and access management solution that enables you to secure your applications and services.
If you are new to Keycloak and would like to learn more, you can refer to my article on Getting Started with Keycloak
In this lab, I will guide you through the process of creating Docker container for Keycloak, and finally accessing the Keycloak application in the web browser.
The objective is to establish a local development environment for the Keycloak application. To accomplish this, you will create a Dockerfile or Docker Compose files, run them locally, and subsequently push the image to an Azure Container Registry (ACR). All of these tasks we are doing here will be useful in later chapters when deploying to the Azure Kubernetes Service (AKS).
Technical Scenario
Title: Securing Microservices with Keycloak in a Microservices Architecture
As an Application Architect
, you are responsible for securing a complex microservices architecture using Keycloak, an open-source identity and access management solution. Your goal is to implement authentication and authorization mechanisms across the microservices, ensuring that only authorized users and services can access specific resources.
Here are some Keycloak requirements within microservices architecture:
-
Microservices architecture: You have a microservices architecture consisting of multiple services, each responsible for specific functionalities. Services include user-facing web applications, APIs, and backend services.
-
Keycloak integration: Integrate Keycloak into the microservices architecture to provide authentication and authorization capabilities. Keycloak should act as the central identity provider for all microservices.
-
User management: Implement user management within Keycloak, allowing users to sign up, log in, and manage their profiles. Define user roles and groups for fine-grained access control.
-
Secure API endpoints: Protect API endpoints to ensure that only authenticated users or services with the appropriate permissions can access them. Implement OAuth 2.0 or OpenID Connect for securing APIs.
-
Single Sign-On (SSO): Keycloak can serve as a versatile solution for enabling SSO between companies by establishing federated trust relationships between IdPs and SPs. This approach simplifies user access across organizations, enhances security, and provides a seamless user experience when accessing services and applications from different companies.
-
JWT Tokens: Utilize JSON Web Tokens (JWT) for secure communication between microservices and Keycloak. Configure token expiration, signing, and validation.
Objective
In this exercise, our objective is to accomplish and learn the following tasks:
- Step-1: Setup repository for Keycloak in Azure devops.
- Step-2: Create Keycloak project.
- Step-3: Add Dockerfiles to the Keycloak project.
- Step-4: Docker build locally.
- Step-5: Docker run locally.
- Step-6: Publish the Keycloak docker container to container registry.
Prerequisites
Before starting this lab, ensure you have the following prerequisites in place:
- Docker and the VS Code Docker extension : - Docker Downloads.
- Git Client tool: - Git Downloads.
- Azure devops and Git Repository: Initialize a Git repository for your Keycloak application.
- Azure Container Registry (ACR)
- Docker compose installed
Verify the docker installation by running following commands:
Verify the docker compose by running following commands:
Architecture Diagram
The following diagram shows the high level steps to create docker container for Keycloak application.
Step-1: Setup repository for Keycloak in Azure DevOps
Before you begin with the Keycloak setup, it's necessary to have a version control repository to manage your project.
- Create azure devops project
- Initialize repository
For this Keycloak application, we can either use an existing git repository created in our first chapter or initiate a new one.
To clone an existing repository, run the following command:
Step-2: Create Keycloak project
In this step, we'll create a dedicated project for our Keycloak application
Create a new project: Inside our Git repository, create a new directory or folder specifically for your Keycloak project. This folder will contain all the necessary files for Keycloak, including Dockerfiles and configurations.
Step-3: Keycloak setup with docker compose
Setup Keycloak Service
To setup the Keycloak with docker compose you need to first create a docker compose file that defines the Keycloak service and any necessary dependencies, such as a PostgreSQL database.
Here's a step-by-step explanation of how to set up Keycloak with docker compose:
Create a file named docker-compose.yml
in your project directory. This file will define the services and configurations for your Keycloak setup.
In the docker-compose.yml file, define the Keycloak service. Use the official Keycloak Docker image and specify any necessary configurations. Here's an example of a Keycloak service definition:
services:
auth:
image: quay.io/keycloak/keycloak
ports:
- "8080:8080"
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
command:
- start-dev
- --import-realm
volumes:
- /home/keycloak/realm.json:/opt/keycloak/data/import/realm.json
This definition:
- Uses the
quay.io/keycloak/keycloak
Docker image. - Maps port 8080 on your host to port 8080 in the Keycloak container.
- Sets up an initial admin user and password for Keycloak.
docker-compose up
# or
docker-compose up -d
#output
[+] Running 1/0
✔ Container keycloak-auth-1 Created 0.0s
Attaching to keycloak-auth-1
.
.
.
Running the server in development mode. DO NOT use this configuration in production.
docker ps
# output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3ee7cef046e quay.io/keycloak/keycloak "/opt/keycloak/bin/k…" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp, 8443/tcp keycloak-auth-1
docker image ls
# output
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/keycloak/keycloak latest 273d68e6fb8c 6 days ago 459MB
docker container ls
# output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3ee7cef046e quay.io/keycloak/keycloak "/opt/keycloak/bin/k…" 22 minutes ago Up 22 minutes 0.0.0.0:8080->8080/tcp, 8443/tcp keycloak-auth-1
docker network ls
# output
NETWORK ID NAME DRIVER SCOPE
e71f9c6bd718 bridge bridge local
d08c17ea4f0e docker-nodejs-sample_default bridge local
cfb02a162739 host host local
c8fb8d726406 keycloak_default bridge local
8bba86e6ad07 none null local
Access Keycloak: Once the Keycloak service is up and running, you can access the Keycloak admin console by opening a web browser and navigating to http://localhost:8080. You can log in using the admin user and password you defined in the Keycloak service configuration.
Keycloal admin console
Keycloak Login page
Keycloak master relm
Setup Keycloak Service with PostgreSQL database
If you want to use a PostgreSQL database as Keycloak's backend, define a PostgreSQL service in the same docker-compose.yml
file.
Here's a complete docker-compose.yml
file that sets up Keycloak with a PostgreSQL database:
version: '3'
services:
keycloak:
image: quay.io/keycloak/keycloak
container_name: keycloak
ports:
- "8080:8080"
environment:
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
command:
- start-dev
- --import-realm
volumes:
- /home/keycloak/realm.json:/opt/keycloak/data/import/realm.json
depends_on:
- postgres
networks:
- keycloak_network
postgres:
image: postgres:latest
container_name: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_DB=keycloak
- POSTGRES_USER=keycloak
- POSTGRES_PASSWORD=keycloak
networks:
- keycloak_network
networks:
keycloak_network:
driver: bridge
In this docker-compose.yml
file:
- The
keycloak
service uses the official Keycloak Docker image, maps port 8080 on your host to port 8080 in the Keycloak container, and sets up an initial admin user and password. - The
postgres
service uses the official PostgreSQL Docker image, specifies the database name, username, and password for PostgreSQL, and maps port 5432 on your host to port 5432 in the PostgreSQL container. depends_on
ensures that thekeycloak
service starts only after thepostgres
service is up and running, as Keycloak relies on the PostgreSQL database.- Both services are connected to a custom network called
keycloak_network
for communication between containers.
Once both services are up and running, you can access the Keycloak admin console by opening a web browser and navigating to http://localhost:8080/auth
. Log in using the admin user and password you specified in the Keycloak service configuration.
Step-4: Keycloak setup with Dockerfile
Step-4.1: Create Dockerfile
Let's create a Dockerfile in the root directory of our project and include the following code. We are going to use this Dockerfile to containerize our Keycloak application as per our need.
FROM quay.io/keycloak/keycloak:latest as builder
# Enable health and metrics support
ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
# Configure a database vendor
ENV KC_DB=postgres
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
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:latest
COPY --from=builder /opt/keycloak/ /opt/keycloak/
# change these values to point to a running postgres instance
ENV KC_DB=postgres
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"]
Step-4.2: Docker build locally
We will build the Docker container locally using the Dockerfiles and ensure that the containerized application working as expected.
The docker build
command is used to build Docker images from a Dockerfile.
output
When you run the docker build
command, Docker looks for a Dockerfile in the specified directory and reads the instructions in the file to build a new image.
The Dockerfile contains a series of instructions that define how to build the image, such as copying files, running commands, and setting environment variables.
Step-4.3: Docker run locally
Run the Docker container locally to verify that the keycloak application working correctly within a containerized environment. This step ensures that the containerized keycloak application works as expected on your local machine.
Run the docker run
command to start a container based on the image:
Step-5: Publish the Keycloak docker container to container registry
Now that we have Keycloak Docker container ready locally, it's time to push them to the Container Registry for future deployment on Azure Kubernetes Services (AKS). This step is important for preparing the container for deployment in a cloud environment.
To publish a Keycloak Docker container to Azure Container Registry (ACR), you will need to have the following:
Create an Azure Container Registry. If you don't have one, you can create one by following the instructions in the Azure Portal or using Azure CLI.
Log in to your Azure Container Registry using the Docker command-line interface. You can do this by running the following command:
# azure Login
az login
# set the azure subscription
az account set -s "anji.keesari"
# Log in to the container registry
az acr login --name acr1dev
# Login Succeeded
# To get the login server address for verification
az acr list --resource-group rg-acr-dev --query "[].{acrLoginServer:loginServer}" --output table
# output should look similar to this.
# AcrLoginServer
# ------------------
# acr1dev.azurecr.io
list all the Docker images that are available on the local system
docker images
# output
REPOSITORY TAG IMAGE ID CREATED SIZE
sample/keycloak-app 20230312.1 587f347206bc 8 minutes ago 216MB
.
.
.
Tag
your Docker container image with the full name of your Azure Container Registry, including the repository name and the version tag. You can do this by running the following command:
Push your Docker container image to your Azure Container Registry using the Docker command-line interface. You can do this by running the following command:
docker push acr1dev.azurecr.io/sample/keycloak-app:20240101.1
#Output
The push refers to repository [acr1dev.azurecr.io/sample/keycloak-app]
649a035a1734: Pushed
4061bd2dd536: Pushed
c0257b3030b0: Pushed
912a3b0fc587: Pushed
a36186d93e25: Pushed
a3d997b065bc: Pushed
65d358b7de11: Pushed
f97384e8ccbc: Pushed
d56e5e720148: Pushed
beee9f30bc1f: Pushed
20240101.1: digest: sha256:73f0669d18c6cae79beb81edc8c523191710f9ec4781d590884b46326f9ad6f9 size: 2419
Wait for the push to complete. Depending on the size of your Docker container image and the speed of your internet connection, this may take a few minutes.
Verify the newly pushed image to ACR.
az acr repository list --name acr1dev --output table
# Output
Result
-------------------------------
mcr.microsoft.com/dotnet/aspnet
mcr.microsoft.com/dotnet/sdk
sample/aspnet-api
sample/aspnet-app
sample/node-api
sample/postgresql-db
sample/keycloak-app
Show the new tags of a image in the acr
You've successfully pushed your Docker container image to Azure Container Registry. You can now use the Azure Portal or Azure CLI to manage your container images and deploy them to Azure services like Azure Kubernetes Service (AKS).
Conclusion
You have successfully created a Docker container for keycloak application, container created as part of this task will be used in the future labs in AKS.
References
-