Search code examples
dockersslkeycloaklets-encryptkeycloak-services

Keycloak 22.0.5 Docker production deployment SSL certificate error


I tried to deploy Keycloak in production mode. These are the Dockerfile, docker build command and docker run command that I have used.

before deploying keycloak, I have created the docker network and mysql database.

1. create network:

docker network create keycloak-network

2. deploy kc_mysql db (a mysql database):

docker run -v /var/lib/docker/volumes/kc_mysql:/var/lib/mysql -p 3307:3306 --name kc_mysql -d --net keycloak-network -e MYSQL_DATABASE=keycloak -e MYSQL_USER=keycloak -e MYSQL_PASSWORD=xxxx -e MYSQL_ROOT_PASSWORD=yyyy mysql

Then I built docker image and run the container,

3. Dockerfile:

# Use the builder image to build with the necessary configurations
FROM quay.io/keycloak/keycloak:latest as builder


# Enable health and metrics support
ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
ENV KC_FEATURES=token-exchange

# Configure a database vendor
ENV KC_DB=mysql

WORKDIR /opt/keycloak

# Build the configuration
RUN /opt/keycloak/bin/kc.sh build --cache=ispn

# Final image
FROM quay.io/keycloak/keycloak:latest

# Copy the built artifacts from the builder stage
COPY --from=builder /opt/keycloak/ /opt/keycloak/

ENV KC_DB=mysql
ENV KC_DB_URL=jdbc:mysql://kc_mysql:3306/keycloak
ENV KC_DB_USERNAME=yyyy
ENV KC_DB_PASSWORD=xxxx
ENV KC_HOSTNAME=localhost



# Set the entry point to start Keycloak
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

4. Docker build command

docker build . -t mykeycloak

5. Docker run command

docker run -v /var/lib/docker/volumes/keycloak:/opt/keycloak/conf -v /etc/letsencrypt/live/abc.xyz.com:/etc/x509/https -e KC_HTTPS_CERTIFICATE_KEY_FILE=/etc/x509/https/privkey.pem -e KC_HTTPS_CERTIFICATE_FILE=/etc/x509/https/fullchain.pem --name mykeycloak -p 8443:8443 -d --net keycloak-network -e KEYCLOAK_ADMIN=admin-e KEYCLOAK_ADMIN_PASSWORD=admin mykeycloak start --optimized

The SSL certificates are used. But I get the below logs when I Run the container. At the bottom of logs I got the error related to SSL certificates.

