Install Keycloak with Postgres & Traefik in Dev Mode

Install Keycloak with Postgres & Traefik in Dev Mode

With Docker Compose on Ubuntu on Localhost

This tutorial goes through launching Keycloak using Postgres as the database and Traefik for a reverse-proxy in separate containers using Docker compose. This tutorial assumes the following: 

  • You have installed Docker, see my tutorial here: https://phoenixignited.tech/install-docker-on-ubuntu/
  • You have installed Docker compose, see my tutorial here: https://phoenixignited.tech/install-docker-compose-on-ubuntu/
  • You are following this tutorial on your local machine
  • The default ports for keycloak and postgres are free: 8080 and 8443 for keycloak and 5432 for postgres
  • The port we are using for Traefik is free (port 777)
  • This tutorial was created with the latest version of Keycloak, Postgresql, Docker, Docker Compose, & Traefik, as of June 26, 2024 on an Ubuntu-like system.

Create our Directory Structure

We will first create the directory setup for our installation.

							
							
					mkdir Keycloak-Install && cd Keycloak-Install && mkdir Keycloak-Postgres-Containers && mkdir Traefik				
			

Create the Compose.Yaml File For Keycloak & Postgres

Next we will create a docker compose file like the following inside our Keycloak-Postgres-Containers directory (feel free to copy for your own purposes). This compose file will manage our Keycloak & Postgres DB instances.

							
							
					cd Keycloak-Postgres-Containers && nano compose.yaml				
			

This will enter the nano editor in the terminal, enter:

							
							
					version: '3.8'

services:
  postgres:
    image: postgres:latest
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - keycloak_network
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.postgres.rule=Host(`postgres.localhost`)"
      - "traefik.http.services.postgres.loadbalancer.server.port=5432"

  keycloak:
    image: quay.io/keycloak/keycloak:latest
    environment:
      KC_DB: postgres
      KC_DB_URL_HOST: postgres
      KC_DB_URL_DATABASE: keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: password
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
      KC_LOG_LEVEL: ALL
    ports:
      - 8080:8080
    depends_on:
      - postgres
    networks:
      - keycloak_network
    command: ["start-dev"]
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.keycloak.rule=Host(`keycloak.localhost`)"
      - "traefik.http.routers.keycloak.entrypoints=web,websecure"
      - "traefik.http.services.keycloak.loadbalancer.server.port=8080"

networks:
  keycloak_network:

volumes:
  postgres_data:

				
			

Then after you enter the above file into your compose.yaml file CTRL + O and then Enter saves the file and CTRL + X exits.

Run the Keycloak-Postgres Compose File

Next we will run the compose.yaml file via the following command:

							
							
					docker-compose up -d				
			

Create the Traefik.Yaml File For Traefik

Next we will create a docker compose file like the following inside our Traefik directory (feel free to copy for your own purposes). This compose file will manage our Traefik install.

							
							
					cd ../Traefik && nano traefik.yml				
			

This will enter the nano editor in the terminal, enter:

note: I set the traefik port to 777 here as the default is 8080, however since 8080 is being used by keycloak I had to set Traefik to a non-standard port.

							
							
					################################################################
#
# Configuration sample for Traefik v2.
#
# For Traefik v1: https://github.com/traefik/traefik/blob/v1.7/traefik.sample.toml
#
################################################################

################################################################
# Global configuration
################################################################
global:
  checkNewVersion: true
  sendAnonymousUsage: false

################################################################
# EntryPoints configuration
################################################################

# EntryPoints definition
#
# Optional
#
entryPoints:
  web:
    address: :80

  websecure:
    address: :443
  traefik:
    address: :777
################################################################
# Traefik logs configuration
################################################################

# Traefik logs
# Enabled by default and log to stdout
#
# Optional
#
#log:
  # Log level
  #
  # Optional
  # Default: "ERROR"
  #
  #level: DEBUG

  # Sets the filepath for the traefik log. If not specified, stdout will be used.
  # Intermediate directories are created if necessary.
  #
  # Optional
  # Default: os.Stdout
  #
#  filePath: log/traefik.log

  # Format is either "json" or "common".
  #
  # Optional
  # Default: "common"
  #
#  format: json

################################################################
# Access logs configuration
################################################################

# Enable access logs
# By default it will write to stdout and produce logs in the textual
# Common Log Format (CLF), extended with additional fields.
#
# Optional
#
#accessLog:
  # Sets the file path for the access log. If not specified, stdout will be used.
  # Intermediate directories are created if necessary.
  #
  # Optional
  # Default: os.Stdout
  #
#  filePath: /path/to/log/log.txt

  # Format is either "json" or "common".
  #
  # Optional
  # Default: "common"
  #
#  format: json

################################################################
# API and dashboard configuration
################################################################

# Enable API and dashboard
#
# Optional
#
api:
  # Enable the API in insecure mode
  #
  # Optional
  # Default: false
  #
  insecure: true

  # Enabled Dashboard
  #
  # Optional
  # Default: true
  #
  dashboard: true

################################################################
# Ping configuration
################################################################

# Enable ping
#ping:
  # Name of the related entry point
  #
  # Optional
  # Default: "traefik"
  #
#  entryPoint: traefik

################################################################
# Docker configuration backend
################################################################

providers:
  # Enable Docker configuration backend
  docker:
    # Docker server endpoint. Can be a tcp or a unix socket endpoint.
    #
    # Required
    # Default: "unix:///var/run/docker.sock"
    #
    endpoint: "unix:///var/run/docker.sock"

    # Default host rule.
    #
    # Optional
    # Default: "Host(`{{ normalize .Name }}`)"
    #
    defaultRule: Host(`{{ normalize .Name }}.docker.localhost`)

    # Expose containers by default in traefik
    #
    # Optional
    # Default: true
    #
    exposedByDefault: false
    network: "keycloak-postgres-containers_keycloak_network"
				
			

Then after you enter the above file into your compose.yaml file CTRL + O and then Enter saves the file and CTRL + X exits.

Run the Traefik.Yml File

Next we will run the traefik.yml file via the following command:

							
							
					docker run -d --network keycloak-postgres-containers_keycloak_network -p 80:80 -p 443:443 -p 777:777 -v $PWD/traefik.yml:/etc/traefik/traefik.yml -v /var/run/docker.sock:/var/run/docker.sock traefik:v3.0				
			

Open & Inspect Traefik, Keycloak, & Postgres

Now we can open and inspect Traefik at http://localhost:777 you should see:

And we can open keycloak at http://keycloak.localhost you should see:

You won’t see much for postgres, but you should see:

Keycloak & Postgres Installation Verification & Logging

You can verify the keycloak and postgres compose.yaml file executed successfully and view logs via the following commands:

							
							
					docker ps # this will display all active docker containers

docker-compose logs keycloak # displays logs related to keycloak

docker-compose logs postgres # displays logs related to the postgres db				
			

Verify Keycloak Initialized the DB successfully

Next we will log into the PostgreSQL server and ensure that keycloak successfully initialized the db

							
							
					docker exec -it <keycloak_ps_name> psql -U keycloak # find the <keycloak_ps_name> by running docker ps and finding the name of the keycloak instance
				
			
							
							
					\d /* returns the databases including templates, default postgres, and the keycloak db we created */

\dt /* lists the tables */				
			

If when you run \dt it returns a list of tables then keycloak has initialized the db correctly and you are good to go!

Walter is a tech entrepreneur and in his free time loves fitness, art, writing, and exploring Montana's outdoors.