Keycloak — open-source identity and access management (SSO, OIDC, SAML, social login, user federation). Deployed all-in-one with its PostgreSQL database in a single host-networked Nomad job; Keycloak runs DB migrations automatically on start.
Save as values.hcl, edit, then run:
# The name of the Nomad job.
job_name = "keycloak"
# The Nomad namespace to deploy into.
namespace = "default"
# The datacenters to deploy to.
datacenters = ["*"]
# The Keycloak container image (26.x). Pin a tag in production.
image = "quay.io/keycloak/keycloak:latest"
# Host port for Keycloak's HTTP listener. Serves plain HTTP — front it with a reverse proxy (Traefik) for TLS.
port = 8080
# Public hostname/URL Keycloak is served at (e.g. https://auth.example.com), set when fronting it with a domain. Empty = hostname-strict is off and Keycloak infers it from the request (fine for IP access / testing).
hostname = ""
# Bootstrap admin username, created on first start with an empty database.
admin_user = "admin"
# Bootstrap admin password. CHANGE THIS. Only applied on first start (empty DB); rotate it in the console afterwards.
admin_password = "admin"
# Resources for the Keycloak (JVM) task.
keycloak_resources = {
cpu = 1000
memory = 1024
}
# PostgreSQL image backing Keycloak.
postgres_image = "postgres:16-alpine"
# Host port PostgreSQL listens on. Keycloak connects on 127.0.0.1 (same host network namespace).
db_port = 5432
# Password for the Keycloak database user. CHANGE THIS. (DB name and user are both "keycloak".)
db_password = "keycloak"
# Docker named volume for the Postgres data dir. This is the critical state (realms, users, clients) — back it up. A fresh volume inherits the image's data-dir ownership so Postgres can write it.
db_data_volume = "keycloak_db_data"
# Resources for the PostgreSQL task.
postgres_resources = {
cpu = 500
memory = 512
}
# Placement constraints — pin the job to one node so the Postgres local volume stays put (single all-in-one alloc). On a nomploy cluster: attribute = "$${meta.nomploy_control_plane}", operator = "=", value = "true".
constraints = []
| Name | Type | Default | Description |
|---|---|---|---|
| job_name | string | "keycloak" | The name of the Nomad job. |
| namespace | string | "default" | The Nomad namespace to deploy into. |
| datacenters | list | ["*"] | The datacenters to deploy to. |
| image | string | "quay.io/keycloak/keycloak:latest" | The Keycloak container image (26.x). Pin a tag in production. |
| port | number | 8080 | Host port for Keycloak's HTTP listener. Serves plain HTTP — front it with a reverse proxy (Traefik) for TLS. |
| hostname | string | "" | Public hostname/URL Keycloak is served at (e.g. https://auth.example.com), set when fronting it with a domain. Empty = hostname-strict is off and Keycloak infers it from the request (fine for IP access / testing). |
| admin_user | string | "admin" | Bootstrap admin username, created on first start with an empty database. |
| admin_password key | string | "admin" | Bootstrap admin password. CHANGE THIS. Only applied on first start (empty DB); rotate it in the console afterwards. |
| keycloak_resources | object | {
cpu = 1000
memory = 1024
} | Resources for the Keycloak (JVM) task. |
| postgres_image | string | "postgres:16-alpine" | PostgreSQL image backing Keycloak. |
| db_port | number | 5432 | Host port PostgreSQL listens on. Keycloak connects on 127.0.0.1 (same host network namespace). |
| db_password key | string | "keycloak" | Password for the Keycloak database user. CHANGE THIS. (DB name and user are both "keycloak".) |
| db_data_volume | string | "keycloak_db_data" | Docker named volume for the Postgres data dir. This is the critical state (realms, users, clients) — back it up. A fresh volume inherits the image's data-dir ownership so Postgres can write it. |
| postgres_resources | object | {
cpu = 500
memory = 512
} | Resources for the PostgreSQL task. |
| constraints | list | [] | Placement constraints — pin the job to one node so the Postgres local volume stays put (single all-in-one alloc). On a nomploy cluster: attribute = "$${meta.nomploy_control_plane}", operator = "=", value = "true". |
No variables match.
Keycloak — open-source identity and access management: SSO, OpenID Connect, SAML, social login, and user federation. Put it in front of the services you host so they share one login.
This pack is all-in-one: Keycloak plus its required PostgreSQL in a single
host-networked Nomad job. Postgres starts first (prestart sidecar); Keycloak reaches it
on 127.0.0.1 and runs its schema migrations automatically on start.
nomad-pack registry add nomploy github.com/Nomploy/nomad-packs
nomad-pack run keycloak --registry nomploy
In nomploy: create a Compose service, type Nomad Pack, pack keycloak, custom
registry github.com/Nomploy/nomad-packs, then Deploy.
Open http://<node-ip>:8080/admin and log in as admin / admin (change it). First
boot is slow — Keycloak builds its config and migrates the database before serving.
Keycloak serves plain HTTP here; terminate TLS at a reverse proxy (Traefik). Proxy
headers are enabled (KC_PROXY_HEADERS=xforwarded). When you put it behind a real domain,
set hostname (e.g. https://auth.example.com) — that turns hostname-strict on so
Keycloak pins its issuer/redirect URLs to that domain.
| Variable | Default | Notes |
|---|---|---|
image |
quay.io/keycloak/keycloak:latest |
Pin a 26.x tag in production. |
port |
8080 |
Keycloak HTTP port. |
hostname |
"" |
Public URL when fronted by a domain; empty = infer from request (IP/testing). |
admin_user / admin_password |
admin / admin |
Bootstrap admin, first boot only. Change the password. |
db_password |
keycloak |
Postgres password. Change this. |
db_data_volume |
keycloak_db_data |
Realms/users/clients live here — back it up. |
db_port |
5432 |
Bundled Postgres host port. |
constraints |
[] |
Pin to a node so the DB volume stays put. |
Per-task resources: keycloak_resources (JVM — default cpu 1000 / mem 1024),
postgres_resources.
count is fixed to 1 (local Postgres volume). Pin with constraints.
For HA/clustered Keycloak, run it against an external Postgres and multiple replicas.db_data_volume (or pg_dump the keycloak database).