Keycloak can feel like a complex beast, but running it locally with Docker Compose is surprisingly straightforward once you see it in action.
Let’s get Keycloak up and running in a Docker Compose setup. Here’s a minimal docker-compose.yml to get you started:
version: '3.8'
services:
keycloak:
image: quay.io/keycloak/keycloak:24.0
ports:
- "8080:8080"
environment:
KC_HTTP_PORT: 8080
KC_HOSTNAME: localhost
KC_HOSTNAME_PORT: 8080
KC_DB_URL: jdbc:h2:mem:keycloak
KC_ADMIN_USER: admin
KC_ADMIN_PASSWORD: admin
command: start-dev
To launch this, save it as docker-compose.yml and run docker compose up -d in the same directory. You should see Keycloak start up. Access the admin console at http://localhost:8080/admin/.
Now, let’s break down what’s happening and why it works. The core of this setup is the docker-compose.yml file.
The services block defines the containers we want to run. Here, we have one service named keycloak.
The image: quay.io/keycloak/keycloak:24.0 line tells Docker to pull the official Keycloak image tagged with version 24.0 from Quay.io. Using specific tags is crucial for reproducibility.
The ports section, - "8080:8080", maps port 8080 on your host machine to port 8080 inside the Keycloak container. This is how you’ll access Keycloak from your browser.
The environment block is where we configure Keycloak.
KC_HTTP_PORT: 8080explicitly sets the HTTP port Keycloak listens on inside the container.KC_HOSTNAME: localhosttells Keycloak to advertise itself aslocalhost.KC_HOSTNAME_PORT: 8080specifies the port Keycloak should use in its generated URLs.KC_DB_URL: jdbc:h2:mem:keycloakconfigures Keycloak to use an in-memory H2 database. This is perfect for local development because it requires no external database setup and data is lost on container restart, keeping your local environment clean.KC_ADMIN_USER: adminandKC_ADMIN_PASSWORD: adminset the credentials for the initial administrator account.
Finally, command: start-dev is the magic command that tells the Keycloak container to start in development mode. This mode is optimized for local development, enabling features like auto-discovery of realms and a simplified startup process.
This setup demonstrates a fundamental aspect of modern application deployment: containerization. By packaging Keycloak and its dependencies into a Docker image, we ensure that it runs consistently regardless of your local machine’s environment. Docker Compose then orchestrates this container, making it easy to bring up and manage the service with a single command.
The start-dev command is particularly interesting. It’s not just a startup script; it’s a mode that enables several development-friendly features. For instance, it automatically creates a master realm if one doesn’t exist and allows you to log in with the admin credentials without any prior configuration. It also disables certain security checks that would be necessary in production, such as requiring specific HTTPS configurations.
To illustrate the flexibility, imagine you want to use a PostgreSQL database instead of the in-memory H2. You’d add a PostgreSQL service to your docker-compose.yml and update the KC_DB_URL and add KC_DB_USERNAME, KC_DB_PASSWORD, and KC_DB_DRIVER environment variables for the Keycloak service.
version: '3.8'
services:
keycloak:
image: quay.io/keycloak/keycloak:24.0
ports:
- "8080:8080"
environment:
KC_HTTP_PORT: 8080
KC_HOSTNAME: localhost
KC_HOSTNAME_PORT: 8080
KC_DB_URL: jdbc:postgresql://db:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: password
KC_DB_DRIVER: org.postgresql.Driver
KC_ADMIN_USER: admin
KC_ADMIN_PASSWORD: admin
command: start-dev
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
Then, you’d run docker compose up -d again. The depends_on directive ensures the database starts before Keycloak, and the KC_DB_URL now points to the db service running on port 5432.
The initial setup you saw relies on Keycloak’s ability to bind to localhost. While convenient for local testing, in a more distributed or production-like environment, you’d need to configure KC_HOSTNAME_STRICT_HTTPS and KC_HOSTNAME_STRICT to false or set KC_HOSTNAME to your actual domain. The start-dev command simplifies this by assuming a local, non-production context.
The next step in exploring Keycloak’s capabilities would be to integrate it with an application, perhaps using the built-in examples or setting up your own client.