Skip to main content

Deploying and Configuring a Keycloak Server using Docker

Prerequisite: Complete all steps in prerequisites and the LDAP Server Deployment before beginning the Keycloak deployment.

1. Install Keycloak

1.1 Create the Certificates needed for the servers

sudo certbot -d srv.example.com
sudo certbot -d keycloak.example.com

Copy over the keycloak certificates to /opt/keycloak/certs folder (usually under /etc/letsencrypt/live/keycloak.example.com)

1.2 Create a docker compose file with the below configuration under /opt/keycloak folder

# PostgreSQL Database for Keycloak
postgres:
image: postgres:15-alpine
container_name: keycloak-postgres
environment:
POSTGRES_DB: ${POSTGRES_DB:-keycloak}
POSTGRES_USER: ${POSTGRES_USER:-keycloak}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-keycloak_secure_password}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- sso-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-keycloak}"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

# Keycloak - Identity & Access Management
keycloak:
image: keycloak/keycloak:26.5.6
container_name: keycloak
environment:
# Database Configuration
KC_DB: "postgres"
KC_DB_URL: "jdbc:postgresql://postgres:5432/${POSTGRES_DB:-keycloak}"
KC_DB_USERNAME: ${POSTGRES_USER:-keycloak}
KC_DB_PASSWORD: ${POSTGRES_PASSWORD:-keycloak_secure_password}

# Keycloak Admin Credentials
KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN:-admin}
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-admin_secure_password}

# Production Mode Settings
KC_PROXY: edge
KC_HOSTNAME: ${KC_HOSTNAME:-localhost}
KC_HOSTNAME_STRICT: ${KC_HOSTNAME_STRICT:-false}
KC_HOSTNAME_STRICT_HTTPS: ${KC_HOSTNAME_STRICT_HTTPS:-false}
KC_HTTP_RELATIVE_PATH: ${KC_HTTP_RELATIVE_PATH:-/auth}
KC_HTTP_ENABLED: ${KC_HTTP_ENABLED:-true}

# TLS/HTTPS Configuration (set these for production with real SSL)
KC_HTTPS_CERTIFICATE_FILE: /etc/keycloak/certs/fullchain.pem
KC_HTTPS_CERTIFICATE_KEY_FILE: /etc/keycloak/certs/privkey.pem

# Security
# KC_FEATURES: ${KC_FEATURES:-}

# Logging
KC_LOG_LEVEL: ${KC_LOG_LEVEL:-info}

# Health Check
KC_HEALTH_ENABLED: "true"

# Performance Tuning
KC_DB_POOL_INITIAL_SIZE: 20
KC_DB_POOL_MAX_SIZE: 40
KC_CACHE: ispn

ports:
- "${KEYCLOAK_PORT:-8080}:8080"
# Uncomment for HTTPS
- "${KEYCLOAK_HTTPS_PORT:-8443}:8443"

volumes:
# Mount SSL certificates if needed (uncomment for HTTPS)
- ./certs:/etc/keycloak/certs:ro
- keycloak_data:/opt/keycloak/data

depends_on:
postgres:
condition: service_healthy

networks:
- sso-network

healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/auth/health/ready"]
interval: 15s
timeout: 10s
retries: 5
start_period: 30s

restart: unless-stopped

# Run Keycloak in production mode
command:
- start
- --optimized

volumes:
postgres_data:
keycloak_data:

networks:
sso-network:

1.3 Complete the settings by updating the appropriate values for the variables

# PostgreSQL Configuration
POSTGRES_DB=keycloak
POSTGRES_USER=keycloak
POSTGRES_PASSWORD=

# Keycloak Configuration
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=
KC_HOSTNAME=keycloak.example.com
KC_HOSTNAME_STRICT=true
KC_HOSTNAME_STRICT_HTTPS=true
KC_HTTP_RELATIVE_PATH=/auth
KC_HTTP_ENABLED=false
KC_LOG_LEVEL=debug

# Ports
KEYCLOAK_PORT=8080

1.4 Bring up the Keycloak services

cd /opt/keycloak
docker compose up -d

1.5 Access the keycloak service

Navigate to the URL, https://keycloak.example.com:8443/

login using the user ID admin and the password given with KEYCLOAK_ADMIN_PASSWORD.