INFO [org.keycloak.common.Profile] (main) Preview features enabled: token-exchange
INFO  [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: Base URL: <unset>, Hostname: localhost, Strict HTTPS: true, Path: <request>, Strict BackChannel: false, Admin URL: <unset>, Admin: <request>, Port: -1, Proxied: false
 WARN  [io.quarkus.agroal.runtime.DataSources] (main) Datasource <default> enables XA but transaction recovery is not enabled. Please enable transaction recovery by setting quarkus.transaction-manager.enable-recovery=true, otherwise data may be lost if the application is terminated abruptly
 WARN  [org.infinispan.PERSISTENCE] (keycloak-cache-init) ISPN000554: jboss-marshalling is deprecated and planned for removal
 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000556: Starting user marshaller 'org.infinispan.jboss.marshalling.core.JBossUserMarshaller'
INFO  [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000088: Unable to use any JGroups configuration mechanisms provided in properties {}. Using default JGroups configuration!
 INFO  [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000078: Starting JGroups channel `ISPN`
INFO  [org.jgroups.JChannel] (keycloak-cache-init) local_addr: 73276fc8-8609-4db5-a34a-73d73e92dbb1, name: 768a15960a95-45041
2023-11-14 04:30:29,649 WARN  [org.jgroups.protocols.UDP] (keycloak-cache-init) JGRP000015: the send buffer of socket MulticastSocket was set to 1MB, but the OS only allocated 212.99KB
 WARN  [org.jgroups.protocols.UDP] (keycloak-cache-init) JGRP000015: the receive buffer of socket MulticastSocket was set to 20MB, but the OS only allocated 212.99KB
WARN  [org.jgroups.protocols.UDP] (keycloak-cache-init) JGRP000015: the send buffer of socket MulticastSocket was set to 1MB, but the OS only allocated 212.99KB
WARN  [org.jgroups.protocols.UDP] (keycloak-cache-init) JGRP000015: the receive buffer of socket MulticastSocket was set to 25MB, but the OS only allocated 212.99KB
INFO  [org.keycloak.broker.provider.AbstractIdentityProviderMapper] (main) Registering class org.keycloak.broker.provider.mappersync.ConfigSyncEventListener
 INFO  [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) 768a15960a95-45041: no members discovered after 2004 ms: creating cluster as coordinator
INFO  [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000094: Received new cluster view for channel ISPN: [768a15960a95-45041|0] (1) [768a15960a95-45041]
INFO  [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000079: Channel `ISPN` local address is `768a15960a95-45041`, physical addresses are `[172.22.0.3:48009]`
 WARN  [org.infinispan.CONFIG] (keycloak-cache-init) ISPN000569: Unable to persist Infinispan internal caches as no global state enabled
INFO  [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: 768a15960a95-45041, Site name: null
INFO  [org.infinispan.CLUSTER] (main) ISPN000080: Disconnecting JGroups channel `ISPN`

ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Failed to start server in (production) mode
ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: /etc/x509/https/fullchain.pem
ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) Key material not provided to setup HTTPS. Please configure your keys/certificates or start the server in development mode.
ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) For more details run the same command passing the '--verbose' option. Also you can use '--help' to see the details about the usage of the particular command.

As I see in many places, I changed the permissions for certificates location /etc/letsencrypt/live/abc.xyz.com

the certificates are;

drwxr-xr-x. 2 root user1  93 Nov  9 13:47 .
drwx--x--x. 3 root root      48 Nov  9 13:47 ..
lrwxrwxrwx. 1 root user1  44 Nov  9 13:47 cert.pem -> ../../archive/abc.xyz.com/cert1.pem
lrwxrwxrwx. 1 root user1  45 Nov  9 13:47 chain.pem -> ../../archive/abc.xyz.com/chain1.pem
lrwxrwxrwx. 1 root user1  49 Nov  9 13:47 fullchain.pem -> ../../archive/abc.xyz.lk/fullchain1.pem
lrwxrwxrwx. 1 root user1  47 Nov  9 13:47 privkey.pem -> ../../archive/abc.xyz.com/privkey1.pem
-rw-r--r--. 1 root user1  692 Nov  9 13:47 README

I am the user1, but there is another user user2. now I checked the permission for certificates for root, user1 and user2. Permissions have no problem.

  sudo -u user1 file ../../archive/abc.xyz.com/fullchain1.pem
    ../../archive/abc.xyz.com/fullchain1.pem: PEM certificate
    
    sudo -u user2 file ../../archive/abc.xyz.com/fullchain1.pem
    ../../archive/abc.xyz.com/fullchain1.pem: PEM certificate

But the error exists. My all previous docker images have root user in when I check using docker inspect <image_name>.

But for this keycloak custom docker image, the user is 1000 (for user2).

 "Config": {
            "Hostname": "768a15960a95",
            "Domainname": "",
            "User": "1000",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "8080/tcp": {},
                "8443/tcp": {}
            },

"Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/docker/volumes/keycloak",
                "Destination": "/opt/keycloak/conf",
                "Mode": "",
                "RW": true,
                "Propagation": "rslave"
            },
            {
                "Type": "bind",
                "Source": "/etc/letsencrypt/live/abc.xyz.com",
                "Destination": "/etc/x509/https",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

In host;

grep 1000 /etc/passwd
>>user2

grep 1001 /etc/passwd
>>user1

I tried the keyword USER in Dockerfile.

USER root or USER 1001

But it didn't change the user in image's or container's user.

I am the user1 (1001) who built and run the keycloak container, but thisis unusual and can someone explain what happened here and although the permissions are set to certificates files in host, why the keycloak container does not up in production mode. How can i run keycloak avoiding the error (main) ERROR: /etc/x509/https/fullchain.pem. Without using certificates, the container could be run in development mode without problem using start-dev. But i need the production mode deployment.


Solution

  • After few days I could find an answer for this issue.

    vendor: quay.io/keycloak/keycloak

    version: Keycloak version is 22.0.5

    First I moved to docker-compose;

    version: '3'
    
    services:
      mykeycloak:
        build:
          context: .
          dockerfile: Dockerfile
        image: my-keycloak:latest
        container_name: mykeycloak
        environment:
          - KC_HTTPS_CERTIFICATE_KEY_FILE=/etc/x509/https/privkey.pem
          - KC_HTTPS_CERTIFICATE_FILE=/etc/x509/https/fullchain.pem
          - KC_DB=mysql
          - KC_DB_URL=jdbc:mysql://kc_mysql:3306/keycloak
          - KC_DB_USERNAME=<kc_username>
          - KC_DB_PASSWORD=<kc_password>
          - KC_HOSTNAME=abc.xyz.com
          - KC_HOSTNAME_PORT=8443
          - KC_HEALTH_ENABLED=true
          - KC_METRICS_ENABLED=true
          - KC_FEATURES=token-exchange
          - KEYCLOAK_ADMIN=<admin>
          - KEYCLOAK_ADMIN_PASSWORD=<admin_password>
        volumes:
          - /var/lib/docker/volumes/keycloak:/opt/keycloak/conf
          - /etc/letsencrypt/live/abc.xyz.com/fullchain.pem:/etc/x509/https/fullchain.pem
          - /etc/letsencrypt/live/abc.xyz.com/privkey.pem:/etc/x509/https/privkey.pem
        ports:
          - "8443:8443"
        networks:
          - keycloak-network
        command: ["start"]
    
    networks:
      keycloak-network:
        external: true
    

    Here, I've changed HOSTNAME from localhost to my real domain name abc.xyz.com.

    I get the same error as above my question. The problem seems to be a permission problem on my host. Docker user does not have proper permissions to use fullchain.pem. Now tried this command on my host.

    Now, following is the solving steps:

    1. I deployed Keycloak in development mode

    For this I had to comment below two environment variables on docker-compose as below:

     - KC_HTTPS_CERTIFICATE_KEY_FILE=/etc/x509/https/privkey.pem
     - KC_HTTPS_CERTIFICATE_FILE=/etc/x509/https/fullchain.pem
    

    Then changed command from start to start-dev as below:

    command: ["start-dev"]
    
    1. Then the container is running and I checked whether it is a permission issue or not, using a cat command to the /etc/x509/https/fullchain.pem file as below..

      docker exec -it <keycloak_container_id> cat /etc/x509/https/fullchain.pem

    response:

    cat: /etc/x509/https/fullchain.pem: Permission denied
    

    Now, it was clear that the issue is a permission problem.

    1. Then I execute the below command and solved the permission problem.

      chmod -R 644 /etc/letsencrypt/live/abc.xyz.com/fullchain.pem

    2. Again I try the same command in step (2) docker exec -it <keycloak_container_id> cat /etc/x509/https/fullchain.pem

    response:

    -----BEGIN CERTIFICATE-----
    MIIGLTCCBRWgAwIBAgIRAMvuT68080185tVdPX+AoIAwDQYJKoZIhvcNAQELBQAw
    
    1. Problem solved!!. Now execute docker-compose down and uncomment the above commented environment variables and change command from start-dev to start or start --optimized

    2. Now execute the docker-compose up. Now Keycloak is running in production mode successfully.

    3. check the logs using docker logs -f <keycloak_container_id>

      INFO [io.quarkus] (main) Keycloak 22.0.5 on JVM (powered by Quarkus 3.2.7.Final) started in 7.837s. Listening on: https://0.0.0.0:8443 INFO [io.quarkus] (main) Profile prod activated. INFO [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-mariadb, jdbc-mssql, jdbc-mysql, jdbc-oracle, jdbc-postgresql, keycloak, logging-gelf, micrometer, narayana-jta, reactive-routes, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-health, vertx]

    Done!! Now you are able to access Keycloak admin panel via https://abc.xyz.com:8443