Aller au contenu
medium

Installer Keycloak avec Docker

15 min de lecture

Logo Keycloak

Ce guide vous permet d'installer Keycloak avec Docker pour le développement et la formation. Vous apprendrez à démarrer Keycloak rapidement, configurer Docker Compose avec PostgreSQL, et accéder à la console d'administration.

À la fin de ce module, vous saurez :

  • Démarrer Keycloak en mode dev pour tester rapidement
  • Configurer Docker Compose avec PostgreSQL pour la persistance
  • Accéder à la console d'administration et créer un compte admin
  • Identifier les variables essentielles de configuration
  • Docker installé (guide d'installation)
  • Docker Compose (inclus dans Docker Desktop, ou docker-compose-plugin sur Linux)

Keycloak ne se lance pas de la même façon selon l'usage : la sous-commande passée au conteneur (start-dev ou start) décide de la base de données, du TLS et du cache. Le tableau ci-dessous se lit ligne par ligne comme une liste de renoncements : chaque case de la colonne « développement » est un contrôle désactivé pour vous éviter une configuration. La ligne Base de données est la plus lourde de conséquences, start-dev utilise H2 en mémoire, donc tout realm créé disparaît à l'arrêt du conteneur.

Keycloak propose deux modes d'exécution :

AspectMode développement (start-dev)Mode production (start)
Base de donnéesH2 embarqué, fichier local (dev-file)PostgreSQL, MySQL, MariaDB
TLS/HTTPSDésactivéObligatoire
Hostnamelocalhost par défautDoit être configuré
CacheLocal uniquementDistribué (Infinispan)
UsageTests, labs, formationProduction, staging

Cette commande sert à voir la console d'administration en moins de deux minutes, sans écrire un seul fichier. Le premier démarrage prend une dizaine de secondes le temps que Quarkus construise son augmentation : tant que la ligne started in n'apparaît pas dans les logs, le port 8080 refuse les connexions. Les identifiants passés par KC_BOOTSTRAP_ADMIN_* ne sont lus qu'au tout premier lancement, quand la base est encore vide.

La méthode la plus rapide pour tester Keycloak :

Fenêtre de terminal
docker run -p 8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:26.7.0@sha256:0f198be292568439d700cdbfb893e69a6009bb43a94a06a945b1d3d506c76b13 \
start-dev

Ce que fait cette commande :

  • Télécharge l'image Keycloak 26.7.0 depuis Quay.io
  • Lance Keycloak sur le port 8080
  • Crée un compte admin temporaire admin/admin
  • Démarre en mode développement avec le pilote dev-file (H2 écrit dans /opt/keycloak/data/h2/keycloakdb.mv.db)

Vérification : Ouvrez http://localhost:8080

Deux conteneurs suffisent : PostgreSQL détient les realms, les utilisateurs et les clients, Keycloak ne garde rien sur son propre disque. Le point à ne pas rater dans le fichier ci-dessous est le couple healthcheck sur PostgreSQL et condition: service_healthy sur Keycloak. Sans lui, Keycloak démarre plus vite que la base, échoue sur une connexion JDBC refusée et le conteneur sort en boucle. Le volume nommé postgres_data est ce qui survit à un docker compose down ; c'est aussi lui que -v détruit.

Pour un environnement de formation avec persistance des données :

  1. Créer le répertoire de travail

    Fenêtre de terminal
    mkdir -p ~/Projets/keycloak && cd ~/Projets/keycloak
  2. Créer le fichier docker-compose.yml

    docker-compose.yml
    services:
    postgres:
    image: postgres:16-alpine
    container_name: keycloak-db
    environment:
    POSTGRES_DB: keycloak
    POSTGRES_USER: keycloak
    POSTGRES_PASSWORD: keycloak
    volumes:
    - postgres_data:/var/lib/postgresql/data
    healthcheck:
    test: ["CMD-SHELL", "pg_isready -U keycloak"]
    interval: 5s
    timeout: 5s
    retries: 5
    networks:
    - keycloak-net
    keycloak:
    image: quay.io/keycloak/keycloak:26.7.0@sha256:0f198be292568439d700cdbfb893e69a6009bb43a94a06a945b1d3d506c76b13
    container_name: keycloak
    command: start-dev
    environment:
    KC_DB: postgres
    KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
    KC_DB_USERNAME: keycloak
    KC_DB_PASSWORD: keycloak
    KC_HOSTNAME: localhost
    KC_BOOTSTRAP_ADMIN_USERNAME: admin
    KC_BOOTSTRAP_ADMIN_PASSWORD: admin
    ports:
    - "8080:8080"
    depends_on:
    postgres:
    condition: service_healthy
    networks:
    - keycloak-net
    volumes:
    postgres_data:
    networks:
    keycloak-net:
    driver: bridge
  3. Démarrer les services

    Fenêtre de terminal
    docker compose up -d
  4. Suivre les logs

    Fenêtre de terminal
    docker compose logs -f keycloak

    Attendez de voir :

    Keycloak 26.7.0 on JVM (powered by Quarkus 3.33.2.1) started in 10.505s. Listening on: http://0.0.0.0:8080
  5. Ouvrir la console

    Accédez à http://localhost:8080

En Keycloak 26, la racine http://localhost:8080 renvoie une redirection 302 vers /admin/, elle-même redirigée vers /admin/master/console/ : vous atterrissez donc directement sur l'écran de connexion de la console. Le compte que vous y utilisez est un administrateur temporaire, créé au tout premier démarrage à partir des variables KC_BOOTSTRAP_ADMIN_*. Les logs le disent explicitement avec KC-SERVICES0077: Created temporary admin user. Sur une base déjà initialisée, ce compte n'est pas recréé : changer les variables dans le fichier Compose ne changera pas le mot de passe.

  1. Ouvrez votre navigateur à l'adresse http://localhost:8080, vous êtes redirigé vers /admin/master/console/

  2. Connectez-vous avec les identifiants définis au démarrage :

    • Username : admin
    • Password : admin
  3. Vous arrivez sur le Master Realm, l'espace d'administration global

Keycloak se configure via des variables d'environnement (préfixées KC_) ou des options CLI (préfixées --).

Ces quatre variables sont le minimum pour sortir de H2. KC_DB sélectionne le pilote JDBC embarqué dans l'image parmi dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres et tidb, et c'est lui qui détermine la syntaxe attendue par KC_DB_URL : une URL PostgreSQL passée avec KC_DB: mysql fait échouer le démarrage, pas une requête plus tard. Un mot de passe en clair dans KC_DB_PASSWORD convient à un lab, mais il reste lisible par docker inspect ; pour la production, Keycloak lit ses secrets depuis une source KeyStore déclarée par --config-keystore.

VariableDescriptionExemple
KC_DBType de base de donnéespostgres, mysql, mariadb
KC_DB_URLURL JDBC de connexionjdbc:postgresql://host:5432/db
KC_DB_USERNAMEUtilisateur de la basekeycloak
KC_DB_PASSWORDMot de passesecret

Ces deux variables n'ont d'effet que sur une base vierge. Keycloak les lit au premier démarrage, crée l'administrateur temporaire du realm master, puis les ignore définitivement. Un mot de passe modifié dans le fichier Compose après coup ne sera donc jamais appliqué ; il faut soit repartir d'un volume vide, soit changer le mot de passe depuis la console.

VariableDescription
KC_BOOTSTRAP_ADMIN_USERNAMENom de l'admin initial
KC_BOOTSTRAP_ADMIN_PASSWORDMot de passe admin initial

KC_HOSTNAME est la variable qui cause le plus d'échecs derrière un reverse proxy. Keycloak s'en sert pour construire les URL absolues qu'il place dans ses réponses OIDC : l'issuer des jetons, les redirections d'authentification, les liens du document de découverte /.well-known/openid-configuration. Si la valeur ne correspond pas à ce que le navigateur a réellement tapé, le client OIDC rejettera les jetons pour cause d'issuer incohérent, alors même que la page de login s'affichait correctement.

VariableDescriptionExemple
KC_HOSTNAMEHostname publiclocalhost, auth.example.com
KC_HTTP_PORTPort HTTP8080

Les deux premières variables activent l'observabilité et méritent d'être posées dès le lab, parce que leur comportement a changé en Keycloak 26 : les endpoints correspondants ne répondent plus sur le port applicatif mais sur un port de management séparé. KC_LOG_LEVEL: DEBUG est utile ponctuellement, mais il génère un volume de logs qui noie les messages utiles ; réservez-le à la reproduction d'un problème précis.

VariableDescriptionExemple
KC_HEALTH_ENABLEDEndpoints /health/* (sur le port de management 9000)true
KC_METRICS_ENABLEDMétriques Prometheus (sur le port 9000)true
KC_LOG_LEVELNiveau de logINFO, DEBUG

Une seule de ces commandes est destructrice, et c'est la dernière. docker compose down arrête et supprime les conteneurs mais conserve le volume postgres_data : vos realms sont toujours là au prochain up. L'option -v supprime en plus le volume, donc la base entière. Retenez la distinction avant de la taper machinalement pour « repartir propre ».

Fenêtre de terminal
# Démarrer
docker compose up -d
# Arrêter
docker compose down
# Voir les logs
docker compose logs -f keycloak
# Redémarrer Keycloak
docker compose restart keycloak
# Supprimer tout (y compris les données)
docker compose down -v

docker compose ps vous dit que le processus tourne, pas que Keycloak est prêt à servir. Entre le démarrage du conteneur et la première réponse HTTP, il s'écoule une dizaine de secondes pendant lesquelles le port 8080 est ouvert mais refuse la connexion. Le test qui fait foi est donc une requête applicative : /realms/master renvoie un JSON et un code 200 dès que le realm est monté, ce qui en fait un point de contrôle utilisable dans un script d'attente.

Fenêtre de terminal
# Vérifier que Keycloak répond (le realm master renvoie 200 une fois prêt)
curl -sf http://localhost:8080/realms/master >/dev/null && echo "Keycloak prêt"
# Voir l'état des conteneurs
docker compose ps

La quasi-totalité des blocages au démarrage vient de la base de données, pas de Keycloak. Avant de lire le tableau, sortez le vrai message avec docker compose logs keycloak : Quarkus affiche la cause racine sur la ligne Caused by, souvent bien plus bas que la stacktrace initiale. La colonne « Cause probable » ci-dessous vous oriente ensuite vers le bon fichier à corriger.

SymptômeCause probableSolution
Connection refused (DB)PostgreSQL non démarréAttendre le healthcheck ou docker compose restart
FATAL: password authentication failedMauvais credentials DBVérifier les variables KC_DB_*
Port already in usePort 8080 occupéUtiliser un autre port : 8180:8080
Page blanche au loginNavigateur cacheCtrl+F5 ou mode navigation privée

Ce couple de commandes est le seul moyen fiable de retrouver un environnement identique à une première installation, notamment pour reprendre la main quand vous avez oublié le mot de passe de l'administrateur temporaire. La suppression du volume remet la base à zéro, donc les variables KC_BOOTSTRAP_ADMIN_* redeviennent effectives au démarrage suivant. Sur un lab de formation c'est sans risque ; ailleurs, sauvegardez d'abord vos realms avec un export.

Pour repartir de zéro (supprime toutes les données) :

Fenêtre de terminal
docker compose down -v
docker compose up -d
  • Docker Compose est la méthode recommandée pour la formation
  • Mode start-dev = développement uniquement (pas de TLS, pas de prod)
  • PostgreSQL pour la persistance des données
  • Variables KC_BOOTSTRAP_ADMIN_* pour créer l'admin initial (dépréciées : KEYCLOAK_ADMIN*)
  • Console admin : http://localhost:8080 redirige vers /admin/master/console/
  • Master Realm : réservé à l'administration, ne pas y créer d'applications

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn