<p>There are many questions like this I can find in the internet but none of the solutions provided worked.</p>
<p>I am using <code>jboss/keycloak:14.0.0</code> docker image. The following properties are set in my <code>ConfigMap</code>:</p>
<pre><code>KEYCLOAK_FRONTEND_URL: /mycontext/access-management
PROXY_ADDRESS_FORWARDING: &quot;true&quot;

</code></pre>
<p>Please note that, change the <code>KEYCLOAK_FRONTEND_URL</code> to an absolute URL like this <code>https://mycompany.com/mycontext/access-managemen</code> makes no difference.</p>
<p>Now the ingress has been defined as below:</p>
<pre><code>Path: /mycontext/access-management(/|$)(.*)
Rewrite To: /$2
Annotations:
    ingress.kubernetes.io/ssl-redirect: &quot;False&quot;
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header X-Request-ID $request_id;
      proxy_set_header X-Trace-ID $request_id;
      gzip off;
    nginx.ingress.kubernetes.io/proxy-connect-timeout: &quot;180&quot;
    nginx.ingress.kubernetes.io/proxy-read-timeout: &quot;180&quot;
    nginx.ingress.kubernetes.io/proxy-send-timeout: &quot;180&quot;
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/server-snippet: |
      add_header X-Request-ID $request_id;
      add_header X-Trace-ID $request_id;
    nginx.org/redirect-to-https: &quot;True&quot;

</code></pre>
<p>What happens is very strange. See below it shows you where it takes me when I hit a URL:</p>
<pre><code>Go to [server]/mycontext/access-management =takes you to=&gt; [server]/auth
Go to [server]/mycontext/access-management/auth =takes you to=&gt; [server]/mycontext/access-management/auth (works fine)

</code></pre>
<p>As you can see the second link works fine and you can see the Keycloak Welcome page with a number of links in it. One of the links is <code>Administration Console</code> that is broken. If you hover your mouse the link is <code>[server]/mycontext/access-management/admin</code> instead of <code>[server]/mycontext/access-management/auth/admin</code> (comparing it with my local Keycloak server). Now if we ignore the link and put the right path in the address bar as <code>[server]/mycontext/access-management/auth/admin</code> another strange thing happens and that changes the URL to <code>[server]/auth/mycontext/access-management/admin/master/console/</code>.</p>
<p>I really don't understand what is happening here. Setting <code>KEYCLOAK_FRONTEND_URL</code> on my local also breaks the links.</p>
<p>I have tried to change the <code>rewrite</code> annotation of the ingress to <code>/mycontext/access-management/$2</code> but this configuration doesn't work at all.</p>
<p>In the Keycloak documentation <a href="https://www.keycloak.org/docs/latest/server_installation/#_hostname" rel="nofollow noreferrer">here</a> it talks about a property named <code>adminUrl</code>, however, setting <code>-DadminUrl</code> or <code>-Dkeycloak.adminUrl</code> seems to be ignored completely by the docker image when using <code>JAVA_OPTS_APPEND</code> according to JBoss documentation page.</p>
<p>What have I missed here? Is there anything that I have missed in my configuration?</p>
<p>Please note that, we have no choice other than exposing it under a context-path followed by the name (i.e. <code>/mycontext/access-management</code>). This is because of both our client requirements as well as the fact that we have many micro-services deployed under <code>/mycontext</code> each of which has its own ingress configuration.</p>
<p>Any help is appreciated.</p>

<p>Okay I managed to get this working by gathering all the solutions that are mentioned out there.</p>
<p>So basically, <code>web-context</code> needs to be set and that's something that is not mentioned anywhere in any documentation except word of mouth.</p>
<p>To set that, you can write a <code>cli</code> script:</p>
<pre><code>set CONTEXT=${env.KEYCLOAK_WEB_CONTEXT}
echo $CONTEXT
embed-server --server-config=standalone-ha.xml --std-out=echo
/subsystem=keycloak-server/:write-attribute(name=web-context,value=$CONTEXT)
stop-embedded-server

embed-server --server-config=standalone.xml --std-out=echo
/subsystem=keycloak-server/:write-attribute(name=web-context,value=$CONTEXT)
stop-embedded-server
</code></pre>
<p>This is mentioned <a href="https://stackoverflow.com/questions/46892613/keycloak-undertow-jboss-cli-set-web-context-from-environment-variable">here</a> but the important things are 1. you need to start embed server otherwise there is no server to connect to and second you should change both <code>standalone.xml</code> and <code>standalone-ha.xml</code> unless you know which one exactly you are running.</p>
<p>See this answer <a href="https://stackoverflow.com/a/58929616/988738">here</a> on how to copy custom scripts to your docker image.</p>
<p><strong>However, there is one important point here! Although Keycloak documentation says that you can change the front-end URL to whatever you want, you actually HAVE TO add <code>/auth</code> at the end of your new URL. It seems many pages in Keycloak are hardcoded to that path</strong></p>
<p>Now you need to set these two properties in your ConfigMap:</p>
<pre><code>#ConfigMap
# Has to end with /auth and has to be absolute URL
KEYCLOAK_FRONTEND_URL: https://your.website.address/mycontext/access-management/auth
PROXY_ADDRESS_FORWARDING: &quot;true&quot;
# The following is our own env var that will be used by the above cli
# Note that it SHOULD NOT start with / and it must END with /auth
KEYCLOAK_WEB_CONTEXT: mycontext/access-management/auth

</code></pre>
<p>This is a bit annoying because <code>KEYCLOAK_FRONTEND_URL</code> cannot be relative path and has to be full absolute URL. The issue is you constructing that makes things not nice and elegant. Luckily we have a <code>host</code> property in <code>global</code> and is shared across the Helm's subcharts, so I could use it but really this makes the design a bit nasty.</p>
<p>But that's not just this, because of all these crap settings, now you have to change your <code>liveness</code> and <code>readiness</code> probes to <code>GET /mycontext/access-management</code>
And even worst, if you have micro-services, which is nearly 20 for us, you'll need to change all the auth server URLs that was previously as simple as <code>http://access-management:8080/auth</code> to <code>http://access-management:8080/mycontext/access-management/auth</code>.</p>
<p>Now make sure your ingress also includes this new path plus another important property <code>proxy-buffer-size</code>. If you don't have a large buffer size Keycloak requests may not work and you will get <code>Bad Gateway</code> error:</p>
<pre><code>Path: /mycontext/access-management(/|$)(.*)
Rewrite To: /mycontext/access-management/$2
nginx.ingress.kubernetes.io/proxy-buffer-size: 8k 
</code></pre>
<p>I really wished we could manage this with ingress without having to touch all these things but it seems not possible. I hope <code>Keycloak.X</code> will solve all these bad coding.</p>
