Developing Keycloak templates with Docker

An article, posted more than 6 years ago filed in docker, keycloak, template, javascript, development, css & html.

I haven’t had much need for isolating services, something that Docker is really good at. Most dependencies of my Rails apps are covered by Gemfile anyway (and packages.json for JavaScript) and reasonably isolated with rbenv. I don’t experience version related issues very often, as I try to stay reasonably up to date and not rely too much on the very state of the art. For temporary projects, however, Docker is a great solution, even for me :o I don’t want an entire JBoss suite running on my machine, so when I had to develop a Keycloak template I knew that Docker would be the right tool. While I’m going to discuss the specifics of getting started with a Keycloak image, the workflow described is replaceable by any other.

Developing Keycloak templates with Docker

So what about Keycloak? Keycloak is a role based authorization and authentication tool that can help an organization to centralize managing user accounts and their roles. Client apps connect via OpenID (or SAML) to offer central / “single sign on” - authentication. I’m currently assisting an organization implementing it.

Installing Docker

Simply run:

brew cask install docker

And start it:

  1. Cmd+Space
  2. Type docker
  3. Hit enter

A docker.app will be installed in your Applications folder. After you’ve started it, its GUI will be accessible from the menu bar (don’t really know why actually).

Running Keycloak

(Don’t we need to install something? Nope :) ) While you can use the in memory H2 database, I suggest using a database docker.

docker run --name mysql -e MYSQL_DATABASE=keycloak -e MYSQL_USER=keycloak -e MYSQL_PASSWORD=password -e MYSQL_ROOT_PASSWORD=root_password -d mysql

What we’re doing here is name the instance (—name mysql) of the mysql docker image (the mysql reference at the end of the line) and pass the DATABASE, USER AND PASSWORD as environment variables, setting up these defaults, and running it as a daemon (the -d option).

Next run the keycloak daemon:

docker run --name keycloak --link mysql:mysql -d jboss/keycloak

We name the instance keycloak, base it on the jboss/keycloak image, and link mysql to the already running mysql instance. Since we used keycloak/keycloak/password as default parameters for the MySQL database, we don’t have to pass any other parameters.

If you have something running at port 8080 try adding -p 9080:8080, which makes the outside port 9080 translate to the internal 8080 port to which the internal Wildfly server is serving to:

docker run -p 9080:8080 --name keycloak --link mysql:mysql -d jboss/keycloak

Now you won’t have access to the admin console just yet, because there is no admin user.

docker exec keycloak keycloak/bin/add-user-keycloak.sh -u admin -p admin

Here we’re running a command on the keycloak machine (keycloak/bin/add-user-keycloak.sh -u admin -p admin, which creates admin:admin username/password) on the docker instance named keycloak.

Ready for the next step.

Creating a theme

You can open the bash console to the Keycloak instance and start editing templates using vi:

docker exec -i -t -u 0 keycloak /bin/bash
cd /opt/jboss/keycloak/themes
cp -R #STOP HERE!

We’re going to hold here. This is not a good idea. While we could use vi now to edit a duplicated theme, changes are “locked” in the instance, and I just need version control. The first line could use some explanation though. It says execute /bin/bash on the keycloak instance, and make it interactive (-i), with tty (-t) support running as user 0 (-u 0) (the root user).

Mounting a local directory

Note: This is only good advice for development; when running docker in production you want to check out Docker Volumes.

Remember that themes are installed in /opt/jboss/keycloak/themes within the instance.

We want a new new theme directory within that directory. But then not accessible just within that instance, but also from the outside in such that it enables us to use whatever editor we want to use locally.

Navigate to wherever you want to put the new theme’s source files, then:

mkdir the_theme
cd the_theme
git init .
echo “# The Theme\n\nRaison d’etre here” > README.md
pwd

Open a new terminal (or tab) and navigate to the same directory and mount the source directory to the target (the pwd command outputs the absolute location)

docker stop keycloak && docker rm keycloak
docker run -d -it -p 9080:8080 --name keycloak --link mysql:mysql --mount type=bind,source=`pwd`,target=/opt/jboss/keycloak/themes/the_theme jboss/keycloak

(or use the old syntax):

docker run -d -it -p 9080:8080 --name keycloak --link mysql:mysql -v `pwd`:/opt/jboss/keycloak/themes/the_theme jboss/keycloak

You may now check the image whether it works:

docker exec -i -t -u 0 keycloak /bin/bash
cd /opt/jboss/keycloak/themes
cat README.md # Should print “# The Theme…”

You may want to reuse an existing theme:

cp -R ../keycloak/* .

You need to rename the theme’s name in META-INF/keycloak-themes.json-file to match the directory name; otherwise booting the admin console may fail.

Make also sure themes are recompiled on the fly and caching is disable for more predictable development:

  1. Run vi /opt/jboss/keycloak/standalone/configuration/standalone.xml
  2. hit the “/“-key to start searching and type “cacheTheme” and hit return
  3. the cursor should be where the Theme’s cache settings are located.
  4. Set both xml properties to false: Type “i” to move into Interactive mode, change the xml to match <cacheThemes>false</cacheThemes> and <cacheTemplates>false</cacheTemplates>
  5. hit ‘esc’, type “:wq” (which should Write the file and Quit vi) (it really isn’t that hard ;) )
  6. type exit

Restart the instance: docker restart keycloak

To see the new theme login to the console:

  1. Login to the console, e.g. visit http://localhost:9080
  2. Go to Realm settings -> Themes
  3. Set all dropdowns to ’the_theme’ (equals the directory name)

Editing the theme

While you can tweak any layout with CSS and JavaScript (the Freemarker Template Language you’ll learn on the fly), I’m not really fond of Keycloak’s default HTML, and especially its use of classes. I guess they’ve never been to the CSS Zen Garden (I’m getting old).

You can still fall back to templates in base, but by copying an .ftl file from the base directory you can modify that part.

Knowledge of CSS and HTML will be sufficient for the rest of the journey, although a few hints before you leave:

Further reading:

Photo by Thomas Kelley on Unsplash

Op de hoogte blijven?

Maandelijks maak ik een selectie artikelen en zorg ik voor wat extra context bij de meer technische stukken. Schrijf je hieronder in:

Mailfrequentie = 1x per maand. Je privacy wordt serieus genomen: de mailinglijst bestaat alleen op onze servers.