docker.recipes

Keycloak Identity Management

advanced

Enterprise-grade identity and access management solution.

Overview

Keycloak is an open-source identity and access management solution originally developed by Red Hat, designed to provide enterprise-grade authentication and authorization capabilities. It supports modern protocols like OpenID Connect, OAuth 2.0, and SAML 2.0, enabling single sign-on (SSO) across multiple applications while maintaining centralized user management. Keycloak has become the go-to choice for organizations seeking a self-hosted alternative to cloud-based identity providers like Auth0 or Okta. This stack combines Keycloak with PostgreSQL as a production-ready database backend and NGINX as a reverse proxy for SSL termination and load balancing. PostgreSQL provides ACID compliance and robust data integrity for storing user credentials, sessions, and configuration data, while NGINX handles incoming requests and can distribute traffic across multiple Keycloak instances. This architecture ensures high availability and performance for enterprise authentication workloads. This configuration is ideal for organizations implementing zero-trust security models, modernizing legacy applications with modern authentication, or building microservices architectures requiring centralized identity management. The stack provides enterprise-level security features while remaining completely self-hosted, giving organizations full control over their identity infrastructure without vendor lock-in or per-user licensing costs.

Key Features

  • Single Sign-On (SSO) with OpenID Connect, OAuth 2.0, and SAML 2.0 protocol support
  • Identity brokering for social logins (Google, GitHub, Facebook) and enterprise identity providers
  • User federation with LDAP and Active Directory integration for existing user stores
  • Multi-tenancy support through realms for isolating different applications or organizations
  • Fine-grained authorization with role-based and attribute-based access control
  • Administrative console with REST APIs for programmatic realm and user management
  • PostgreSQL backend providing ACID compliance and data integrity for identity data
  • NGINX reverse proxy with SSL termination and load balancing capabilities

Common Use Cases

  • 1Enterprise SSO implementation for modernizing authentication across legacy and new applications
  • 2Microservices authentication gateway providing JWT token validation and user context
  • 3Multi-tenant SaaS platforms requiring isolated user management per customer organization
  • 4API security layer protecting REST APIs with OAuth 2.0 scopes and client credentials
  • 5Hybrid cloud identity bridge connecting on-premises Active Directory with cloud applications
  • 6Development platform authentication for internal tools, CI/CD systems, and developer portals
  • 7Healthcare and financial services requiring HIPAA/SOX compliant identity management

Prerequisites

  • Minimum 2GB RAM recommended (1GB for Keycloak, 512MB for PostgreSQL, 256MB for NGINX)
  • Available ports 80, 443 (NGINX), and 8080 (Keycloak admin console)
  • Basic understanding of OAuth 2.0, OpenID Connect, and JWT token concepts
  • SSL certificates for production deployment (self-signed acceptable for development)
  • Knowledge of PostgreSQL administration for backup and maintenance procedures
  • Familiarity with NGINX configuration for customizing reverse proxy rules

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 keycloak:
3 image: quay.io/keycloak/keycloak:latest
4 ports:
5 - "8080:8080"
6 environment:
7 KC_DB: postgres
8 KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
9 KC_DB_USERNAME: ${POSTGRES_USER}
10 KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
11 KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN}
12 KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
13 KC_HOSTNAME: localhost
14 KC_HOSTNAME_PORT: 8080
15 KC_HTTP_ENABLED: "true"
16 command: start-dev
17 depends_on:
18 postgres:
19 condition: service_healthy
20 networks:
21 - keycloak-net
22 restart: unless-stopped
23
24 postgres:
25 image: postgres:16-alpine
26 environment:
27 POSTGRES_USER: ${POSTGRES_USER}
28 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
29 POSTGRES_DB: ${POSTGRES_DB}
30 volumes:
31 - postgres_data:/var/lib/postgresql/data
32 healthcheck:
33 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
34 interval: 10s
35 timeout: 5s
36 retries: 5
37 networks:
38 - keycloak-net
39 restart: unless-stopped
40
41 nginx:
42 image: nginx:alpine
43 ports:
44 - "80:80"
45 - "443:443"
46 volumes:
47 - ./nginx.conf:/etc/nginx/nginx.conf:ro
48 - ./certs:/etc/nginx/certs:ro
49 depends_on:
50 - keycloak
51 networks:
52 - keycloak-net
53 restart: unless-stopped
54
55volumes:
56 postgres_data:
57
58networks:
59 keycloak-net:
60 driver: bridge

.env Template

