Keycloak on Docker with Nginx SSL proxy

JBoss Keycloak is available as a Docker image. It’s all fun and games until you’ll try to run it behind SSL reverse proxy like I do for all my services. Despite settings all required HTTP headers on the proxy side (Nginx in my case) like:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

it fails to pass all the requests to the Docker Keycloak image (running on Wildfly server). It’s because the Keycloak configuration is not prepared to be run behind the SSL reverse proxy. Configuring it is quite simple as all you need is to set:

proxy-address-forwarding="true"  

in the http-listener element in standalone.xml configuration.

However, how to do that in case of a Docker image? I came up with two solutions:

Create your own simplified Dockerfile which alters the Wildfly configuration.

It might be as simple as:

    FROM jboss/keycloak:latest
    
    USER root
    RUN yum install -y xmlstarlet
    
    USER jboss
    RUN xmlstarlet ed --inplace \
        -N x="urn:jboss:domain:undertow:3.0" \
        -a "//x:http-listener" \
        -t attr \
        -n 'proxy-address-forwarding' \
        -v 'true' \
        /opt/jboss/keycloak/standalone/configuration/standalone.xml

It basically installs the xmlstarlet which we’ll use to modify the Wildfly XML configuration file and it adds required attribute to the http-listener.

You can also use this Dockerfile to put your admin password and username accordingly and do not pass them as a environment variables from the command line which isn’t the best idea anyway.

Alter configuration of running image

If you already have Keycloak image running, you can alter the configuration by using JBoss CLI and issue following command:

    docker exec {CONTAINER} /opt/jboss/keycloak/bin/jboss-cli.sh --connect \
        "/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding, value=true)"

You can then check if it’s correctly set by invoking following command:

    docker exec {CONTAINER} /opt/jboss/keycloak/bin/jboss-cli.sh --connect \
        "/subsystem=undertow/server=default-server/http-listener=default:read-resource"

After these changes you shouldn’t have any problems with running Keycloak behind SSL reverse proxy.

The image is available at Docker Hub here: piotrnowicki/keycloak