Feb 19, 2025

Keycloak + Docker Compose: Setup & Authentication Tutorial

In this tutorial we will:

  • Spin up Keycloak and PostgreSQL with a single Docker Compose file.

  • Configure a Keycloak realm, client, and user roles.

  • Demonstrate how to acquire access tokens and refresh tokens using Postman.

  • Learn how to log out and invalidate refresh tokens.

Keycloak is an open-source Identity and Access Management solution, enabling you to secure applications and services with minimum fuss. Let’s dive in.

Overview

This guide shows how to run Keycloak in a local, containerized environment. Our docker-compose.yaml sets up two services:

  1. PostgreSQL – Stores Keycloak’s data (users, roles, clients, etc.).

  2. Keycloak – The main authentication server, connected to PostgreSQL.

Once Keycloak is up and running, you’ll configure a dedicated realm, define a client, create a role, and register a user. Finally, you’ll use Postman to demonstrate the OAuth2/OpenID Connect flow:

  • Obtain an access token with user credentials and client secret.

  • Access protected resources (here, Keycloak’s built-in userinfo endpoint).

  • Refresh tokens without re-entering user credentials.

  • Log out (invalidate the active session and refresh tokens).

Prerequisites

  • Docker installed (Docker Desktop on Mac/Windows, or Docker engine on Linux).

  • Basic familiarity with running commands in a terminal/command prompt.

  • (Optional) Postman for testing Keycloak endpoints (this tutorial includes a Postman collection).

Cloning the Starter Code

All required files are located in the GitHub Repository. To follow along:

git

Then navigate into the cloned folder:

cd

You’ll find:

  • docker-compose.yaml for spinning up PostgreSQL and Keycloak.

  • A Postman_Collection.json (or similarly named file) containing sample requests for testing.

Setting up Docker Compose

The docker-compose.yaml Explained

Below is the core content of docker-compose.yaml (already included in the repository):

version: '3.8'

services:
  postgres:
    image: postgres:15
    container_name: keycloak-postgres
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: keycloak_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "keycloak"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - keycloak-network

  keycloak:
    image: quay.io/keycloak/keycloak:latest
    container_name: keycloak
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: keycloak_password
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin_password
      KC_HOSTNAME_STRICT: false
      KC_HOSTNAME_STRICT_HTTPS: false
      KC_HTTP_ENABLED: true
    command:
      - start-dev
    ports:
      - "8080:8080"
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - keycloak-network

volumes:
  postgres_data:
    name: keycloak_postgres_data

networks:
  keycloak-network:
    name

Key Points:

  • PostgreSQL container (named keycloak-postgres) is set up with a database and user named keycloak, password keycloak_password.

  • Keycloak container uses the official image from Quay.io.

  • Environment variables configure Keycloak to connect to the postgres service and create an admin user with credentials:

    • KEYCLOAK_ADMIN=admin

    • KEYCLOAK_ADMIN_PASSWORD=admin_password

  • Mapped port 8080 on the host is exposed to Keycloak’s internal port 8080.

Running Keycloak and PostgreSQL

From within the same directory as docker-compose.yaml, simply run:

(or docker-compose up if you’re on an older Docker Compose version.)

Docker will pull the images (if not already cached) and then start the two containers. You’ll see logs from PostgreSQL and Keycloak in your terminal.

Once Keycloak has finished starting, look for a message indicating Keycloak is listening on 0.0.0.0:8080 or similar. At this point:

Accessing the Keycloak Admin Console

  1. Open http://localhost:8080 in your browser.

  2. Click “Administration Console”.

  3. Log in with the admin credentials specified in the docker-compose.yaml file:

    • Username: admin

    • Password: admin_password

You’ll enter the Keycloak Admin Console, which allows you to manage realms, clients, roles, and users.

Creating a Realm

Keycloak uses realms to separate user and client data under different authentication contexts.

  1. In the Admin Console, click the “Master” dropdown (top-left).

  2. Click “Create Realm”.

  3. Provide a Realm Name, e.g., test-realm.

  4. Click “Create”.

This realm contains all the authentication entities—users, clients, roles—related to our test environment.

Creating a Client

A client represents an application or service that requests authentication. When a user attempts to log in or get a token via this client, Keycloak knows how to validate it.

  1. Navigate to “Clients” in the left menu.

  2. Click “Create Client” (or “Create” button).

  3. Enter test-client as the Client ID.

  4. Enable Client Authentication (so Keycloak will issue a client secret).

  5. For Redirect URIs, type http://localhost:8080/* (or any valid URL if needed).

  6. Click “Save”.

When you finish, Keycloak will generate a client secret that you can find under the “Credentials” tab for this client.

Defining a User and Role

1. Create a Realm Role

Optionally, let’s define a role that represents “API Access.”

  1. Click “Realm Roles” in the left menu.

  2. Click “Create Role”.

  3. Name it api-access (or any descriptive name).

  4. Save it.

