---
title: "Deploy KEYCLOAK"
description: "Auth0 Alternative. Open-source SSO, OIDC and SAML identity server"
category: "Authentication"
url: https://railway.com/deploy/keycloak-iam
---

# Deploy KEYCLOAK

Auth0 Alternative. Open-source SSO, OIDC and SAML identity server

**[Deploy KEYCLOAK on Railway](https://railway.com/template/keycloak-iam)**

- **Creator:** A3A
- **Category:** Authentication
- **Total deploys:** 1

## Template content

### Postgres https://devicons.railway.app/i/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### keycloak https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/keycloak.svg

- **Image:** quay.io/keycloak/keycloak:26.7.1
- **Start command:** `/opt/keycloak/bin/kc.sh start`
- **Health check:** /health/ready
- **Public domain:** Yes

## Documentation

![Keycloak logo](https://github.com/keycloak/keycloak-misc/raw/main/logo/logo.svg)

# Deploy and Host Keycloak on Railway

Keycloak is the open-source identity and access management server built at Red Hat, now a CNCF project. Self-host Keycloak and your applications get single sign-on, OAuth 2.0, OpenID Connect and SAML 2.0 from one place instead of hand-rolled password resets and token endpoints. One server hosts many isolated *realms* with their own users, roles, themes and clients, federates against LDAP and Active Directory, and brokers social logins.

Deploy Keycloak on Railway and two services come up: the official `quay.io/keycloak/keycloak:26.7.1` image and managed PostgreSQL on the private network. Railway terminates TLS at the edge, so `KC_HTTP_ENABLED=true`, `KC_PROXY_HEADERS=xforwarded` and `KC_PROXY_TRUSTED_ADDRESSES=100.64.0.0/10,fd00::/8` are what make tokens carry `https://` URLs and login events record real client IPs. Keycloak 25+ serves health on management port 9000, so `PORT=9000` aims the health check at `/health/ready` while the domain targets 8080 — keeping `/health` off your public URL. All data lives in Postgres, so Keycloak needs no volume.

![Keycloak Railway architecture](https://res.cloudinary.com/rroe4rtk/image/upload/v1786643130/7e4ea8cd-a6e2-464f-b5cf-2edd2ab214e1.png)

## Getting Started with Keycloak on Railway

Open your Railway domain, click **Administration Console** and sign in with `KC_BOOTSTRAP_ADMIN_USERNAME` / `KC_BOOTSTRAP_ADMIN_PASSWORD` — there are no default credentials, and those are read only on the first boot, while `master` is created. Keycloak calls that a *temporary admin*: create a permanent administrator under **master → Users**, give it the `admin` role, then delete the temporary one.

Create your own realm from the selector top-left; never put applications in `master`. Add a user under **Users**, set a non-temporary password on **Credentials**, then register your app under **Clients** as an OpenID Connect client with its callback URL as a valid redirect URI — public with PKCE for browser apps, confidential for server-side. Verify by fetching `/realms//.well-known/openid-configuration` and confirming `issuer` uses your domain.

![Keycloak dashboard screenshot 1](https://res.cloudinary.com/rroe4rtk/image/upload/v1786643122/02-sign-in_d9ll5j.png)
![Keycloak dashboard screenshot 2](https://res.cloudinary.com/rroe4rtk/image/upload/v1786643118/03-authentication_xeorql.png)
![Keycloak dashboard screenshot 3](https://res.cloudinary.com/rroe4rtk/image/upload/v1786643115/01-clients_sknci6.png)

## About Hosting Keycloak

Teams self-host Keycloak when authentication is not something they want to rent: credentials, sessions and audit trails stay in a database you control, per-active-user pricing disappears, and nothing caps realms or clients. Where lighter tools cover OIDC alone, Keycloak adds SAML 2.0 and LDAP/AD federation.

Key features:

- Single sign-on and single logout across every connected app
- OIDC, OAuth 2.0 and SAML 2.0 from one standards-compliant token service
- Multi-realm tenancy: isolated users, roles, themes and policies
- Identity brokering, social login, LDAP/AD federation
- MFA with OTP and WebAuthn passkeys, plus conditional auth flows

PostgreSQL is the system of record for realms, users, clients, keys and sessions, so back up the database, not a volume. Clustering defaults to Infinispan with the `jdbc-ping` stack, so extra replicas find each other through that same database — no multicast, no extra ports.

## Why Deploy Keycloak on Railway

Railway removes the operations work that makes Keycloak expensive to run.

- Managed PostgreSQL provisioned and privately networked
- Automatic HTTPS and a public domain before first boot
- Health checks on the private management port, so `/health` stays off your public URL
- Vertical scaling and extra replicas without re-architecting
- One-click rollbacks when you bump the pinned image tag

## Common Use Cases

- **SSO across internal tools** — Grafana, Nextcloud, Argo CD and your dashboards behind one login, group-based access.
- **SaaS product authentication** — a realm per environment, passkeys and social login, one client per service.
- **B2B and enterprise SSO** — onboard customers who bring their own Okta, Entra ID or ADFS as brokered providers.
- **Machine-to-machine auth** — service-account tokens via client credentials, validated against the realm's JWKS.

## Dependencies for Keycloak

- **Keycloak** — `quay.io/keycloak/keycloak:26.7.1` from [github.com/keycloak/keycloak](https://github.com/keycloak/keycloak). Serves login pages, both consoles, OIDC/SAML endpoints and the admin API on 8080; `/health/*` and `/metrics` on 9000.
- **PostgreSQL** — the system of record; Keycloak migrates it with Liquibase on first boot.

The `ENTRYPOINT` is `/opt/keycloak/bin/kc.sh` with **no `CMD`**, so a start command is mandatory and replaces the entrypoint — give the full path:

```
/opt/keycloak/bin/kc.sh start
```

### Environment Variables Reference

| Variable | Purpose |
|---|---|
| `KC_DB` / `KC_HEALTH_ENABLED` / `KC_METRICS_ENABLED` | Vendor, plus `/health/*` and `/metrics` on 9000. Build-time. |
| `KC_DB_POOL_MAX_SIZE` | Cap at 20; the default 100 can claim a small Postgres instance's whole `max_connections`. |
| `KC_HOSTNAME` | Full `https://` URL, baked into issuer and redirect URLs. |
| `KC_HTTP_ENABLED` / `KC_PROXY_HEADERS` / `KC_PROXY_TRUSTED_ADDRESSES` | Trust Railway's edge. |
| `PORT` | Inert for Keycloak, so purely the health-check target. |

### Deployment Dependencies

- Source:  · Config: 

## Hardware Requirements for Self-Hosting Keycloak

Upstream sizing puts base usage near 1250 MB of RAM per instance and about 1 vCPU per 15 logins per second.

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2–4 vCPU |
| RAM | 1.5 GB | 4 GB or more |
| Storage | None on Keycloak; 1 GB Postgres | 5 GB+ Postgres volume, backed up |
| Runtime | JDK 21, PostgreSQL 13+ | Bundled in the image and managed database |

The image is not pre-built for PostgreSQL, so `kc.sh start` re-augments on boot in about 6 seconds — roughly 11 seconds to listening. Keycloak takes ~70% of the memory limit as heap plus ~300 MB off-heap and reads cgroup limits correctly, so `JAVA_OPTS_APPEND=-XX:MaxRAMPercentage=70` is all the tuning needed.

## Self-Hosting Keycloak with Docker

A quick local trial, in development mode with an in-memory database:

```
docker run -p 8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  -e KC_BOOTSTRAP_ADMIN_PASSWORD=change-me \
  quay.io/keycloak/keycloak:26.7.1 start-dev
```

Never run `start-dev` in production — it relaxes HTTPS and keeps data in memory. A real deployment points at PostgreSQL with the same proxy settings:

```
docker run -p 8080:8080 \
  -e KC_DB=postgres -e KC_DB_POOL_MAX_SIZE=20 \
  -e KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak \
  -e KC_DB_USERNAME=keycloak -e KC_DB_PASSWORD=change-me \
  -e KC_HOSTNAME=https://auth.example.com \
  -e KC_HTTP_ENABLED=true -e KC_PROXY_HEADERS=xforwarded \
  quay.io/keycloak/keycloak:26.7.1 start
```

## How Much Does Keycloak Cost to Self-Host?

Keycloak is free and Apache-2.0 licensed, with no paid tier, no monthly-active-user metering and no feature gating — SAML, LDAP federation, MFA, passkeys and unlimited realms are all in the community build. Red Hat sells an optional supported build with an SLA. Self-hosting costs are infrastructure only: the container, Postgres and its volume.

## Troubleshooting Self-Hosted Keycloak

**Container prints help and exits** → the image has no `CMD`; set the start command to `/opt/keycloak/bin/kc.sh start`.

**Health checks fail while the app responds** → probe port 9000 at `/health/ready`, not 8080.

**Tokens carry `http://` URLs, or logins redirect-loop** → set `KC_HOSTNAME` to the full `https://` URL *before* first boot, with `KC_HTTP_ENABLED=true` and `KC_PROXY_HEADERS=xforwarded`. Changing it later also means updating registered clients.

**Login events show `100.64.x.x`, not real IPs** → add `KC_PROXY_TRUSTED_ADDRESSES=100.64.0.0/10,fd00::/8`.

## FAQ

**What is Keycloak?**

An open-source identity and access management server: single sign-on and standards-based auth over OpenID Connect, OAuth 2.0 and SAML 2.0.

**What does this template deploy?**

Keycloak on the official `quay.io/keycloak/keycloak:26.7.1` image with start command, health check and proxy settings preconfigured, plus managed PostgreSQL.

**Why does this Keycloak template include a PostgreSQL database?**

All persistent state lives there — realms, users, clients, keys, sessions — and Keycloak will not start without it. It is also how `jdbc-ping` clustering finds nodes, and why Keycloak needs no volume.

**How do I connect my application to self-hosted Keycloak?**

Register it as an OpenID Connect client with its callback URL as a valid redirect URI, then point your OIDC library at `/realms//.well-known/openid-configuration` — Spring Security, Auth.js and Grafana need only that issuer URL and a client ID.

**How often should I upgrade self-hosted Keycloak?**

Regularly. There is no long-term-support stream — only the newest release gets security fixes, and 26.7.1 was a security patch over 26.7.0. Pin an exact tag, not `latest`.

## Similar templates

- [Keycloak](https://railway.com/deploy/mSwigX) — Keycloak template with keywind theme + apple and discord providers
- [lua-protector](https://railway.com/deploy/lua-protector) — Test deployed my project first
- [bknd](https://railway.com/deploy/p4nTYL) — Feature-rich yet lightweight backend

Open this page in a browser: https://railway.com/deploy/keycloak-iam