.env
1# PostgreSQL
2POSTGRES_USER=keycloak
3POSTGRES_PASSWORD=secure_postgres_password
4POSTGRES_DB=keycloak
5
6# Keycloak Admin
7KEYCLOAK_ADMIN=admin
8KEYCLOAK_ADMIN_PASSWORD=secure_admin_password

Usage Notes

  1. 1Keycloak Admin at http://localhost:8080
  2. 2Create realms, clients, and users
  3. 3Supports OIDC, OAuth2, SAML
  4. 4Use 'start' instead of 'start-dev' for production

Individual Services(3 services)

Copy individual services to mix and match with your existing compose files.

keycloak
keycloak:
  image: quay.io/keycloak/keycloak:latest
  ports:
    - "8080:8080"
  environment:
    KC_DB: postgres
    KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
    KC_DB_USERNAME: ${POSTGRES_USER}
    KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
    KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN}
    KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
    KC_HOSTNAME: localhost
    KC_HOSTNAME_PORT: 8080
    KC_HTTP_ENABLED: "true"
  command: start-dev
  depends_on:
    postgres:
      condition: service_healthy
  networks:
    - keycloak-net
  restart: unless-stopped
postgres
postgres:
  image: postgres:16-alpine
  environment:
    POSTGRES_USER: ${POSTGRES_USER}
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    POSTGRES_DB: ${POSTGRES_DB}
  volumes:
    - postgres_data:/var/lib/postgresql/data
  healthcheck:
    test:
      - CMD-SHELL
      - pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}
    interval: 10s
    timeout: 5s
    retries: 5
  networks:
    - keycloak-net
  restart: unless-stopped
nginx
nginx:
  image: nginx:alpine
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf:ro
    - ./certs:/etc/nginx/certs:ro
  depends_on:
    - keycloak
  networks:
    - keycloak-net
  restart: unless-stopped

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 keycloak:
5 image: quay.io/keycloak/keycloak:latest
6 ports:
7 - "8080:8080"
8 environment:
9 KC_DB: postgres
10 KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
11 KC_DB_USERNAME: ${POSTGRES_USER}
12 KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
13 KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN}
14 KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
15 KC_HOSTNAME: localhost
16 KC_HOSTNAME_PORT: 8080
17 KC_HTTP_ENABLED: "true"
18 command: start-dev
19 depends_on:
20 postgres:
21 condition: service_healthy
22 networks:
23 - keycloak-net
24 restart: unless-stopped
25
26 postgres:
27 image: postgres:16-alpine
28 environment:
29 POSTGRES_USER: ${POSTGRES_USER}
30 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
31 POSTGRES_DB: ${POSTGRES_DB}
32 volumes:
33 - postgres_data:/var/lib/postgresql/data
34 healthcheck:
35 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
36 interval: 10s
37 timeout: 5s
38 retries: 5
39 networks:
40 - keycloak-net
41 restart: unless-stopped
42
43 nginx:
44 image: nginx:alpine
45 ports:
46 - "80:80"
47 - "443:443"
48 volumes:
49 - ./nginx.conf:/etc/nginx/nginx.conf:ro
50 - ./certs:/etc/nginx/certs:ro
51 depends_on:
52 - keycloak
53 networks:
54 - keycloak-net
55 restart: unless-stopped
56
57volumes:
58 postgres_data:
59
60networks:
61 keycloak-net:
62 driver: bridge
63EOF
64
65# 2. Create the .env file
66cat > .env << 'EOF'
67# PostgreSQL
68POSTGRES_USER=keycloak
69POSTGRES_PASSWORD=secure_postgres_password
70POSTGRES_DB=keycloak
71
72# Keycloak Admin
73KEYCLOAK_ADMIN=admin
74KEYCLOAK_ADMIN_PASSWORD=secure_admin_password
75EOF
76
77# 3. Start the services
78docker compose up -d
79
80# 4. View logs
81docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/keycloak-sso/run | bash

Troubleshooting

  • Keycloak fails to start with database connection error: Verify PostgreSQL container is healthy and POSTGRES_* environment variables match between services
  • Admin console shows 'Invalid request' after login: Check KC_HOSTNAME and KC_HOSTNAME_PORT match your actual access URL, update for production domains
  • PostgreSQL container exits with 'role does not exist': Ensure POSTGRES_USER environment variable is set and matches KC_DB_USERNAME in Keycloak service
  • NGINX returns 502 Bad Gateway: Verify Keycloak container is running and accessible on port 8080, check Docker network connectivity
  • Keycloak themes not loading properly: Mount custom theme volumes to /opt/keycloak/themes/ and restart container
  • High memory usage in production: Switch from 'start-dev' to 'start' command and configure KC_CACHE for clustering

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space