2. Create a Test User

  1. Click “Users” in the left menu.

  2. Click “Add User”.

  3. Choose Username, e.g., test-user, then click “Save”.

  4. In the “Attributes” or “Details” tabs, optionally give email/first name.

  5. Go to “Credentials” and set a password (e.g., test-password). Disable “Temporary” so the user doesn’t have to reset on first login.

  6. Go to “Role Mappings” tab.

  7. Under “Realm Roles”, select api-access and assign it to the user.

Thus, test-user can now authenticate and will be marked with the api-access role.

Testing Authentication with Postman

To demonstrate the OAuth2 flow, we’ll:

  1. Obtain an access token using the user’s username/password plus the client secret.

  2. Use that token to access a protected resource (userinfo endpoint).

  3. Refresh the token if it expires.

  4. Log out (invalidate the refresh token/session).

Import the Postman Collection

Inside the repo, you’ll find a JSON file (e.g., Keycloak_Auth_Flow.postman_collection.json). In Postman:

  1. Click “Import”.

  2. Select the JSON file.

  3. You will see four requests:

    1. Get Access Token (Password Grant)

    2. Refresh Token

    3. User Info

    4. Logout

1. Obtaining an Access Token

Open “1. Get Access Token (Password Grant)” in Postman. Make sure these fields match your setup:

  • client_id: test-client

  • client_secret: the secret found under “Clients” → “test-client” → “Credentials.”

  • grant_type: password

  • username: test-user

  • password: test-password

  • URL: http://localhost:8080/realms/test-realm/protocol/openid-connect/token

Click “Send”. You should receive a JSON response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9....",
  "expires_in": 300,
  "refresh_expires_in": 1800,
  "refresh_token": "eyJhbGc....",
  "token_type": "Bearer",
  ...
}

2. Accessing a Protected Resource

Keycloak provides a built-in userinfo endpoint, which is protected. To access it:

  1. Copy the "access_token" from the previous response.

  2. Open the “3. User Info” request.

  3. Under Headers, ensure Authorization: Bearer <access_token> is set.

  4. Send the request.

If authentication succeeds, you will see the JSON user info (username, email, etc.).

3. Refreshing the Token

If your access token expires, you can refresh it without re-entering the user’s credentials:

  1. Open “2. Refresh Token.”

  2. Provide the same client_id, client_secret, and set grant_type to refresh_token.

  3. Copy the "refresh_token" from the first step’s response and paste it.

  4. Send the request.

You’ll receive a new access_token (and possibly a new refresh_token). This step is crucial in real-world apps to ensure continuous access without forcing users to log in repeatedly.

4. Logging Out

To invalidate the refresh token and session:

  1. Open “4. Logout.”

  2. Supply client_id, client_secret, and the refresh_token you want to invalidate.

  3. Send the request.

Keycloak responds with 204 No Content. The user’s session is terminated, and the refresh token can no longer be used.

Cleaning Up

When you’re done testing:

  1. Return to your terminal where docker compose up is running. Press Ctrl + C to stop Keycloak and PostgreSQL containers.

  2. (Optional) Remove containers and networks entirely:

    docker compose down
    docker system prune -a

This ensures everything is fully removed.

Video Chapters

  • 00:00:00 – 00:01:29 What to Expect: Keycloak Authentication on Docker Compose

  • 00:01:29 – 00:03:36 Download and Test Starter Code

  • 00:03:36 – 00:04:24 Keycloak Admin Console

  • 00:04:24 – 00:05:08 Create Keycloak Realm

  • 00:05:08 – 00:08:08 Create Keycloak Client

  • 00:08:08 – 00:10:06 Create Realm Role for Keycloak User

  • 00:10:06 – 00:10:56 Import Postman Collection

  • 00:10:56 – 00:12:44 Keycloak Access Token

  • 00:12:44 – 00:13:40 Access Protected Resource

  • 00:13:40 – 00:14:40 Keycloak Refresh Token

  • 00:14:40 – 00:15:25 Keycloak Logout

  • 00:15:25 – end Cleaning Up

Additional Resources

Conclusion

In this guide, you learned how to:

  1. Deploy Keycloak and PostgreSQL via a simple Docker Compose file.

  2. Create a Realm and Client to establish a valid authentication flow.

  3. Register Users and Roles, granting controlled access to resources.

  4. Obtain, Refresh, and Revoke tokens using Postman requests.

This setup provides a straightforward local environment to explore Keycloak’s authentication features. For production, consider additional security measures (SSL, advanced network settings, etc.). If you found this tutorial helpful, be sure to check out more DevOps and Kubernetes content, and don’t forget to watch the accompanying YouTube video for a hands-on walkthrough.

Kubernetes Training

If you find these guides helpful, check out our Kubernetes Training course

Let’s keep in touch

Subscribe to the mailing list and receive the latest updates

Let’s keep in touch

Subscribe to the mailing list and receive the latest updates

Let’s keep in touch

Subscribe to the mailing list and receive the latest updates

Let’s keep in touch

Subscribe to the mailing list and receive the latest updates