---
title: Red Hat OpenShift
description: "Install OpenLM Platform on Red Hat OpenShift: turn on the chart's OpenShift mode, use routes, and fit the restricted security context constraints."
product: OpenLM Platform
---

To install OpenLM Platform on a Red Hat OpenShift cluster, turn on the OpenLM Platform chart's OpenShift mode. In that mode the chart serves OpenLM Platform through OpenShift routes instead of Ingress objects, and it lets OpenShift assign the user IDs its pods run as. Do the common steps in [Platform installation](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/platform-installation), and add the settings on this page where that page installs the API gateway and OpenLM Platform.

:::info[Preview: the openlm-platform chart]
This page covers the current `openlm_mono` chart. For the new `openlm-platform` 1.0 chart, available as a release candidate, follow [OpenLM Platform on OpenShift](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/kubernetes/platforms/openshift) in the preview guide.
:::

## Before you begin

Confirm these prerequisites:

- **OpenShift version**: OpenLM has tested the OpenLM Platform chart on OpenShift 4.18 and 4.20.
- **Project**: Install the API gateway and OpenLM Platform into a project named `openlm`. Both charts create their routes in the `openlm` namespace, and the OpenLM Platform components carry `openlm` as their namespace by default. Installing into another project means overriding that namespace in every component you turn on.
- **Host name**: One fully qualified domain name (FQDN) for OpenLM Platform, for example `openlm.example.com`, that resolves to the OpenShift router. Keep it short: see [Why do web components crash-loop on a long host name?](#why-do-web-components-crash-loop-on-a-long-host-name).
- **Certificate**: The certificate the router serves for that host name. See [Certificates on OpenShift](#certificates-on-openshift).
- **Images**: Pull access to `public.ecr.aws/r3q3q2f4` (OpenLM images), `docker.tyk.io` (the API gateway), and `docker.io` (the gateway's `busybox` init container, and Bitnami infrastructure images if you run them in the cluster). If the cluster pulls through a mirror, mirror these registries.
- **Infrastructure**: SQL Server, MongoDB, Kafka, and Redis, outside the cluster or in it. See [Infrastructure services on OpenShift](#infrastructure-services-on-openshift).

## How the OpenShift mode works

To serve OpenLM Platform through routes, set `global.useOpenShift: true` in the OpenLM Platform values file. The chart then changes three things:

- It creates an OpenShift route for each web component instead of an Ingress object: 32 routes for the full on-premises component set. Each route terminates TLS at the router (edge termination) and redirects HTTP to HTTPS.
- It adds an HTTP Strict Transport Security (HSTS) header and these security response headers to every route: `X-Frame-Options`, `X-Content-Type-Options`, `Referrer-Policy`, and `Content-Security-Policy: frame-ancestors 'self'`. To leave them out, set `global.routeSecurity.enabled: false`.
- It leaves `runAsUser`, `runAsGroup`, and `fsGroup` out of every pod. OpenShift then assigns them from the project's range under the default `restricted-v2` security context constraint (SCC).

The rest of each pod's security context stays as the chart defines it: every component of the on-premises set runs as non-root, with the `RuntimeDefault` seccomp profile, no privilege escalation, and all Linux capabilities dropped. No component in the chart runs privileged, uses the host network, mounts a host path, or runs as user ID 0.

## Set the OpenLM Platform values

Add the following settings to the values file you write in [Platform installation](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/platform-installation#write-the-values-file).

### Turn on the OpenShift mode

Set the OpenShift switch. Leave `global.masterIngress.enabled` at its default, `false`: the routes take its place.

```yaml
global:
  useOpenShift: true
```

### Set your host name on every web component

Each route takes its host from its own component's `ingress.hostname`. The chart has no global host name, and the default is an OpenLM development host, `dev-k8s-us-cloud.openlm.com`. Set your FQDN on each web component you turn on:

```yaml
homepageui:
  enabled: true
  ingress:
    hostname: openlm.example.com
identity:
  enabled: true
  ingress:
    hostname: openlm.example.com
```

The following components have a route. Set `ingress.hostname` on each one you turn on:

<details>
<summary>Components with a route (32)</summary>

`agentactivitymanagerui`, `agentshubui`, `alertsserviceui`, `auditserviceui`, `brokerhubui`, `cloudbrokerui`, `complianceserviceui`, `denialsui`, `donglemonitoringui`, `dssui`, `homepageui`, `identity`, `identityui`, `integrationui`, `licenseaccesscontrolui`, `licenseallocationsui`, `licensefilesui`, `licensemanagerui`, `licenseserversui`, `licensesui`, `navigationui`, `notificationui`, `personaldashboard`, `processmanagerui`, `productsserviceui`, `projectsserviceui`, `samcatalogui`, `softwareassetmanagementui`, `uiconfigurationserviceui`, `usageui`, `usersandgroupsserviceui`, `vlmui`

</details>

To check the hosts before you install, render the chart and count them. Every line of the output must show your FQDN:

```bash
helm template monohelm openlm_mono-<version>.tgz -f mono-values.yaml -n openlm \
  | grep -E '^[[:space:]]+host:' | sort | uniq -c
```

### Run without node labels

By default the chart schedules workloads only on nodes labeled `openlm.com/role=main` or `openlm.com/role=spark`. If your cluster's nodes don't carry these labels, turn node affinity and the matching tolerations off, or the pods never get a node:

```yaml
global:
  affinity:
    enabled: false
  taints:
    enabled: false
```

To keep the dedicated node roles instead, label the nodes as described in [Node affinity](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/platform-installation#node-affinity).

## Certificates on OpenShift

The routes terminate TLS at the router and carry no certificate of their own, so the router serves its Ingress Controller's default certificate for them ([Red Hat: Certificate types and descriptions](https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/security_and_compliance/certificate-types-and-descriptions)). The `openlm-lb-cert` secret from [Platform installation](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/platform-installation) doesn't change what the routes serve. Use one of these setups:

- **Host name under the cluster's apps domain**: For example `openlm.apps.<cluster-domain>`. The router's wildcard certificate covers it.
- **Any other host name**: Your cluster administrator configures the certificate the Ingress Controller serves for it ([Red Hat: Replacing the default ingress certificate](https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/security_and_compliance/configuring-certificates#replacing-default-ingress)).

Agents, browsers, and the OpenLM Platform components must all trust that certificate: the components call the OpenLM Platform public URL (`https://<FQDN>/identity`) from inside the cluster. If the certificate comes from a private CA, mount the CA chain into the components as described in [Trust a private CA inside the cluster](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/tls-certificates#trust-a-private-ca-inside-the-cluster).

## Install the API gateway

The gateway chart creates the `/api` route itself. Install it into `openlm` as described in [API gateway installation](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/platform-installation#install-the-api-gateway), with these settings in the gateway values:

```yaml
openShiftRoute:
  enabled: true
  host: openlm.example.com
tyk-oss:
  tyk-gateway:
    gateway:
      hostName: openlm.example.com
      ingress:
        enabled: false
      securityContext:
        runAsUser: null
        fsGroup: null
      containerSecurityContext:
        runAsUser: null
```

Each setting does the following:

- `openShiftRoute` creates the `/api` route in the `openlm` namespace with edge TLS termination. From gateway chart `0.2.11`, the route carries the same HSTS and security headers as the OpenLM Platform routes.
- `ingress.enabled: false` turns off the gateway's own Ingress object, which the route replaces.
- The `null` values remove the fixed IDs of the Tyk gateway pods, `runAsUser: 1000` and `fsGroup: 2000`. The `restricted-v2` SCC refuses IDs outside the project's range, so with the fixed IDs the gateway pod never starts and every `/api` call fails.

Helm 4 removes a sub-chart value that you set to `null`. Helm 3 keeps the chart's value instead. On Helm 3, replace each `null` with the first ID of the project's range, which this command prints:

```bash
oc get namespace openlm -o jsonpath='{.metadata.annotations.openshift\.io/sa\.scc\.uid-range}'
```

The output has the form `<first-id>/<size>`, for example `1005910000/10000`.

## Infrastructure services on OpenShift

OpenLM Platform needs only the endpoints and credentials of SQL Server, MongoDB, Kafka, and Redis, so they can run outside the cluster. If you run them in the cluster, check each chart's security context against the `restricted-v2` SCC. The following table shows how the Bitnami charts that OpenLM uses behave:

| Chart | On OpenShift |
| --- | --- |
| MariaDB `22.0.0`, MongoDB `15.6.19`, PostgreSQL `16.7.21`, Redis `20.1.7` | Adapt their security context to OpenShift by themselves (`global.compatibility.openshift.adaptSecurityContext: auto`). |
| Kafka `26.6.2` | Sets `runAsUser: 1001` and `fsGroup: 1001` on the controller and broker pods, with no OpenShift adaptation. Admit these IDs for the Kafka pods, override them in the Kafka values, or run Kafka outside the cluster. |

## Install OpenLM Platform

Install OpenLM Platform into `openlm` with the command in [Install the platform](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/platform-installation#install-openlm-platform), using the values file with the OpenShift settings.

## Verify the installation

Run these checks after the installation:

1. List the routes:

   ```bash
   oc get routes -n openlm
   ```

   Every route shows your FQDN as its host, and the gateway's `/api` route is in the list.

2. List the pods that aren't running:

   ```bash
   oc get pods -n openlm | grep -vE 'Running|Completed'
   ```

   When every pod is up, the output is only the header line.

3. Run the requests in [Verify deployment](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/platform-installation#verify-deployment).

## Troubleshooting

The following entries cover common problems when you install OpenLM Platform on OpenShift.

### Why are pods refused by a security context constraint?

A pod is configured with a user or group ID outside the project's range. Helm still reports the release as `deployed`, so look for the refusal in the events:

```bash
oc get events -n openlm --field-selector reason=FailedCreate
```

For the OpenLM Platform components, set `global.useOpenShift: true`. For the API gateway and Kafka, remove or replace the fixed IDs as described in [Install the API gateway](#install-the-api-gateway) and [Infrastructure services on OpenShift](#infrastructure-services-on-openshift).

### Why do pods never get a node?

Node affinity or the tolerations are on, but no node carries the matching `openlm.com/role` label, so the pods stay in the `Pending` state. Set `global.affinity.enabled: false` and `global.taints.enabled: false`, or label the nodes as described in [Node affinity](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/platform-installation#node-affinity).

### Why does a route show the wrong host?

A route that shows `dev-k8s-us-cloud.openlm.com` belongs to a component with no `ingress.hostname` in your values file. Add your FQDN to that component, and run the installation command again.

### Why does every /api call fail with 503?

The API gateway pod isn't running. Check the gateway's events for an SCC refusal, and set its IDs as described in [Install the API gateway](#install-the-api-gateway).

### Why do web components crash-loop on a long host name?

The web components write your FQDN into their nginx configuration, and nginx can't hold a long name in its default server names hash. Their log shows `could not build server_names_hash, you should increase server_names_hash_bucket_size`. OpenLM saw this with a 57-character host name. Use a shorter FQDN, or contact OpenLM Support.

### Why does a web component fail with "Permission denied" on its nginx files?

The component's image writes nginx files, such as `/run/nginx.pid`, to directories that only root can write to. Under a user ID that OpenShift assigns, the component crashes. Contact OpenLM Support for a fixed image.

### Why does sign-in fail with IdentityUnavailable?

The components can't resolve or reach `https://<FQDN>/identity`. Check that the FQDN resolves inside the cluster, and that the components trust the certificate the router serves (see [Certificates on OpenShift](#certificates-on-openshift)).
