I was recently tasked with evaluating Laravel-based and external SSO workflows and stumbled on Keycloak in several places. There is a Socialite provider as well as Supabase auth so I needed a way to make a quick evaluation. I chose to use Docker as I didn't want to dive into the world of Java installations. There is some extensive documentation, but like some OSS projects, it can be a firehose at times.
Fortunately, Google came to the rescue with many resources I've included at the bottom of this post for reference.
A Docker compose file to spin up the Keycloak container and Postgres to store its data.
The docker image needs environment variables set and the best way I know to do that is through direnv
and specifically the asdf
version manager plugin for it.
I lifted this template from this StackOverflow post and surgically altered it for my purposes.
I commented out the parts that weren't relevant and stripped away the backend
and frontend
services since I no longer needed them.
---
version: "3.8"
services:
database:
image: postgres:14
container_name: database
environment:
# add multiple schemas
# POSTGRES_MULTIPLE_DATABASES: ${DB_DATABASE},${KEYCLOAK_DATABASE}
POSTGRES_DB: ${DB_DATABASE}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
# POSTGRES_KEYCLOAK_USER: ${KEYCLOAK_USER}
# POSTGRES_KEYCLOAK_PASSWORD: ${KEYCLOAK_PASSWORD}
# POSTGRES_DB2: ${KEYCLOAK_DATABASE}
hostname: local
restart: always
volumes:
- ./db-data:/var/lib/postgresql/data/
- ./sql:/docker-entrypoint-initdb.d/:ro
# - ./sql/access_attempt.sql:/docker-entrypoint-initdb.d/A.sql
# - ./sql/bceid.sql:/docker-entrypoint-initdb.d/B.sql
# - ./sql/lookup_activitytype.sql:/docker-entrypoint-initdb.d/C.sql
# - ./sql/lookup_gender_pronoun.sql:/docker-entrypoint-initdb.d/D.sql
# - ./sql/client.sql:/docker-entrypoint-initdb.d/E.sql
ports:
- "5439:5432"
networks:
- db-keycloak
keycloak:
image: quay.io/keycloak/keycloak:21.0.1
command: ["start-dev"]
container_name: keycloak
environment:
DB_VENDOR: ${DB_VENDOR}
DB_ADDR: database
DB_PORT: 5432
DB_SCHEMA: public
DB_DATABASE: ${DB_DATABASE}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
KEYCLOAK_USER: ${KEYCLOAK_USER}
KEYCLOAK_PASSWORD: ${KEYCLOAK_PASSWORD}
KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN}
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
KC_PROXY_MODE: edge
KC_METRICS_ENABLED: true
KC_HTTP_ENABLED: true
ports:
- "8089:8080"
- "8443:8443"
depends_on:
- database
restart: always
links:
- database
networks:
- db-keycloak
networks:
db-keycloak:
driver: bridge
This sets the environment variables used by both Postgres and Keycloak.
APP_DOMAIN="localhost"
DB_VENDOR="postgres"
DB_DATABASE="keycloak"
DB_USER="keycloak"
DB_PASSWORD="keycloak"
KEYCLOAK_USER="developer"
KEYCLOAK_PASSWORD="developer"
KEYCLOAK_ADMIN="admin"
KEYCLOAK_ADMIN_PASSWORD="admin"
KC_DB="postgres"
KC_DB_URL="jdbc:postgresql://database/keycloak"
# KC_HOSTNAME_FRONTEND_URL=""
# KC_HOSTNAME_ADMIN_URL=""
Run docker compose up
to run the containers in interactive mode.
db-data
directory should fill up with files and directories.docker compose up -d
to run your containers in the background.docker-compose down --rmi all
to completely cleanup all containers.command: ["start-dev"]
to start keycloak in the other modes. This is necessary as the entrypoint isn't specific enough.It may be useful to create an optimized Keycloak image, but that wasn't necessary for my purposes.
Modify the image section image: quay.io/keycloak/keycloak:21.0.1
to keycloak-custom:latest
to use the custom image.
docker build -t keycloak-custom:latest .
.