Deploying Keycloak to a VPS Using Docker-compose, Nginx, Certbot, and SSL

Roman Surkoff - Jul 6 - - Dev Community

In this article, I would like to share how to deploy Keycloak to a VPS using Docker-compose, Nginx, Certbot, and SSL.

Key points:

  • Keycloak v.25.0.1
  • SSL protection for Keycloak
  • Certbot v.2.11.0 for obtaining and renewing SSL certificates
  • Nginx v.1.27.0 as a reverse proxy
  • Postgres v.14 to replace the default internal H2 DB of Keycloak
  • Automatic realm import during deployment
  • Docker-compose for deployment automation
  • .env file for managing environment variables

For those who might not be familiar, Keycloak is a powerful access management system with SSO support that can significantly simplify user management and authentication.

The desire to deploy your own Keycloak can arise both for experimenting with your projects and for handling your usual backend tasks. This happened to me as well. I decided to kill two birds with one stone. However, I couldn't find a comprehensive guide. I don't need Keycloak locally, but setting it up on a separate, always-available server with backup and the ability to export/import realms, etc., is excellent. Plus, the deployment process is automated, making it easier to switch to another VPS provider.

Everyone has their own motivation, but let's get to the point.

Introduction

What is Keycloak?

Keycloak is an open-source identity and access management solution. It provides features such as SSO (Single Sign-On), user management, authentication, and authorization.

Why Docker-compose?

Docker-compose makes it easy to manage multi-component applications like Keycloak and simplifies the deployment and scaling process. This guide uses containers for Keycloak, Certbot, Nginx, and the Postgres database.

Why Nginx and Certbot?

Nginx will act as a reverse proxy, ensuring security and performance, while Certbot will help obtain and automatically renew SSL certificates from Let's Encrypt, saving us a couple of thousand rubles on certificates for our domain, which is nice.

Let's get started!

Step 1: Preparing the Environment

Cloning the Repository

First, clone the repository with ready-made configurations to our VPS, which I have carefully prepared for you. It contains docker-compose.yml for managing deployment, nginx configs, and an environment variables file needed for docker-compose.

git clone git@github.com:s-rb/keycloak-dockerized-ssl-nginx.git
cd keycloak-dockerized-ssl-nginx
Enter fullscreen mode Exit fullscreen mode

Editing the .env File

Open the .env file and edit the following variables:

  • KEYCLOAK_ADMIN_PASSWORD - Admin password for accessing Keycloak
  • KC_DB_PASSWORD - Password for Keycloak service access to the Postgres DB (should match POSTGRES_PASSWORD if a separate user is not created)
  • POSTGRES_PASSWORD - Admin password for Postgres

Replace password with your values unless you want anyone to connect to your services ;)

Example of a complete environment variables file:

KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=password
PROXY_ADDRESS_FORWARDING=true
KC_PROXY=edge
KC_DB=postgres
KC_DB_URL=jdbc:postgresql://keycloak-postgres:5432/keycloak
KC_DB_USERNAME=keycloak
KC_DB_PASSWORD=password
POSTGRES_DB=keycloak
POSTGRES_USER=keycloak
POSTGRES_PASSWORD=password
Enter fullscreen mode Exit fullscreen mode

Step 2: Domain Registration and DNS Setup

This step can be done before the first step - it does not depend on it. In the following instructions, we assume you have registered your domain (e.g., surkoff.com) and we want Keycloak to be accessible at my-keycloak.surkoff.com.

Domain Registration

Register a domain with any registrar, for example, REG.RU.

Creating an A Record for the Subdomain

Create an A record pointing to your server's IP. For example, for the subdomain my-keycloak.surkoff.com, specify your server's IP.

Creating subdomain

Checking the DNS Record

Ensure the DNS record is correctly configured:

ping my-keycloak.surkoff.com
Enter fullscreen mode Exit fullscreen mode

The response should show your server's IP address.

Step 3: Configuring Nginx

Nginx Configuration

In the nginx configs - default.conf_with_ssl, default.conf_without_ssl edit and specify your domain:

  • server_name section
  • path to the certificate ssl_certificate
  • path to the key ssl_certificate_key

Example configuration with SSL:

server {
    listen 443 ssl;
    server_name my-keycloak.surkoff.com;

    ssl_certificate /etc/letsencrypt/live/my-keycloak.surkoff.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my-keycloak.surkoff.com/privkey.pem;

    location / {
        proxy_pass http://keycloak:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Obtaining an SSL Certificate

Obtaining a Test Certificate

Use the configuration without SSL:

cp nginx/conf.d/default.conf_without_ssl nginx/conf.d/default.conf
docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

Obtain a test certificate (replace the domain and email with your own):

docker exec certbot certbot certonly --webroot --webroot-path=/data/letsencrypt -d my-keycloak.surkoff.com --email your_email@gmail.com --agree-tos --no-eff-email --staging
Enter fullscreen mode Exit fullscreen mode

Obtain test SSL certificate

Checking the Certificate

docker exec certbot certbot certificates
Enter fullscreen mode Exit fullscreen mode

Check if certificate exists

Deleting the Test Certificate (replace the domain with your own)

docker exec certbot certbot delete --cert-name my-keycloak.surkoff.com
Enter fullscreen mode Exit fullscreen mode

Obtaining a Real Certificate (replace email and domain with your own)

docker exec certbot certbot certonly --webroot --webroot-path=/data/letsencrypt -d my-keycloak.surkoff.com --email your_email@gmail.com --agree-tos --no-eff-email
Enter fullscreen mode Exit fullscreen mode

Step 5: Final Configuration and Launch

Updating Nginx Configuration to Use SSL

docker-compose down
cp nginx/conf.d/default.conf_with_ssl nginx/conf.d/default.conf
docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

Checking Access to Keycloak

Open a browser and go to my-keycloak.surkoff.com (your domain).

You should see the admin login page where you can log in using the username and password you specified in the .env file.

Keycloak admin page

For configuring Keycloak, there are interesting articles on other resources, which we won't cover in this publication.

Automatic Certificate Renewal

To automatically renew certificates and restart Nginx, create the renew_and_reload.sh script (already available in the repository):

#!/bin/bash
# Renew certificates
docker exec certbot certbot renew --webroot --webroot-path=/data/letsencrypt

# Restart Nginx
docker restart nginx
Enter fullscreen mode Exit fullscreen mode

Make the script executable:

chmod +x renew_and_reload.sh
Enter fullscreen mode Exit fullscreen mode

Add it to crontab for regular execution:

crontab -e
Enter fullscreen mode Exit fullscreen mode

Add a line to crontab, remembering to specify the path to the script:

0 0 1 * * /path/to/renew_and_reload.sh
Enter fullscreen mode Exit fullscreen mode

Importing Realms

If you want to import a realm at startup, you can place it in the keycloak/config/ folder, and it will be imported when the application starts.

Conclusion

That's it! Now you have a deployed latest Keycloak with SSL on your VPS. I hope this article was helpful! If you have any questions or suggestions, feel free to write to me.

The source code is available at the link here

.