Subindo Keycloak 20.0.2 via docker-compose
Tags: keycloak, docker, dockercompose, oauth2
Published: 2023-05-21 18:48:00


Pois bem! Recentemente, precisei subir um server Keycloak na versão 20.0.2 via docker-compose para assegurar autenticação e autorização das APIs da minha aplicação. Notei que tive muita dificuldade em encontrar exemplos concretos na web, na forma que eu precisava. Levei alguns dias até entender tudo e conseguir fazer o que eu queria. Visto isso, decidi que, ao término da tarefa, eu escreveria um artigo descrevendo como fazer o que eu fiz com o intuito de ajudar os próximos caros colegas que precisem de uma ajuda. Vamos lá!

Inicialmente, deixo aqui dois links que me ajudaram a enteder o que é para que serve o Keycloak. O Keycloack é um servidor de autorização que funciona em cima da especificação do OAuth2, porém que também é capaz de performar autorizações através do protocolo OpenID. Ele provê toda uma estrutura em cima dessas duas principais funções que facilitam demais a vida de quem precisa implementar esses serviços em suas aplicações. O Keycloak provê, por exemplo: Cadastro e gerenciamento de múltiplos realms (que são conjuntos isolados de configurações possíveis e provê multi tenancy ao Keycloak), cadastro e gerenciamento de clients (que representam usuários ou aplicações terceiras que desejam acessar a sua), de roles, e muito mais coisas.

O primeiro link é um resumão sobre Keycloak feito pelo Wesley, da Full Cycle: [Aqui!](https://www.youtube.com/watch?v=82GIvH0qkJ4)
O segundo link é um tutorial sobre como integrar o Keycloak com uma aplicação Java feita com Spring feito pelo Pedro, do canal Java Para Iniciantes: [Aqui!](https://www.youtube.com/watch?v=x-6kEIL0RsU)

Beleza... Visto isso, acho importante dar um contexto sobre as mudanças que o Keycloak sofreu entre as versões 15 e 20 (não sei dizer especificamente em qual foi). A imagem do Keycloak 15.0.2 era disponibilizada pela JBoss e rodava em cima de Wildfly. A versão 20.0.2 está sendo disponibilizada pela Red Hat e roda em cima do Quarkus. Isso faz uma diferença tremenda na montagem do container via docker-compose. Até as variáveis de ambiente mudam. O Keycloak 20.0.2 inicia através da execução de um script chamado kc.sh. Vamos ao exemplo do container e na sequência eu explico o que é o quê:

```
 keycloak:
    image: quay.io/keycloak/keycloak:20.0.2
    environment:
      KC_HOSTNAME: localhost
      KC_HOSTNAME_PORT: 7080
      KC_HOSTNAME_STRICT_BACKCHANNEL: "true"
      KC_DB: mysql
      KC_DB_URL: jdbc:mysql://mysqldev:3306/meu_schema?createDatabaseIfNotExist=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2
      KC_DB_USERNAME: root
      KC_DB_PASSWORD: root
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
      KC_HEALTH_ENABLED: "true"
      KC_LOG_LEVEL: info
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:7080/health/ready" ]
      interval: 15s
      timeout: 2s
      retries: 15
    command:
      [ "start-dev", "--http-port 7080", "--https-port 7443", "--import-realm" ]
    volumes:
      - ../keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json
    ports:
      - 7080:7080
      - 7443:7443
    depends_on:
      - mysqldev
```
Vamos por partes:

1. A imagem que estou utilizando é a oficial do Keycloak 20.0.2: quay.io/keycloak/keycloak:20.0.2
2. Estou informando que meu servidor vai estar rodando em localhost:7080
3. Estou informando que este server Keycloak vai estar consumindo um banco MySQL e informo o endereço do mesmo através da variável KC_DB_URL. Inclusive, no endereço, informo que o schema a ser usado, no banco, é o meu_schema. E se o mesmo não existir, deve ser criado automaticamente
4. Informo login e senha do banco (root/root)
5. Informo login e senha do console de administração do Keycloak (admin/admin)
6. Configuro um endpoint de healthcheck (opcional)
7. Em "command" devem ser informados os parâmetros que serão passados para a execução do script kc.sh:
  1. "start-dev" é obrigatório ser passado para a execução do script. Porém, é um parâmetro que denota restritamente o ambiente de desenvolvimento. Se fosse produção, seria outro valor. Ex: "start"
  2. Informo que via HTTP o servidor estará disponível na 7080 e via HTTPS, na 7443
  3. "--import-realm" é um parâmetro que informa que um arquivo de pré-configuração deverá ser importado pelo Keycloak, na subida do servidor. Esse parâmetro tentará importar todos os arquivos .json que obedeçam a sintaxe esperada pelo Keycloak e que estejam na pasta /opt/keycloak/data/import
8. Mapeio um volume para copiar o arquivo realm-export.json para dentro do container. Dessa forma, esse arquivo será importado conforme mencionei. Esse arquivo já cria realm, clients e roles específicas para mim
9. Informo as portas internas e externas do container
10. Informo que esse container do Keycloak depende de um outro container meu, de MySQL

Dessa forma, com a execução do arquivo docker-compose (docker-compose up), teremos um container de Keycloak 20.0.2 rodando tranquilamente. Você poderá acessar o console do Keycloak através do endereço http://localhost:7080/admin. Nesse momento, será exibida uma mensagem "HTTPS is required". Isso porque o primeiro acesso ao console é através do realm "master", que é um realm do próprio Keycloak e o mesmo exige HTTPS. Para contornar essa situação, basta acessar o banco e dar um update na tabela REALM, trocando essa informação de SSL EXTERNAL para NONE.
Com isso, basta reiniciar o Keycloak e tudo deve funcionar normalmente. Bom, espero ter ajudado e ter sido sucinto. Este é o meu primeiro artigo aqui no dev.to. Obrigado por ler :)