Hello everyone!
In this article, I would like to share how to deploy Keycloak on 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
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
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.
Checking the DNS Record
Ensure the DNS record is correctly configured:
ping my-keycloak.surkoff.com
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` specify your domain:
- In the `server_name` section
- In the path to the certificate `ssl_certificate`
- In the 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;
}
}
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
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
Checking the Certificate
docker exec certbot certbot certificates
Deleting the Test Certificate (replace the domain with your own)
docker exec certbot certbot delete --cert-name my-keycloak.surkoff.com
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
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
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.
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
Make the script executable:
chmod +x renew_and_reload.sh
Add it to crontab for regular execution:
Add a line to crontab, remembering to specify the path to the script:
0 0 1 * * /path/to/renew_and_reload.sh
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 in private messages.