TL;DR
In this detailed guide, we will set up Keycloak on your VPS step-by-step, transforming it into a powerful Identity and Access Management (IAM) hub with Single Sign-On (SSO) functionality. You will learn how to install all necessary components, configure Keycloak to work with PostgreSQL and HTTPS via Caddy, and ensure its security and fault tolerance. This will allow you to centralize authentication for your applications, enhance security, and simplify user management.
- Installation and configuration of Keycloak 25.0.0 with PostgreSQL 17.
- Using Docker Compose for easy deployment.
- Automatic acquisition and renewal of TLS certificates with Caddy.
- Basic server protection (SSH, Firewall, Fail2ban).
- Setting up automatic database and configuration backups.
- Recommendations for VPS configuration selection and scaling.
What we are setting up and why
In today's world, where every application requires authentication, managing user accounts can become a real headache. Keycloak solves this problem by providing a powerful Identity and Access Management (IAM) platform with Single Sign-On (SSO) support.
Keycloak is an open-source solution that allows you to centrally manage users, roles, groups, and grant them access to your applications. It supports standard protocols such as OpenID Connect, OAuth 2.0, and SAML 2.0, making it compatible with virtually any modern web application or service. With Keycloak, you can:
- Implement Single Sign-On (SSO): Users only need to authenticate once to access all connected applications without re-entering credentials.
- Manage users and roles: Centralized creation, editing, and deletion of users, assigning them roles and groups.
- Use social login: Easily integrate login via Google, GitHub, Facebook, and other popular providers.
- Apply Multi-Factor Authentication (MFA): Enhance account security.
- Configure identity federation: Connect external providers such as LDAP or Active Directory.
Ultimately, the reader will get a fully configured and ready-to-use Keycloak server that will serve as a central authentication point for their projects. This will significantly simplify the development of new applications, enhance security, and improve the user experience.
Alternatives: Cloud-managed vs Self-hosted
There are commercial cloud IAM/SSO services such as Auth0, Okta, Amazon Cognito, Google Identity Platform. They offer "turnkey" convenience, relieving the burden of maintenance and scaling. However, they have their drawbacks:
- Cost: As the number of users or features grows, costs can quickly become significant.
- Data control: Your authentication data is stored with a third-party provider, which may be unacceptable for security, privacy, or regulatory reasons.
- Flexibility: While cloud services are flexible, they still have limitations in customization and integration that an open-source solution might not.
Self-hosted Keycloak on a VPS offers complete control over your authentication system. It is an ideal choice for developers, solo SaaS founders, companies requiring a high degree of customization, or those looking to minimize operational costs in the long run. You manage all aspects of security, performance, and data, providing maximum freedom and independence.
What VPS configuration is needed for this task
Keycloak, being a Java application, requires sufficient resources, especially RAM. The choice of optimal VPS configuration depends on the anticipated load: the number of users, frequency of authentications, and the number of connected applications.
Minimum requirements for a small installation (up to 500 active users)
- CPU: 2 vCPU (virtual cores). This will be sufficient to handle most requests.
- RAM: 4 GB. Keycloak itself can consume 1.5-2 GB RAM, plus PostgreSQL and the operating system.
- Disk: 50 GB SSD. SSD is critical for database performance and fast Keycloak loading. 50 GB is enough for the OS, Keycloak, and a moderate amount of DB data.
- Network: 100 Mbps. For most tasks, this is more than enough.
Recommended VPS plan for a medium project (up to 5000 active users)
For more serious loads or if you plan to actively use Keycloak with multiple applications and a large number of users, it is recommended to consider the following configuration:
- CPU: 4 vCPU. Will provide better responsiveness during peak loads.
- RAM: 8 GB. Will allow Keycloak and PostgreSQL to cache data more efficiently and process more concurrent requests.
- Disk: 100-200 GB SSD. A larger disk volume will provide space for logs, backups, and database growth.
- Network: 1 Gbps. For high-load applications.
For renting a VPS with the specified characteristics, you can choose a VPS with 4 vCPU, 8 GB RAM, and 100 GB SSD.
When a dedicated server is needed, not a VPS
A dedicated server becomes necessary when:
- Very high load: Thousands of simultaneous requests, tens of thousands of active users.
- Performance requirements: Guaranteed performance is needed without "neighboring" other users on the same physical server.
- Specific hardware requirements: For example, hardware security modules (HSM) or a very large amount of RAM/disk.
- Strict compliance standards: Some regulatory requirements may mandate the use of physically isolated hardware.
For such cases, when maximum performance and isolation are required, you can consider a suitable dedicated server.
Location: what it affects
Choosing a VPS location is important for several reasons:
- Latency: The closer the server is to your users and applications, the lower the latency. This is critical for interactive services.
- Data legislation: Depending on where your users are located and where you conduct business, various laws on personal data storage and processing may apply (e.g., GDPR in Europe). Choosing a server location that complies with these laws is mandatory.
- Availability: Placing servers in different geographical locations can increase the fault tolerance of your infrastructure.
Always choose a location that is as close as possible to the primary audience of your applications.
Server preparation
Before installing Keycloak, you need to perform basic setup of the new VPS to ensure security and stability. We will use Ubuntu Server 24.04 LTS as the operating system.
1. System update
First, update all packages to their current versions.
sudo apt update && sudo apt upgrade -y
This command updates the list of available packages and then upgrades installed packages to the latest versions.
2. Creating a new user and configuring SSH access
For increased security, it is not recommended to work as the root user. Let's create a new user and grant them sudo privileges.
# Create a new user (replace 'youruser' with your desired name)
sudo adduser youruser
# Add the user to the sudo group
sudo usermod -aG sudo youruser
Now, copy your public SSH key for the new user. From your local machine:
ssh-copy-id youruser@your_vps_ip
After this, exit the root session and log in as the new user.
exit
ssh youruser@your_vps_ip
3. Configuring SSH server
Disable password login and root user login, leaving only key authentication.
sudo nano /etc/ssh/sshd_config
Find and change the following lines:
# Forbid root user login
PermitRootLogin no
# Forbid password login
PasswordAuthentication no
# Allow only key authentication
PubkeyAuthentication yes
Save changes (Ctrl+O, Enter) and exit (Ctrl+X). Restart the SSH server:
sudo systemctl restart sshd
Important: Make sure you can log in as the new user with an SSH key before closing the current session!
4. Configuring firewall (UFW)
Uncomplicated Firewall (UFW) is an easy-to-use interface for iptables. Let's configure it to allow only necessary ports.
# Allow SSH (port 22, if you haven't changed it)
sudo ufw allow OpenSSH
# Allow HTTP (port 80)
sudo ufw allow http
# Allow HTTPS (port 443)
sudo ufw allow https
# Enable the firewall
sudo ufw enable
# Check firewall status
sudo ufw status
The output of sudo ufw status should show that SSH, HTTP, and HTTPS are allowed.
5. Installing Fail2ban
Fail2ban scans logs and blocks IP addresses showing signs of malicious activity (e.g., multiple failed SSH login attempts).
# Install Fail2ban
sudo apt install fail2ban -y
# Copy the default configuration file
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Start and enable Fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Check status
sudo systemctl status fail2ban
Fail2ban protects SSH by default. You can configure it to protect other services by editing /etc/fail2ban/jail.local.
6. Installing basic utilities
Let's install some useful utilities that will come in handy during setup and monitoring.
sudo apt install curl wget git htop net-tools -y
Now your server is ready for the main software installation.
Software Installation — Step-by-Step
For ease of deployment and management, we will use Docker and Docker Compose. This will allow Keycloak and PostgreSQL to be isolated, simplifying their updates and configuration. All versions are current for 2026.
1. Docker Installation
Let's install Docker Engine on Ubuntu.
# Remove old Docker versions, if any
for pkg in docker.io docker-doc docker-compose docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin; do sudo apt remove $pkg; done
# Install necessary packages
sudo apt install ca-certificates curl gnupg lsb-release -y
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add Docker repository to APT
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update package list and install Docker Engine
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
# Add current user to the docker group to work without sudo
sudo usermod -aG docker youruser
Log out of your current SSH session and log back in for group changes to take effect. Verify Docker installation:
docker run hello-world
If you see a welcome message from Docker, the installation was successful.
2. Caddy Installation (Reverse Proxy and TLS)
Caddy is a powerful, easy-to-configure web server that automatically obtains and renews TLS certificates from Let's Encrypt. This significantly simplifies HTTPS setup.
# Install necessary packages
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
# Add Caddy's official GPG key
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# Add Caddy repository to APT
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
# Update package list and install Caddy
sudo apt update
sudo apt install caddy -y
# Check Caddy status
sudo systemctl status caddy
Caddy will be installed as a system service, but we will not configure it yet; this will be done later.
3. Creating a Docker Compose File for Keycloak and PostgreSQL
Let's create a directory for the Keycloak project and the file docker-compose.yml.
mkdir keycloak-sso
cd keycloak-sso
nano docker-compose.yml
Paste the following content. We are using Keycloak 25.0.0 and PostgreSQL 17.
version: '3.8'
services:
keycloak:
image: quay.io/keycloak/keycloak:25.0.0 # Current Keycloak version
container_name: keycloak
environment:
KEYCLOAK_ADMIN: admin # Keycloak administrator name
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} # Administrator password (will be taken from .env)
KC_DB: postgres # Use PostgreSQL
KC_DB_URL: jdbc:postgresql://db:5432/keycloak # Database URL
KC_DB_USERNAME: keycloak # DB user
KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD} # DB password (will be taken from .env)
KC_HOSTNAME: ${KEYCLOAK_HOSTNAME} # Keycloak domain name (will be taken from .env)
KC_PROXY: edge # Important for working with a reverse proxy
KC_HTTP_ENABLED: 'true' # Keycloak will listen on HTTP for the proxy
KC_HTTP_PORT: 8080 # Port on which Keycloak listens for HTTP
KC_HEALTH_ENABLED: 'true' # Enable Health Check
KC_METRICS_ENABLED: 'true' # Enable metrics
JAVA_OPTS_APPEND: -Dquarkus.log.level=INFO -Dquarkus.log.category."org.keycloak".level=INFO # Logging settings
ports:
- "8080:8080" # Keycloak's internal port, proxied by Caddy
volumes:
- ./keycloak-data:/opt/keycloak/data # Persistent storage for Keycloak data
command: start --optimized --hostname-strict=false # Start Keycloak in optimized mode
depends_on:
db:
condition: service_healthy
restart: always
db:
image: postgres:17-alpine # Current PostgreSQL version
container_name: keycloak-db
environment:
POSTGRES_DB: keycloak # Database name
POSTGRES_USER: keycloak # Database user
POSTGRES_PASSWORD: ${KEYCLOAK_DB_PASSWORD} # Database password (will be taken from .env)
volumes:
- ./postgres-data:/var/lib/postgresql/data # Persistent storage for DB data
healthcheck: # DB health check
test: ["CMD-SHELL", "pg_isready -U keycloak"]
interval: 5s
timeout: 5s
retries: 5
restart: always
Save the file (Ctrl+O, Enter) and exit (Ctrl+X).
4. Creating the .env file
To store sensitive data and the domain name, let's create a .env file.
nano .env
Paste the following content, replacing the placeholders with your actual values:
KEYCLOAK_ADMIN_PASSWORD=YourStrongAdminPassword123! # Change to a strong password
KEYCLOAK_DB_PASSWORD=YourStrongDBPassword456! # Change to a strong password for the DB
KEYCLOAK_HOSTNAME=auth.yourdomain.com # Replace with your domain for Keycloak (e.g., keycloak.example.com)
Important: Make sure you use very strong passwords and that the domain name auth.yourdomain.com (or any other you choose) already points to your VPS's IP address in your DNS records.
5. Starting Keycloak and PostgreSQL
Now you can start the containers using Docker Compose.
docker compose up -d
This command will start Keycloak and PostgreSQL in the background. Docker Compose will first create networks and volumes, then start the PostgreSQL container, wait for it to be ready (healthcheck), and then start Keycloak.
Check the container status:
docker compose ps
Both containers should be in the "running" state.
Configuration
After starting the Keycloak and PostgreSQL containers, you need to configure the Caddy reverse proxy to provide HTTPS and ensure Keycloak works correctly with external access.
1. Configuring Caddy for Keycloak
Edit the Caddy configuration file. By default, it is located at /etc/caddy/Caddyfile.
sudo nano /etc/caddy/Caddyfile
Remove all default content and paste the following. Replace auth.yourdomain.com with your Keycloak domain.
auth.yourdomain.com {
# Enable automatic HTTPS with Let's Encrypt
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN} # If you use Cloudflare for DNS, specify the API token
# If you don't use Cloudflare DNS, just leave tls
}
# Settings for proxying requests to Keycloak
reverse_proxy keycloak:8080 {
# Pass important headers for Keycloak to work correctly behind a proxy
header_up Host {host}
header_up X-Real-IP {remote_ip}
header_up X-Forwarded-For {remote_ip}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Host {host}
}
# Security settings
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Frame-Options "DENY"
X-Content-Type-Options "nosniff"
Referrer-Policy "strict-origin-when-cross-origin"
# Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" # Configure if necessary
}
# Logging
log {
output file /var/log/caddy/keycloak_access.log
format json
}
}
Note on tls: If you are using a DNS provider other than Cloudflare, or do not want to use a DNS challenge, you can simply leave the tls line. Caddy will attempt to use the HTTP-01 challenge, which requires port 80 to be accessible externally. If you are using Cloudflare, as in the example, you will need to create the file /etc/caddy/Caddyfile.env:
sudo nano /etc/caddy/Caddyfile.env
And add your Cloudflare API Token there:
CLOUDFLARE_API_TOKEN=YOUR_CLOUDFLARE_API_TOKEN
Ensure this token has permissions to manage DNS records for your domain.
Save the file(s). Validate Caddy's configuration and restart it:
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
If validation is successful, Caddy will restart and attempt to obtain a TLS certificate.
2. Verifying Functionality
After all configurations, it is necessary to ensure that Keycloak is running and accessible.
Container Check
Ensure both containers are running:
docker compose ps
The output should show State: Up for both services.
Checking Keycloak Accessibility via Domain
Open https://auth.yourdomain.com/admin in your browser (replace with your domain). You should see the Keycloak administrative console login page.
Enter the login admin and the password you specified in the .env file (KEYCLOAK_ADMIN_PASSWORD).
Checking OpenID Connect Configuration
You can verify that Keycloak correctly provides its OpenID Connect configuration:
curl -k https://auth.yourdomain.com/realms/master/.well-known/openid-configuration
You should receive a JSON response with OpenID Connect metadata for the default master realm.
If all steps are completed correctly, Keycloak is fully installed and configured to work with HTTPS and a PostgreSQL database.
Backups and Maintenance
Reliable backup and regular maintenance are critically important for any production system. Keycloak is no exception, especially since it stores all user data and authentication configurations.
1. What to Back Up
- PostgreSQL Database: This is the most important component, as it contains all information about users, realms, clients, roles, and Keycloak sessions.
- Keycloak Configuration: In our case with Docker Compose, the main Keycloak settings are defined in the
docker-compose.ymland.envfiles. However, if you made any specific changes inside the container (which is not recommended for Dockerized applications), they also need to be backed up. It is also useful to save thekeycloak-dataandpostgres-datavolumes. - Caddy Configuration: The
/etc/caddy/Caddyfilefile and, possibly,/etc/caddy/Caddyfile.env. - Logs: For debugging and auditing. Although not critical for recovery, they are useful.
2. Simple Auto-Backup Script
Let's create a simple bash script that will dump the database and archive important files.
Create a directory for backups and the script itself:
sudo mkdir -p /var/backups/keycloak
sudo nano /usr/local/bin/keycloak_backup.sh
Paste the following content. Replace keycloak-sso with the name of your Docker Compose directory if it differs.
#!/bin/bash
# Path to the Docker Compose directory
DOCKER_COMPOSE_DIR="/home/youruser/keycloak-sso" # Specify the full path to your keycloak-sso directory
# Directory for storing backups
BACKUP_DIR="/var/backups/keycloak"
# .env file name
ENV_FILE="${DOCKER_COMPOSE_DIR}/.env"
# Load environment variables from .env
if [ -f "$ENV_FILE" ]; then
export $(grep -v '^#' "$ENV_FILE" | xargs)
else
echo "Error: .env file not found at $ENV_FILE"
exit 1
fi
DATE=$(date +%Y%m%d%H%M%S)
BACKUP_FILENAME="${BACKUP_DIR}/keycloak_backup_${DATE}.tar.gz"
DB_DUMP_FILE="${BACKUP_DIR}/keycloak_db_dump_${DATE}.sql"
echo "Starting Keycloak backup..."
# 1. PostgreSQL Database Backup
echo "Creating PostgreSQL database dump..."
docker compose -f "${DOCKER_COMPOSE_DIR}/docker-compose.yml" exec -T db pg_dump -U keycloak -d keycloak > "$DB_DUMP_FILE"
if [ $? -eq 0 ]; then
echo "DB dump successfully created: $DB_DUMP_FILE"
else
echo "Error creating DB dump."
exit 1
fi
# 2. Archiving important files and data
echo "Archiving configuration files and data..."
tar -czf "$BACKUP_FILENAME" \
--absolute-names \
"${DOCKER_COMPOSE_DIR}/docker-compose.yml" \
"${DOCKER_COMPOSE_DIR}/.env" \
"$DB_DUMP_FILE" \
"/etc/caddy/Caddyfile" \
"/etc/caddy/Caddyfile.env" \
"${DOCKER_COMPOSE_DIR}/keycloak-data" \
"${DOCKER_COMPOSE_DIR}/postgres-data" # Adding persistent volumes
if [ $? -eq 0 ]; then
echo "Backup archive successfully created: $BACKUP_FILENAME"
else
echo "Error creating backup archive."
exit 1
fi
# 3. Deleting temporary DB dump
rm "$DB_DUMP_FILE"
# 4. Deleting old backups (keeping the last 7 days)
echo "Deleting old backups (older than 7 days)..."
find "$BACKUP_DIR" -type f -name "keycloak_backup_*.tar.gz" -mtime +7 -delete
echo "Keycloak backup completed."
Make the script executable:
sudo chmod +x /usr/local/bin/keycloak_backup.sh
3. Scheduling Backups with Cron
Let's add the script to the Cron schedule for daily execution (e.g., at 3:00 AM).
sudo crontab -e
Add the following line to the end of the file:
0 3 * * * /usr/local/bin/keycloak_backup.sh >> /var/log/keycloak_backup.log 2>&1
This line will run the script every day at 3:00 AM, and the output will be redirected to the log file /var/log/keycloak_backup.log.
4. Where to Store Backups (External Storage)
Storing backups on the same server as the main service is risky. In case of server failure, you will lose both data and backups. It is recommended to use external storage:
- Cloud Object Storage (S3-compatible): Amazon S3, DigitalOcean Spaces, Backblaze B2. This is an economical and reliable solution. You can use utilities like
s3cmdorrclonefor automatic backup uploads. - Separate VPS: If you have another VPS, you can set up
rsyncorscpto copy backups to it. - Specialized Solutions: BorgBackup or Restic for deduplicated, encrypted backups.
For example, to upload to S3 using rclone, you would add a line to the script after creating the archive:
# rclone copy "$BACKUP_FILENAME" "remote_s3_storage:keycloak-backups/"
After configuring rclone with your S3 credentials.
5. Updates: rolling vs maintenance window
- OS and Docker Updates: Regularly update your operating system and Docker. For Ubuntu, this is
sudo apt update && sudo apt upgrade -y. Do this during scheduled times, as a server reboot may sometimes be required. - Keycloak Updates: For Keycloak in Docker Compose, this involves changing the image version in
docker-compose.yml(e.g., from25.0.0to25.0.1) and then runningdocker compose pull keycloak && docker compose up -d. Always read the release notes before updating, as there may be configuration changes or DB migrations. - PostgreSQL Updates: Upgrading major PostgreSQL versions (e.g., from 16 to 17) requires a more complex data migration procedure. This should always be performed within a planned "maintenance window" with a prior backup. Minor updates (e.g., 17.0 to 17.1) are usually safe and do not require migration.
For production systems, it is always recommended to have a test environment where you can first verify updates before applying them to the main server.
Troubleshooting + FAQ
In this section, we will cover typical issues that may arise during Keycloak installation and configuration, and answer frequently asked questions.
Keycloak Fails to Start / DB Connection Error
Problem: The Keycloak container constantly restarts or throws database connection errors in the logs. What to check:
- Keycloak logs:
docker compose logs keycloak. Look for messages about PostgreSQL connection errors. - PostgreSQL logs:
docker compose logs db. Ensure that PostgreSQL is successfully started and listening for connections. - Environment variables: Check the correctness of
KC_DB_URL,KC_DB_USERNAME,KC_DB_PASSWORDindocker-compose.ymland.env. Make sure the passwords match. - PostgreSQL Healthcheck: Ensure that the healthcheck for the
dbcontainer passes successfully (docker compose ps). Keycloak will not start until the DB is ready.
sudo rm -rf keycloak-sso/postgres-data) and run docker compose up -d again (this will delete all DB data!).
Cannot Access Keycloak Admin Console via Domain
Problem: When trying to open https://auth.yourdomain.com/admin, the browser shows a "Connection refused" or "ERR_CONNECTION_CLOSED" error.
What to check:
- DNS record: Ensure that your domain (e.g.,
auth.yourdomain.com) correctly points to your VPS's IP address. Usedig auth.yourdomain.com. - Firewall (UFW): Check that ports 80 and 443 are open:
sudo ufw status. - Caddy: Check Caddy's status:
sudo systemctl status caddy. Ensure it is running and there are no errors in its logs:sudo journalctl -u caddy. - Caddyfile configuration: Check that the domain in
Caddyfilematches yours, and thatreverse_proxycorrectly points to the Keycloak container (keycloak:8080). KC_PROXYvariable: Ensure that theKC_PROXY: edgevariable is set for Keycloak indocker-compose.yml.
Caddyfile, and restart Caddy: sudo systemctl reload caddy. Restart Keycloak if you changed KC_PROXY.
HTTPS Issues / Caddy Fails to Obtain Certificate
Problem: Caddy cannot obtain a TLS certificate from Let's Encrypt, and the site is only accessible via HTTP (or not at all). What to check:
- Caddy logs:
sudo journalctl -u caddy --no-pager. Look for errors related totlsor Let's Encrypt. - Port 80/443 availability: Ensure that no other services are occupying ports 80 or 443. (
sudo lsof -i :80,sudo lsof -i :443). - DNS record: Ensure that your domain correctly points to your VPS. Let's Encrypt verifies domain ownership.
- DNS challenge configuration (if used): If you are using
tls { dns ... }, check that the environment variable with the API token is correctly set and the token itself has the necessary permissions.
sudo systemctl reload caddy.
How to Reset Keycloak Admin Password?
Problem: You forgot the Keycloak administrator password.
What to check: The administrator password is set by the KEYCLOAK_ADMIN_PASSWORD variable in the .env file.
How to fix:
- Edit the
.envfile and change theKEYCLOAK_ADMIN_PASSWORDvalue to a new, strong password. - Restart the Keycloak container for the changes to take effect:
docker compose restart keycloak. - You will now be able to log in to the admin console with the new password.
What is the minimum suitable VPS configuration?
A minimally suitable VPS configuration for installing Keycloak for a small project (up to 500 active users) includes 2 vCPUs, 4 GB of RAM, and a 50 GB SSD. This should be sufficient for running the operating system, Keycloak, and its PostgreSQL database. It is important that the disk is an SSD to ensure adequate database performance. As the load or number of users increases, resource scaling will be required.
What to choose — VPS or dedicated for this task?
The choice between a VPS and a dedicated server depends on the scale of your project and performance requirements. For most startups, small to medium-sized teams, and individual projects, a VPS will be the optimal choice. It is economical, flexible, and easily scalable. A dedicated server becomes preferable for high-load systems with thousands of concurrent users, critically important performance, strict resource isolation requirements, or specific hardware needs that cannot be met on a virtual machine.
How to Scale Keycloak?
Problem: Your Keycloak installation is experiencing high load, and the current VPS performance is insufficient. What to check: Monitor CPU, RAM, disk I/O on your VPS. Keycloak logs for delays or errors. How to fix:
- Vertical Scaling (Scale Up): Increase the resources of your current VPS (CPU, RAM, Disk). This is the simplest first step.
- Horizontal Scaling (Scale Out): Deploy multiple Keycloak instances behind a load balancer. This requires configuring Keycloak in cluster mode (with a shared database and cache).
- Database Optimization: Ensure that PostgreSQL has sufficient resources and is configured for optimal performance.
- Keycloak Optimization: Configure JVM, caching, and logging parameters for better performance.
Conclusions and Next Steps
Congratulations! You have successfully installed and configured Keycloak on your VPS, creating a robust platform for identity and access management with single sign-on capabilities. You now have a centralized authentication solution that enhances security and simplifies user management for your applications.
Next steps for further developing your system:
- Application Integration: Connect your web applications, APIs, or microservices to Keycloak using available adapters or standard OpenID Connect/OAuth 2.0 protocols.
- Advanced Configuration: Explore additional Keycloak features, such as theme customization, adding multi-factor authentication (MFA), and federation with external identity providers (LDAP, Active Directory, social networks).
- Monitoring and Fault Tolerance: Set up a monitoring system (e.g., Prometheus + Grafana) to track Keycloak performance. For high-load production environments, consider Keycloak clustering to ensure high availability.





