There is an option not to overwrite an already existing realm.
When I understand your shell script right, this is exactly what you want to do.
When using the Docker image, it’s just to copy/mount the realm.json file to the container and set the env var KEYCLOAK_IMPORT to the location of your json file.
What I could think of, is… a bit weird, but perhaps worth thinking about?
Put a script in the startup-scripts folder, which starts a decoupled bash/shell process, so that the script in the folder can be terminated immediately and does not block anything.
In the new process, you periodically poll the /auth endpoint until it is available (or until a timeout), then you can run your realm creation. After that, terminate the process.
I know, polling is not what we really want, but… often the only possibility. Kubernetes is doing the same with the readiness checks.
I got your idea, but the script inside startup-scripts folder block the server boot, and never reach his target, take a look at the script:
#!/bin/bash
export PATH=$PATH:$JBOSS_HOME/bin
for i in {1..10}; do
kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user $KEYCLOAK_USER --password $KEYCLOAK_PASSWORD
admin_realm=$(kcadm.sh get realms/admin)
if [ -z "$admin_realm" ]; then
kcadm.sh create realms -f $JBOSS_HOME/dojot/admin.json
else
echo "the realm admin already exists."
fi
sleep 5s
done
It would works if there was a way to enable it runs as a decoupled process. Do you know how ?
Your pasted script should be the one being called from the one in startup-scripts.
Let’s assume, you put your script to /tmp/createRealm.sh
Then, put a script to the startup-scripts folder, e.g. .../startup-scripts/startRealmCreationCheckInOwnProcess.sh
This file should look like:
#!/bin/bash
echo "start realm creation/check in own process"
/tmp/createRealm.sh &> /dev/null & disown
echo "realm creation/check called, terminating this process"
Be aware, that with &> /dev/null, you won’t see any output of the called script. Try to omit it to see something on stdout.
P.S.: In your loop, you should of course check the availability of /auth, e.g. with curl, and only execute your kcadm commands if available. Once executed, you should exit the loop.
Just a curiosity, I note that the directory /opt/jboss/startup-scripts isn’t available by default inside docker image, was necessary to create it. Do you know why ?
I don’t know exactly, but I guess it’s not existent, b/c it’s only for custom scripts, and as long as there are not scripts, no directory is needed.
Also, as it’s a container, one should not need to “created” it, but just mount volumes as such a directory into the container on startup.
Thanks for the information, guys. Still useful nearly 2 years later!
I figured I’d share my end product so that it might help other people too. It uses your suggestions @dasniko while being a bit more compact.
Still using the Wildfly distro so I imagine this will all change with Quarkus but… sharing here anyway.
#!/bin/bash
function configure_keycloak(){
while :
do
if curl http://localhost:8080/auth; then
/opt/jboss/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user KEYCLOAK --password KEYCLOAK
/opt/jboss/keycloak/bin/kcadm.sh create realms -s realm=APP -s enabled=true
/opt/jboss/keycloak/bin/kcadm.sh create users -r APP -s username=APPUSER -s enabled=true -s email=APPUSER -s firstName=APPUSER -s lastName=APPUSER
break;
fi
sleep 5
done
touch /tmp/keycloak_configured
}
echo “Launching background process to configure Keycloak”
configure_keycloak &> /dev/null & disown
echo “Launched background process to configure Keycloak”