title: Keycloak behind nginx reverse proxy with SSL
body: <p>I have a problem with setting up an environment (all of them on the same machine) consisting of:</p>
  <ul>
  <li><p>Nginx - reverse proxy</p>
  </li>
  <li><p>Docker:</p>
  <ul>
  <li>Keycloak - authorization</li>
  <li>Gateway with microservices (based on java / spring boot)</li>
  </ul>
  </li>
  </ul>
  <p>I think my problem is connected with SSL certificate. My certificate with private key is in nginx/ssl folder and added in configuration. Keycloak is up with options for running behind reverse proxy. When I want to connect with microservices behing gateway I am redirected to keycloak login page. After filling form and submit it I'm getting this message: <code>connection timed out example.com/ip_address:443</code> (of course I changed the original domain and ip). Why I'am getting this kind of error? Below I putted configuration files that I am using (domain, ip's and password changed).</p>
  <h2>Keycloak - docker-compose.yml</h2>
  <pre><code>version: '3'
  services:
    db:
      image: postgres
      container_name: keycloak_db
      ports:
        - &quot;5433:5432&quot;
      restart: always
      volumes:
        - postgres-vol:/var/lib/postgresql/data
      environment:
        POSTGRES_USER: ${DB_USERNAME}
        POSTGRES_PASSWORD: ${DB_PASSWORD}
        POSTGRES_DB: ${DB_NAME}
    adminer:
      image: adminer
      container_name: keycloak_adminer
      restart: always
      ports:
        - &quot;5001:8080&quot;
      depends_on:
        - db
    keycloak:
      image: jboss/keycloak:12.0.2
      container_name: keycloak
      environment:
        - KEYCLOAK_USER=${KEYCLOAK_USER}
        - KEYCLOAK_PASSWORD=${KEYCLOAK_PASSWORD}
        - DB_VENDOR=postgres
        - DB_ADDR=${DB_ADDR}
        - DB_PORT=${DB_PORT}
        - DB_USER=${DB_USERNAME}
        - DB_PASSWORD=${DB_PASSWORD}
        - DB_DATABASE=${DB_NAME}
        - PROXY_ADDRESS_FORWARDING=true
        - REDIRECT_SOCKET=proxy-https
        - KEYCLOAK_FRONTEND_URL=${KEYCLOAK_FRONTEND_URL}
      ports:
        - &quot;8090:8080&quot;
      healthcheck:
        test: &quot;curl -f http://localhost:8080/auth || exit 1&quot;
        start_period: 30s
      depends_on:
        - db
  
  volumes:
    postgres-vol:
  
  </code></pre>
  <h2>nginx.conf (only server configuration)</h2>
  <pre><code>    server {
          listen 80; 
          server_name example.com;
          return 301 https://$host$request_uri;
      }
          
      server  {
          
          listen 443 ssl default_server;
          listen [::]:443 ssl default_server;
          ssl_certificate /etc/nginx/ssl/cert.cer;
          ssl_certificate_key /etc/nginx/ssl/cert.key;
  
          location /404{          
          }
              
          location /auth {
              proxy_pass http://address_ip:8090;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Host $server_name;                     
          }
          
          location /auth/admin {
              proxy_pass http://address_ip:8090;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Host $server_name;         
          }
          
          location / {
              proxy_pass http://address_ip:8080;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto &quot;https&quot;;
              add_header        Front-End-Https        on;            
          }
          
          error_page 404 /40x.html;
              location = /40x.html {
                  root /usr/share/nginx/html;
          }
          
          error_page 502 /50x.html;
              location = /50x.html {
                  root /usr/share/nginx/html;
          }
  
      }   
  </code></pre>
  <h2>Gateway - application.yml</h2>
  <pre><code>server:
    port: 8080
    use-forward-headers: true
  
  logging:
    level:
      root: INFO
      org.springframework.web: INFO
      org.springframework.web.HttpLogging: DEBUG
      org.springframework.security: DEBUG
      org.springframework.security.oauth2: DEBUG
      org.springframework.cloud.gateway: DEBUG
  
  spring:
    profiles:
      active: @activatedProperties@
    cloud:
      gateway:
        globalcors:
          corsConfigurations:
            '[/**]':
              allowedOrigins: &quot;*&quot;
              allowedMethods:
                - GET
                - POST
                - PUT
                - PATCH
                - DELETE
              allowedHeaders: &quot;*&quot;
    autoconfigure:
      exclude: org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration
    thymeleaf:
      cache: false
  
  #'dev' proflie
  ---
  
  spring:
    profiles: dev
    security:
      oauth2:
        client:
          registration:
            gateway:
              provider: keycloak
              client-id: client
              client-secret: secret
              authorization-grant-type: authorization_code
              redirect-uri-template: &quot;{baseUrl}/login/oauth2/code/{registrationId}&quot;
              scope:
                - openid
                - email
                - profile
          provider:
            keycloak:
              authorization-uri: https://dev.example.com/auth/realms/gateway/protocol/openid-connect/auth
              token-uri: https://dev.example.com/auth/realms/gateway/protocol/openid-connect/token
              user-info-uri: https://dev.example.com/auth/realms/gateway/protocol/openid-connect/userinfo
              user-name-attribute: preferred_username
              jwk-set-uri: https://dev.example.com/auth/realms/gateway/protocol/openid-connect/certs
  
  #'prod' proflie
  ---
  
  spring:
    profiles: prod
    security:
      oauth2:
        client:
          registration:
            gateway:
              provider: keycloak
              client-id: client
              client-secret: secret
              authorization-grant-type: authorization_code
              redirect-uri-template: &quot;{baseUrl}/login/oauth2/code/{registrationId}&quot;
              scope:
                - openid
                - email
                - profile
          provider:
            keycloak:
              authorization-uri: https://example.com/auth/realms/gateway/protocol/openid-connect/auth
              token-uri: https://example.com/auth/realms/gateway/protocol/openid-connect/token
              user-info-uri: https://example.com/auth/realms/gateway/protocol/openid-connect/userinfo
              user-name-attribute: preferred_username
              jwk-set-uri: https://example.com/auth/realms/gateway/protocol/openid-connect/certs
  
  </code></pre>
  <h2>Gateway dockerfile</h2>
  <pre><code>FROM openjdk:11-jdk-slim
  WORKDIR /opt/workdir
  
  ARG CERT_PATH=&quot;./build/certificates/prod.pfx&quot;
  ARG CERT_NAME=&quot;prod.pfx&quot;
  
  #import cert into java
  COPY $CERT_PATH /opt/workdir/
  
  RUN echo yes | keytool -importkeystore -srckeystore prod.pfx -srcstorepass pass -srcstoretype pkcs12 -destkeystore prod.p12 -deststoretype pkcs12 -deststorepass pass
  COPY target/gateway-0.0.1-SNAPSHOT.jar /app/app.jar
  RUN jarsigner -keystore prod.p12 -storepass pass /app/app.jar 1
  CMD [&quot;java&quot;, &quot;-jar&quot;, &quot;/app/app.jar&quot;]
  EXPOSE 8080
  
  </code></pre>