Deploy Keycloak Using Podman
Introduction
Keycloak provides single sign-on functionality for web applications and RESTFUL web services. A primary goal of Keycloak is to provide security features that developers can easily use to secure applications and services within their organizations, for example Single-Sign-On authentication. Keycloak can also be integrated with existing LDAP and Active Directory servers.
Keycloak is based on standard protocols and provides support for User Federation, OpenID Connect, OAuth 2.0 and SAML and many more. Keycloak provides both administrators, and users, with management consoles. Users can update their passwords, profile details and setup two-factor authentication via the Account Managment Console. Likewise administrators can use the Admin Console to manage all aspects of Keycloak's functionality, it's authorization policies, applications and manage users (including user's permissions and sessions).
Objectives
This lab shows how to deploy Keycloak on Podman, configure it with a datastore using a Podman volume to store the data outside of Podman. Then demonstrate how to access Keycloak, create a new Realm
then add a User
to the newly created Keycloak Realm
. Finally the newly created User
will log on to the Keycloak server's newly created Realm
to demonstrate where a User
could manage the Single Sign-On details. The main steps are outlined below:
- Install Podman
- Configure a Podman network and volume
- Deploy a Postgres database container
- Deploy a Keycloak container using the Postgres container as a datastore
- Create a new Keycloak
Realm
andUser
Note: A production deployment would most likely use either Podman secrets, or Kubernetes secrets, to obfuscate any passwords. Neither of the scenarios are covered in this Lab.
What Do You Need?
- A client system with Oracle Linux installed
- Access to the Internet
For more information about Keycloak itself, see the upstream website .
Setup the Lab Environment
Note: When using the free lab environment, see Oracle Linux Lab Basics for connection and other usage instructions.
Open a terminal and connect via ssh to the ol-server instance if not already connected.
ssh oracle@<ip_address_of_instance>
Install the Container Tools
The Container Tools in Oracle Linux provide the latest fast and stable versions of Podman, Buildah, Skopeo, and associated dependencies.
Install the Container Tools packages.
sudo dnf install -y container-tools
Check the version of Podman.
podman --version
Create a Podman Network
Podman provides a default network environment wihch can be used to run any container available to it. However, there may be occasions where the business requires the ability to segregate some deployments from each other - this is where the podman network
command helps. In this scenario Keycloak, along with it's database, will be deployed onto it's own podman network
.
Whilst it is possible, as part of creating a Podman Network to define numerous other options at the same time, for example a different --subnet
, --gateway
or --ip-range
, to be defined - this scenario will not demonstrate this. Please refer to the upstream documentation for more details. This scenario only shows a basic bridge
network, using Podman's default settings, being created.
Create the Podman network.
podman network create keycloak-network
Verify that the Podman network is created.
Note: Podman creates a default Podman network (called podman) when Podman is installed, hence why two networks are displayed.
podman network ls
Example Output:
[oracle@ol-server ~]$ podman network ls NETWORK ID NAME DRIVER ea439617652f keycloak-network bridge 2f259bab93aa podman bridge
Display the network configuration used by the newly created Podman
keycloak-network
. This can be used to confirm that the required/expected network settings for a deployment are active for the specifiedpodman network
.podman network inspect keycloak-network
Example Output:
[oracle@ol-server ~]$ podman network inspect keycloak-network [ { "name": "keycloak-network", "id": "ea439617652ffdd8320503c4eb2723f5f5ca291ed1ed70f8efc05ec52980f9e3", "driver": "bridge", "network_interface": "podman1", "created": "2022-10-05T11:39:55.55110214Z", "subnets": [ { "subnet": "10.89.0.0/24", "gateway": "10.89.0.1" } ], "ipv6_enabled": false, "internal": false, "dns_enabled": true, "ipam_options": { "driver": "host-local" } } ]
Download Postgres
By default Keycloak uses a file-based H2 database to store any configuration changes made. However because this is stored within the deployed container, it means that any information is lost whenever the Keycloak container is stopped. However Keycloak has built-in support for multiple databases. So, this example uses a Postgres database configured to store it's data externally from the container to prevent any Keycloak configuration being lost when the Keycloak container is stopped (shutdown).
Download the latest image of Postgress.
podman pull docker.io/library/postgres:latest
Example Output:
[oracle@ol-server ~]$ podman pull docker.io/libraary/postgres ��� docker.io/library/postgres:latest Trying to pull docker.io/library/postgres:latest... Getting image source signatures Copying blob b955aac8d5e0 done ... ... Copying config e270a11b9c done Writing manifest to image destination Storing signatures e270a11b9c8a719c4f501c34f1fccf7de89cda4d95e6e6ec9cadc73bdb1ae6d5
Confirm the Postgres image is available.
podman image ls
Example Output:
[oracle@ol-server ~]$ podman image ls REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/postgres latest e270a11b9c8a 4 hours ago 384 MB
Create a Podman volume to store the data.
podman volume create pgdata
Example Output:
[oracle@ol-server ~]$ podman volume create pgdata pgdata
Verifiy the Podman volume has been created.
podman volume inspect pgdata
Note: The Podman volume's data is located in the $PATH indicated by the
Mountpoint
variable.Example Output:
[oracle@ol-server ~]$ podman volume inspect pgdata [ { "Name": "pgdata", "Driver": "local", "Mountpoint": "/home/oracle/.local/share/containers/storage/volumes/pgdata/_data", "CreatedAt": "2022-10-12T12:19:31.393134253Z", "Labels": {}, "Scope": "local", "Options": {}, "MountCount": 0, "NeedsCopyUp": true, "NeedsChown": true } ]
Start the Postgres container.
podman run -p 5432:5432 --name myPostgresDB -d --net keycloak-network -v pgdata:/var/lib/postresql/data -e POSTGRES_USER=pgresUser -e POSTGRES_PASSWORD=pgresPW -e POSTGRES_DB=keycloakDB postgres
Example Output:
[oracle@ol-server ~]$ podman run -p 5432:5432 --name -d --net keycloak-network -v pgdata:/var/lib/postresql/data -e POSTGRES_USER=pgresUser -e POSTGRES_PASSWORD=pgresPW -e POSTGREs_DB=keycloakDB postgres 8008a2b87bdca436fce22ad4420ae40caf456c4f3f77099b0e44584caca5984b
Time to explain what just occurred.
podman run
instructs Podman to create and run a container.-p 5432:5432
is the port mapping being used by the running container. In this case the5432
on the left maps to the local port, and5432
on the right maps to the port internally within Podman.--name myPostgresDB
is the name chosen for the container being created.-d
indicates that Podman is to execute the container in detached mode (it runs in a background process)--net keycloak-network
instructs Podman to assign the Postgres container to the keycloak-network-v pgdata:/var/lib/postresql/data
starts Postgres using a Podman volume (the left hand value) to store the Postres data (the right hand value) externally from the Postgres container- Next set the required Postgres environment variables:
-e POSTGRES_DB=keycloakDB
Sets the database's name-e POSTGRES_USER=pgresUser
Sets the administrator user's name-e POSTGRES_PASSWORD=pgressPW
Sets the administrator user's password
postgres
is the name of the image Podman is to run.
Confirm the Postgres container is running.
Notice that the
NAMES
column listed is the same value as that passed to Podman using the--name
switch.podman ps
Example Output:
[oracle@ol-server ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8008a2b87bdc docker.io/library/postgres:latest postgres 11 minutes ago Up 11 minutes ago 0.0.0.0:5432->5432/tcp myPostgresDB
(Optional) How to confirm the Postgres container's environment variables.
This demonstrates how to inspect, or confirm, the environment variables for the running Postgres container.
podman exec myPostgresDB env
Example Output:
[oracle@ol-server ~]$ podman exec myPostgresDB env LANG=en_US.utf8 PG_MAJOR=14 PG_VERSION=14.5-1.pgdg110+1 POSTGRES_PASSWORD=pgresPW PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/14/bin TERM=xterm container=podman GOSU_VERSION=1.14 PGDATA=/var/lib/postgresql/data POSTGRES_USER=pgresUser POSTGREs_DB=keycloakDB HOME=/root
Download and start PGAdmin
Now that Postgres is running, either the command-line can be used to connect to the database, or use PGAdmin, a web-based GUI tool used to connect to Postgres servers. The following steps demonstrate how to get PGAdmin working in Podman.
Download PGAdmin
Download the PGAdmin image.
podman pull docker.io/dpage/pgadmin4:latest
Example Output:
[oracle@ol-server ~]$ podman pull docker.io/dpage/pgadmin4:latest Trying to pull docker.io/dpage/pgadmin4:latest... Getting image source signatures Copying blob 15719ca221da done ... ... Copying config 94c0924749 done Writing manifest to image destination Storing signatures 94c0924749b6efbd528467945d7c12370f5e8b98e4b873a0b50406aa25d4ca4b
Important Note: If running Podman on Oracle Linux, the default container registry is set as: container-registry.oracle.com. However it requires a username/password to access, therefore if you do not already have this, or if using the Free Lab environment (and not using the Docker hub URI directly), please use the down arrow key on the keyboard to select the public repository: docker-io
Example Output:
[oracle@ol-server ~]$ podman pull dpage/pgadmin4:latest ? Please select an image: ��� container-registry.oracle.com/dpage/pgadmin4:latest docker.io/dpage/pgadmin4:latest
Confirm the Server's IP address and Hostname
Get the ip address of the server.
sudo ip addr show
Example Output:
[oracle@ol-server ~]$ sudo ip addr show ... 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000 link/ether 02:00:17:09:3d:1f brd ff:ff:ff:ff:ff:ff altname enp0s3 inet 10.0.0.150/24 brd 10.0.0.255 scope global dynamic noprefixroute ens3 valid_lft 71828sec preferred_lft 71828sec inet6 fe80::17ff:fe09:3d1f/64 scope link noprefixroute valid_lft forever preferred_lft forever
The IPv4 address to use is on the line starting with
inet
Confirm the forward DNS configuration.
host $(hostname -f)
Example output:
[oracle@ol-server ~]$ host $(hostname -f) ol-server.pub.linuxvirt.oraclevcn.com has address 10.0.0.150
Start PGAdmin
Start PGAdmin
podman run --name my-pgadmin -p 8082:80 --net keycloak-network -e PGADMIN_DEFAULT_EMAIL="pgresUser@example.com" -e PGADMIN_DEFAULT_PASSWORD="pgresPW" -d dpage/pgadmin4
Important: use the email as specified.
Again, time to explain what just occured.
podman run
instructs Podman to create and run a container.-p 8082:80
is the port mapping being used by the running container. In this case the8082
maps to the local port, and80
maps to the port internally within Podman. (Note: Ports lower than1024
need to be started byroot
)--name my-pgadmin
is the name chosen for the container being created.-d
indicates that Podman is to execute the container in detached mode (it runs in a background process)--net keycloak-network
instructs Podman to assign the Postgres container to the keycloak-network- Sets the Postgres environment variables:
-e PGADMIN_DEFAULT_EMAIL="pgresUser@example.com"
Sets the administrator user's email-e PGADMIN_DEFAULT_PASSWORD="pgresPW"
Sets the administrator user's password
dpage/pgadmin4
is the name of the image Podman is to run.
Access the PGAdmin Web Console
Right-click on the Virtual Desktop and select
Open Terminal Here
.Configure an SSH tunnel.
ssh -L 8082:localhost:8082 oracle@<hostname or ip address>
Open a new browser session (on the Virtual Desktop) and enter the URL.
http://localhost:8082
Example Output:
Login to PGAdmin
This requires using the same User Name and Password passed when starting the PGAdmin container. Enter the values shown below:
User Name
- pgresUser@example.comPassword
- pgresPW
Example Output:
Connect to the Postgres database
- Click on the
Add New Server
icon, a new dialogue box appears.
Example Output:
- Enter the name of the Postgres server to connect to which in the scenario is
myPostgresDB
Example Output:
Click on the
Connection
tab within the dialogue box, and enter the following details in the relevant fields:Host name/Address
- 10.0.0.150Port
- 5432Username
- pgresUserPassword
- pgresPWClick on the
Save
button to register the server.
Example Output:
- The connection to
myPostgresDB
is complete
Example Output:
- Click on the
Download and Start Keycloak
The first step is to pull, and start, the Keycloak container.
Pull and start Keycloak. The following step will start Keycloak using port 8080, and then create an initial administrator user
admin
and assign the passwordadmin
to that user. The last optionstart-dev
initializes Keycloak to use:podman run -p 8080:8080 -d --name keycloak -d --net keycloak-network -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e KC_DB=postgres -e KC_DB_URL_DATABASE=keycloakDB -e KC_DB_URL_HOST=10.0.0.150 -e KC_DB_URL_PORT=5432 -e KC_DB_USERNAME=pgresUser -e KC_DB_PASSWORD=pgresPW quay.io/keycloak/keycloak:latest start-dev
Again, time to explain what command-line options describe.
podman run
instructs Podman to create and run a container.-p 8080:8080
is the port mapping being used by the running container. In this case the8080
on the left hand side maps to the local port, and8080
on the right hand side maps to the port internally within Podman. (Note: Ports lower than1024
need to be started byroot
)--name keycloak
is the name chosen for the container being created.-d
indicates that Podman is to execute the container in detached mode (it runs in a background process)--net keycloak-network
instructs Podman to assign the Postgres container to the keycloak-network-e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin
set the required Keycloak environment variables. In this instance the administrator user and password.-e KC_DB=postgres -e KC_DB_URL_DATABASE=keycloakDB -e KC_DB_URL_HOST=10.0.0.150 -e KC_DB_URL_PORT=5432 -e KC_DB_USERNAME=pgresUser -e KC_DB_PASSWORD=pgresPW
- set the required environment variables to enable Keycloak to store it's data in the Postgres database.dquay.io/keycloak/keycloak:latest
is the name of the image Podman is to run.start-dev
- Starts Keycloak in development mode (which is not using certificates & SSL). NOTE This is NOT suitable for production use.
Example Output:
[oracle@ol-server ~]$ podman run -p 8080:8080 -d --name keycloak -d --net keycloak-network -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e KC_DB=postgres -e KC_DB_URL_DATABASE=keycloakDB -e KC_DB_URL_HOST=10.0.0.150 -e KC_DB_URL_PORT=5432 -e KC_DB_USERNAME=pgresUser -e KC_DB_PASSWORD=pgresPW quay.io/keycloak/keycloak:latest start-dev Trying to pull quay.io/keycloak/keycloak:latest... Getting image source signatures Copying blob 0f8dfc4ae562 done Copying blob 008dba906bf6 done Copying blob d5d2e87c6892 done Copying blob e89553497f29 done Copying config fab433d55e done Writing manifest to image destination Storing signatures 0fead1b248b4118950b20e89ab8db485746adaa12db545e892b871959ce394b8
Access the Keycloak Console
The next step is to open a second SSH Tunnel. Right-click on the Virtual Desktop and select
Open Terminal Here
.Configure the SSH tunnel.
ssh -L 8080:localhost:8080 oracle@<hostname or ip address>
Note: In this example, the
<hostname or ip address>
is the hostname or IP address of the system running Keycloak . If hostname is used, the host must be resolvable. If using the free lab environment this will be the IP address forol-server
Example Output:
[luna.user@lunabox Desktop]$ ssh -L 8080:localhost:8080 oracle@130.162.241.27 Activate the web console with: systemctl enable --now cockpit.socket Last login: Wed Sep 28 10:29:42 2022 from 147.154.151.58 [oracle@ol-server ~]$
Open a new browser session (on the Virtual Desktop) and enter the URL.
http://localhost:8080
Example Output:
Login to the Keycloak Administration Console
Click on the called
Administration Console
Example Output:
Enter the Administrator user's credentials, and click the
Sign In
button.- User name =
admin
- Password =
admin
The main page for the Keycloak Master Realm is displayed.
Example Output:
- User name =
Create a new Realm
Keycloak defines Realms as a space where objects, users, applications, roles and groups are managed. The Realms within a Keycloak deployment are administered from within the Keycloak Admin Console. Once logged in to the Keycloak Admin Console there are two types of realms:
Master Realm
- This realm is created as part of the initial Keycloak deployment and contains details of the Administrator user created during the initial login. It is important that themaster realm
is only used to create and manage the other realms defined on the system. So the administrator user logs onto the master realm, and manages other realms within their organization from there.Other Realms
- These realms are created by the administrator from within the master realm. The administrator uses these realms to manage, and delineate, the creation of users within an organization and the applications used/required by those users. The realms created are isolated from each other and can only manage the users and applications assigned to any individual realm.
Further information about using, creating and managing realms can be located in the upstream Keycloak documentation.
For now, this lab will demonstrate setting up an example Realm and adding a new User to that realm.
Click on the hamburger menu, then click the drop-down listbox showing Master. Now click on the
Create Realm
button.Example Output:
The
Create realm
screen is displayed. Enter the value test in theRealm Name
field, the press theCreate
button.Example Output:
The newly created Realm's "Welcome" page is diplayed.
Example Output:
Create a new User in the new Realm
Click on the hamburger menu, and select
Users
Example Output:
The
Users
screen is displayed. Click on theCreate new user
button.Example Output:
The
Create User
screen is displayed. Enter the following details into these fields:Username
- user01First Name
- FooLast Name
- Bar
Click on the
Create
button.Example Output:
The new user's details are displayed.
Example Output:
Click on the
Credentials
tabExample Output:
Click on the
Set Password
button. A dialogue box is displayed, etner the following details:Password
- user01Password confirmation
- user01Temporary
- Click to set toOff
Important Note: An insecure password is used for illustrative purposes only. Production deployment would define secure password requirements as part of Keycloak administration.
Example Output:
Click on the
Save
button, a confirmation dialogue box is dsplayed. Click on theSave Password
button.Example Output:
A confirmation screen is displayed, confirming a password has been set.
Example Output:
Verify the New User is Setup Correctly
The next step is to to verify that the newly created user's details are correctly configured by logging in to the account console using the new user's credentials.
(On Luna Desktop) Login to the Keycloak Account Console. Open a new tab on the browser and enter the URL:
http://localhost:8080/realms/test/account
Example Output:
Click the
Sign In
button (top right-hand side of browser).Example Output:
Enter the credentials for
user01
previously defined:Username -
user01
Password -user01
Click on the
Sign In
button.Example Output:
The Welcome to Keycloak account management page is displayed.
Example Output:
(Optional) Confirm the Keycloak repository is stored within Postgres.
It can be confirmed that Keycloak has indeed created a schema within the Postgres container by returning to the previously opened browser tab on the Virtual Desktop's environment used to connect to PGAdmin
Connect to PGAdmin as previously detailed (or reuse the existing open browser tab).
Expand the tree in the left-hand panel (called
Browser
) by clicking on the icon calledServers
, followed byDatabases
,keycloakDB
,Schemas
,public
,Tables
. This shows all of the Keycloak schema's tables which are used to record any changes made within the Keycloak Admin console.Example Output:
Summary
This completes the demonstration detailing how to configure Podman to run a Keycloak container that stores it's data in a Postgres container which is also running in Podman.
For More Information
See other related resources: