How to deploy SSO (keycloak) on Linux server with docker-compose and SSL in less than 10min
Tags: docker, nginxproxy, sso, keycloak
Published: 2022-04-24 16:21:12


This article is also [available on my blog](https://temfack.com/how-to-deploy-sso-keycloak-on-linux-server-with-docker-compose-and-ssl-in-less-than-10min/). Check it out to support me. 

---
An SSO( Single Sign-On) is a system that allows users to access multiple services/platforms with the same credential. This system is very popular today and is used by the giants of the internet (Google, Facebook, etc). There are many platforms that sell this type of service among [onelogin](https://www.onelogin.com/), [okta](https://www.okta.com/), etc. In this story, we’ll set up our own SSO servers using keycloak.

**Prerequisite**
- A Linux Server with SSH Access
- Docker and docker-compose installed on this server
- A domain name point to this server

**What is KeyCloak?**

**KeyCloak** is an open-source Identity and Access Management that allows us to add authentication in our application and secure service with minimum effort. It is a community project sponsored by Red Hat. Red Hat use it in their own products and also distribute it to their client as [Red Hat SSO](https://access.redhat.com/products/red-hat-single-sign-on).

KeyCloak is a java project and is based on two popular protocols: **SAML 2** and **OpenID Connect**. With keycloak, you can easily enable social login or use an existing LDAP/Active Directory as a user federation.

Keycloak is a very extensible tool and it gives you the possibility to customize it based on your need. It’s the best free SSO solution on the market and you can definitely choose it without being afraid if you want to set up your own SSO server. For further information, check their [well-written documentation](https://www.keycloak.org/).

**Installation of KeyCloak**

I have already prepared a **docker-compose** file for you and it is the one that I use to deploy keycloak in my production environment.

```
version: "3.9"

services:
  postgres:
    image: postgres:13.2
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRESQL_DB}
      POSTGRES_USER: ${POSTGRESQL_USER}
      POSTGRES_PASSWORD: ${POSTGRESQL_PASS}
    volumes:
      - postgres_data:/var/lib/postgresql/data

  keycloak:
    depends_on:
      - postgres
    container_name: keycloak
    environment:
      DB_VENDOR: postgres
      DB_ADDR: postgres
      DB_DATABASE: ${POSTGRESQL_DB}
      DB_USER: ${POSTGRESQL_USER}
      DB_PASSWORD: ${POSTGRESQL_PASS}
      VIRTUAL_HOST: ${VIRTUAL_HOST}
      LETSENCRYPT_HOST: ${LETSENCRYPT_HOST}
      LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
      VIRTUAL_PORT: "8080"
      HTTPS_METHOD: redirect
      PROXY_ADDRESS_FORWARDING: "true" # <==== very important if you use reverse proxy
    image: jboss/keycloak:${KEYCLOAK_VERSION}
    restart: unless-stopped

volumes:
  postgres_data:

#Use this configuration in production with nginx-proxy container
networks:
  default:
    external:
      name: nginx-proxy
```
docker-compose.yml file

```
KEYCLOAK_VERSION=16.1.1
PORT_KEYCLOAK=8080
POSTGRESQL_USER=keycloak
POSTGRESQL_PASS=keycloak
POSTGRESQL_DB=keycloak
VIRTUAL_HOST=example.com
LETSENCRYPT_HOST=example.com
LETSENCRYPT_EMAIL=example@gmail.com
```
.env file

Our docker-compose file exposes two services, one volume, and one external network.

**Postgres service**
Keycloak supports many databases like Postgres, MySQL/MariaDB, Oracle, etc. We use in our case Postgres.

**Keycloak service**
This service depends on Postgres service. This means that the Postgres service will start or stop before the keycloak service. Keycloak has many different images in the Docker hub and we will use the one provided by the JBoss community. As we use Nginx-proxy as a reverse proxy and acme-compagnon for Let’s Encrypt certificate, we need to add three special environment variables in the keycloak service.

- **VIRTUAL_HOST** indicate the domain name (or subdomain name) that keycloak will be accessible through (VIRTUAL_HOST=auth.example.com)
- **LETSENCRYPT_HOST** contains the same value as VIRTUAL_HOST and indicates to acme-compagnon to ask for SSL certificate for this domain (or subdomain ) to Let’s encrypt
- **LETSENCRYPT_EMAIL** contains a valid email address required by let’s encrypt servers to issue an SSL certificate for our domain and to send notifications when the SSL certificate will be expired.
- **PROXY_ADDRESS_FORWARDING** is set to true when we run keycloak behind a reverse proxy. Without this variable set to true, we can’t log in to our keycloak server.

**network**

We use the Nginx-proxy container as a reverse proxy and it required all containers to be connected to a unique network so that it can easily handle traffic to them.

The .env file is the one that contains all environment variables we use in our docker-compose file. We place it in the same directory with the docker-compose file and it’s automatically discovered when we make a **docker-compose up**. You can modify it according to your need. If you don’t want to copy and paste the content of those files, you can clone the project with all this configuration from [my repository](https://gitlab.com/tderick/keycloak-docker-compose-template-file-for-easy-deploy-on-vps-behind-nginx-proxy-container).

If you want to copy and paste, let’s do it. First, create a directory in your Linux server for this project.

```
mkdir keycloak && cd keycloak
```
Secondly, copy the content of my docker-compose file and paste it into the docker-compose file you create in this directory.

```
nano docker-compose.yml
```
Do the same with the .env file.

```
nano .env
```

**Start keycloak service**
Before starting keycloak, we need to create the external network that we declare in our docker-compose file.

```
docker network create nginx-proxy
```
After that, we can run our container.

```
docker-compose up --build -d
```
When starting keycloak for the first time, there are no users in his database, we need to create an admin user to manage our keycloak instance. To do that, use the following command:

```
docker exec keycloak \
    /opt/jboss/keycloak/bin/add-user-keycloak.sh \
    -u admin \
    -p admin \
&& docker restart keycloak
```
This command will add a user in the keycloak database with username admin and password admin. Change the password to a more secure one. Now, our keycloak server is ready. We can now install Nginx-proxy to make it accessible.

**Installation of Nginx-proxy and acme-compagnon**

Nginx proxy is a container running Nginx and docker-gen which is a service that generates reverse proxy configs for Nginx and reloads Nginx when containers are started or stopped.

This container is mounted on a docker socket to capture all events created by docker to be able to proxied any container with an env variable **VIRTUAL_HOST** define. All containers that want to be proxied by Nginx-proxy must be connected to the same network with it. To know more about Nginx-proxy, visit [the GitHub of the project](https://github.com/nginx-proxy/nginx-proxy).

ACME-compagnon is a compagnon for Nginx-proxy responsible to automate the creation, renewal, and use of SSL certificates for proxied Docker containers through ACME protocol. For more information about acme-compagnon, visit [the GitHub of the project](https://github.com/nginx-proxy/acme-companion).

Again, I also have a prepared project in my repository to use without further configuration. You just need to clone and run it. I also use this template in all my projects. With this configuration, it’s easy to make things work in less than a minute. Just use the following command.

```
cd ~
git clone https://gitlab.com/tderick/nginx-proxy-conf.git 
docker-compose up --build -d
```
Check your domain name and you will see the following output.

![keycloak home page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szq8scdew9ht7m3shwgz.png)

Click on “**Administration console**” and log in with the credential we created early.

![keycloak authentication form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5qsxbpdvjf4eq5ysfwm.png)

Congratulation, you have deployed an SSO system in your own server using docker and protected it with a free SSL certificate issued by **Let’s Encrypt**.If you encounter a problem during the process, leave a comment and I will help you.

In the upcoming stories, we will explore more keycloak. If you like this content, you can [buy me a coffee](https://www.buymeacoffee.com/tderick).