Project: Gravitee.io (Orchestration & Management / API Gateway)
File: README.md

Chart supported versions: 3.0.x and higher Versioning change After version 3.2.0, version of the Helm Chart will be aligned with the product version. eg: If you want to use APIM version 3.x.y you have to use the Chart version 3.x.y If you want to use APIM version 3.x.z you have to use the Chart version 3.x.z Chart and package name changes For the version 4.0.0 and after, the chart folder change from **graviteeio/apim3** to _graviteeio/apim_ For the versions 3.x.y, all the package will be available in **graviteeio/apim3** and _graviteeio/apim_ with a different name eg: Version 3.20.x will be published in graviteeio/apim3 with the name apim3-3.20.x AND in graviteeio/apim with the name apim-3.20.x **graviteeio/apim3** is now depreciated. This chart will deploy the following: Gravitee Management API Gravitee Management UI Gravitee Portal UI Gravitee Gateway MongoDB replica-set (optional dependency) Elasticsearch cluster (optional dependency) Add the Gravitee.io helm charts repo ``` $ helm repo add graviteeio https://helm.gravitee.io ``` Install it ``` $ helm install --name graviteeio-apimx graviteeio/apim ``` Please, before upgrading to a new chart version, always check . This one is about latest version (master), but you can switch to another maintained branch version in github to view the one dedicated to your version. Also, product or helm change with potential breaking changes are listed in the documentation page. To package this chart directory into a chart archive, run: ``` $ helm package . ``` To install the chart from the Helm repository with the release name `graviteeio-apimx`: ```bash $ helm install --name graviteeio-apimx graviteeio/apim ``` Note: If you're using Helm 3, the name parameter is no more valid. Please check https://helm.sh/docs/faq/#release-names-are-now-scoped-to-the-namespace To install the chart using the chart archive, run: ``` $ helm install apim-3.0.0.tgz ``` The following tables list the configurable parameters of the Gravitee chart and their default values. You can rely on kubernetes ConfigMaps and Secrets to initialize Gravitee settings since APIM 3.15.0. To use this feature, you have to create the ServiceAccount that allows APIM to connect to the Kubernetes API (the helm chart should do it by default) and then you simply have to define your application settings like this: for a Secret : `kubernetes://<namespace>/secrets/<my-secret-name>/<my-secret-key>` for a ConfigMap : `kubernetes://<namespace>/configmaps/<my-configmap-name>/<my-configmap-key>` Here is an example for the mongodb uri initialized from the `mongo` secret deployed in the `default` namespace: ```yaml mongo: uri: kubernetes://default/secrets/mongo/mongouri ``` If you need to access a secret, you have to create a role within your namespace. If you are deploying in another namespace and you need to access a secret there, you have to create a separate role in that namespace. The two roles can have the same name, but they are completely separate objects - each role only gives access to the namespace it is created in. For more information about roles, see in the . To configure common features such as: chaos testing (see chart) configuration database (see chart) logs database (see chart) | Parameter | Description | Default | | - | | - | | `chaos.enabled` | Enable Chaos test | false | | `inMemoryAuth.enabled` | Enable oauth login | true | | `ldap.enabled` | Enable LDAP login | false | There are three ways to configure MongoDB

The most simple is to provide the . | Parameter | Description | Default | | | | -- | | `mongo.uri` | Mongo URI | `null` | If no `mongo.uri` is provided, you can provide a `mongo.servers` raw definition in combination with `mongo.dbname`, plus eventual authentication configuration: ```yaml mongo: servers: | host: mongo1 port: 27017 host: mongo2 port: 27017 dbname: gravitee auth: enabled: false username: password: ``` If neither `mongo.uri` or `mongo.servers` are provided, you have to define the following configuration options: | Parameter | Description | Default | | | | -- | | `mongo.rsEnabled` | Whether Mongo replicaset is enabled or not | `true` | | `mongo.rs` | Mongo replicaset name | `rs0` | | `mongo.dbhost` | Mongo host address | `mongo-mongodb-replicaset` | | `mongo.dbport` | Mongo host port | `27017` | | `mongo.dbname` | Mongo DB name | `gravitee` | | `mongo.auth.enabled` | Enable Mongo DB authentication | `false` | | `mongo.auth.username` | Mongo DB username | `null` | | `mongo.auth.password` | Mongo DB password | `null` | | Parameter | Description | Default | | -- | -- | - | | `mongo.sslEnabled` | Enable SSL connection to MongoDB | `false` | | `mongo.socketKeepAlive` | Enable keep alive for socket | `false` | | Parameter | Description | Default | | - | - | - | | `mongodb-replicaset.enabled` | Enable deployment of Mongo replicaset | `false` | See for detailed documentation on helm chart. Please be aware that the mongodb-replicaset installed by Gravitee is NOT recommended in production and it is just for testing purpose and running APIM locally. | Parameter | Description | Default | |||| | `es.security.enabled` | Elasticsearch username and password enabled | false | | `es.security.username` | Elasticsearch username | `example` | | `es.security.password` | Elasticsearch password | `example` | | `es.tls.enabled` | Elasticsearch TLS enabled | false | | `es.tls.keystore.type` | Elasticsearch TLS keystore type (jks, pem or pfx) | `null` | | `es.tls.keystore.path` | Elasticsearch TLS keystore path (jks, pfx) | `null` | | `es.tls.keystore.password` | Elasticsearch TLS keystore password (jks, pfx) | `null` | | `es.tls.keystore.certs` | Elasticsearch TLS certs (only pems) | `null` | | `es.tls.keystore.keys` | Elasticsearch TLS keys (only pems) | `null` | | `es.index` | Elasticsearch index | `gravitee` | | `es.endpoints` | Elasticsearch endpoint array | `[http://graviteeio-apim-elasticsearch.default.svc.cluster.local:9200]` | | `es.pipeline.plugins.ingest` | Elasticsearch pipeline ingest plugins | `geoip, user_agent` | | Parameter | Description | Default | | -- | | - | | `elasticsearch.enabled` | Enable deployment of Elasticsearch cluster | `false` | See for detailed documentation on optional requirements helm chart. Please be aware that the Elasticsearch installed by Gravitee is NOT recommended in production and it is just for testing purpose and running APIM locally. | Parameter | Description | Default | | -- | | - | | `ui.name` | UI service name | `ui` | | `ui.baseURL` | Base URL to access to the Management API (if set to `null`, defaults to Management API ingress value) | `[apim.example.com]/management` | | `ui.title` | UI Portal title (if set to `null`, retrieved from the management repository) | `API Portal` | |

| UI Management title (if set to `null`, retrieved from the management repository) | `API Management` | | `ui.documentationLink` | UI link to documentation (if set to `null`, retrieved from the management repository) | `https://documentation.gravitee.io/` | | `ui.portal.apikeyHeader` | API Key header name (if set to `null`, retrieved from the management repository) | `X-Gravitee-Api-Key` | | `ui.portal.devMode.enabled` | Whether to enable developer mode (if set to `null`, retrieved from the management repository) | `false` | | `ui.portal.userCreation.enabled` | Whether to enable user creation (if set to `null`, retrieved from the management repository) | `false` | | `ui.portal.support.enabled` | Whether to enable support features (if set to `null`, retrieved from the management repository) | `true` | | `ui.portal.rating.enabled` | Whether to enable API rating (if set to `null`, retrieved from the management repository) | `false` | | `ui.portal.analytics.enabled` | Whether to enable analytics features (if set to `null`, retrieved from the management repository) | `false` | | `ui.portal.analytics.trackingId` | Tracking ID used for analytics (if set to `null`, retrieved from the management repository) | `""` | | `ui.replicaCount` | How many replicas of the UI pod | `1` | | `ui.image.repository` | Gravitee UI image repository | `graviteeio/management-ui` | | `ui.image.tag` | Gravitee UI image tag | `1.29.5` | | `ui.image.pullPolicy` | K8s image pull policy | `Always` | | `ui.image.pullSecrets` | K8s image pull secrets, used to pull both Gravitee UI image and `extraInitContainers` | `null` | | `ui.autoscaling.enabled` | Whether auto-scaling is enabled or not | `true` | | `ui.autoscaling.minReplicas` | If `ui.autoscaling.enabled` is `true`, what's the minimum number of replicas | `2` | | `ui.autoscaling.maxReplicas` | If `ui.autoscaling.enabled` is `true`, what's the maximum number of replicas | `3` | | `ui.autoscaling.targetAverageUtilization` | If `ui.autoscaling.enabled` what's the average target utilization (in %) before it auto-scale | `50` | | `ui.service.name` | UI service name | `nginx` | | `ui.service.type` | K8s publishing | `ClusterIP` | | `ui.service.externalPort` | K8s UI service external port | `8082` | | `ui.service.internalPort` | K8s UI service internal port (container) | `80` | | `ui.service.internalPortName` | K8s UI service internal port name (container) | `http` | | `ui.ingress.enabled` | Whether Ingress is enabled or not | `true` | | `ui.ingress.hosts` | If `ui.ingress.enabled` is enabled, set possible ingress hosts | `[apim.example.com]` | | `ui.ingress.annotations` | Supported Ingress annotations to configure ingress controller | `[kubernetes.io/ingress.class: nginx, kubernetes.io/app-root: /management, kubernetes.io/rewrite-target: /management, ingress.kubernetes.io/configuration-snippet: "etag on;\nproxypassheader ETag;\n"]` | | `ui.ingress.tls.hosts` | | `[apim.example.com]` | | `ui.ingress.tls.secretName` | Ingress TLS K8s secret name containing the TLS private key and certificate | `api-custom-cert` | | `ui.resources.limits.cpu` | K8s pod deployment | `100m` | | `ui.resources.limits.memory` | K8s pod deployment limits definition for memory | `128Mi` | | `ui.resources.requests.cpu` | K8s pod deployment | `50m` | | `ui.resources.requests.memory` | K8s pod deployment requests definition for memory | `64Mi` | | `ui.lifecycle.postStart` | K8s pod deployment command definition | `null` | | `ui.lifecycle.preStop` | K8s pod deployment command definition | `null` | | Parameter | Description | Default | |-| -- |-| | `api.name` | API service name | `api` | | `api.logging.debug` | Whether to enable API debug logging or not | `false` | | `api.logging.graviteeLevel` | Logging level for Gravitee classes | `DEBUG` | | `api.logging.jettyLevel` | Logging level for Jetty classes | `INFO` | |

| Logback standard output encoder pattern | `%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n` | | `api.logging.file.enabled` | Whether to enable file logging or not | `true` | | `api.logging.file.rollingPolicy` | Logback file rolling policy configuration | `TimeBasedRollingPolicy` for 30 days | | `api.logging.file.encoderPattern` | Logback file encoder pattern | `%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n` | | `api.logging.additionalLoggers` | List of additional logback loggers. Each logger is defined by a `name` and `level` (TRACE, DEBUG, INFO, WARN, or ERROR) | `empty` | | `api.ssl.enabled` | API exposition through HTTPS protocol activation | `false` | | `api.ssl.keystore.type` | Keystore type for API exposition through HTTPS protocol | `jks` | | `api.ssl.keystore.path` | Keystore path for API exposition through HTTPS protocol | `null` | | `api.ssl.keystore.password` | Keystore password for API exposition through HTTPS protocol | `null` | | `api.ssl.truststore.type` | Truststore type for client authentication through 2 way TLS | `jks` | | `api.ssl.truststore.path` | Truststore path for client authentication through 2 way TLS | `null` | | `api.ssl.truststore.password` | Truststore password for client authentication through 2 way TLS | `null` | | `api.http.services.core.http.authentication.password` | HTTP core service authentication password | `adminadmin` | | `api.http.services.core.http.port` | HTTP core service port exposed in container | `18083` | | `api.http.services.core.http.host` | HTTP core service bind IP or host inside container (0.0.0.0 for exposure on every interfaces) | `localhost` | | `api.http.services.core.http.authentication.password` | HTTP core service authentication password | `adminadmin` | | `api.http.services.core.http.ingress.enabled` | Ingress for HTTP core service authentication (requires `api.http.services.core.service.enabled` to be true) | `false` | | `api.http.services.core.http.ingress.path` | The ingress path which should match for incoming requests to the management technical API. | `/management/_(.*)` | | `api.http.services.core.http.ingress.hosts` | If `api.ingress.enabled` is enabled, set possible ingress hosts | `[apim.example.com]` | | `api.http.services.core.http.ingress.annotations` | Supported Ingress annotations to configure ingress controller | `[kubernetes.io/ingress.class: nginx, nginx.ingress.kubernetes.io/rewrite-target: /_$1]` | | `api.http.services.core.http.ingress.tls.hosts` | | `[apim.example.com]` | | `api.http.services.core.http.ingress.tls.secretName` | Ingress TLS K8s secret name containing the TLS private key and certificate | `api-custom-cert` | | `api.http.services.core.http.service.enabled` | Whether a service is added or not for technical API | `false` | | `api.http.services.core.http.service.externalPort` | K8s service external port (internal port is defined by `api.http.services.core.http.port` ) | `18083` | | `api.http.api.entrypoint` | Listening path for the API | `/management` | | `api.http.client.timeout` | HTTP client global timeout | `10000` | | `api.http.client.proxy.type` | HTTP client proxy type | `HTTP` | | `api.http.client.proxy.http.host` | HTTP client proxy host for HTTP protocol | `localhost` | | `api.http.client.proxy.http.port` | HTTP client proxy port for HTTP protocol | `3128` | | `api.http.client.proxy.http.username` | HTTP client proxy username for HTTP protocol | `null` | | `api.http.client.proxy.http.password` | HTTP client proxy password for HTTP protocol | `null` | | `api.http.client.proxy.https.host` | HTTP client proxy host for HTTPS protocol | `localhost` | | `api.http.client.proxy.https.port` | HTTP client proxy port for HTTPS protocol | `3128` | | `api.http.client.proxy.https.username` | HTTP client proxy username for HTTPS protocol | `null` | | `api.http.client.proxy.https.password` | HTTP client proxy password for HTTPS protocol | `null` | | `api.user.login.defaultApplication` | Whether to enable default application creation on first user authentication | `true` | | `api.user.anonymizeOnDelete` | Whether to enable user anonymization on deletion | `false` | |

| Whether to enable support feature | `true` | | `api.ratingEnabled` | Whether to enable API rating feature | `true` | | `api.newsletterEnabled` | Whether to enable newsletter sign up feature | `true` | | `smtp.enabled` | Email sending activation | `true` | | `smtp.host` | SMTP server host | `smtp.example.com` | | `smtp.port` | SMTP server port | `25` | | `smtp.from` | Email sending address | `info@example.com` | | `smtp.username` | SMTP server username | `info@example.com` | | `smtp.password` | SMTP server password | `example.com` | | `smtp.subject` | Email subjects template | `[gravitee] %s` | | `smtp.auth` | SMTP server authentication activation | `true` | | `smtp.starttlsEnable` | SMTP server TLS activation | `false` | | `smtp.localhost` | Hostname that is resolvable by the SMTP server | `null` | | `api.portalURL` | The portal URL used in emails | `https://{{ index .Values.ui.ingress.hosts 0 }}` | | `api.restartPolicy` | Policy to | `OnFailure` | | `api.updateStrategy.type` | | `RollingUpdate` | | `api.updateStrategy.rollingUpdate.maxUnavailable` | If api.updateStrategy.type is set to `RollingUpdate`, make sure to set a value here or your Deployment can have 100% unavailability by default. The Deployment controller will stop the bad rollout automatically, and will stop scaling up the new ReplicaSet. This depends on the rollingUpdate parameters (maxUnavailable specifically) that you have specified. Kubernetes by default sets the value to 1 and spec.replicas to 1 so if you havent cared about setting those parameters, your Deployment can have 100% unavailability by default! | `1` | | `api.replicaCount` | How many replicas for the API pod | `1` | | `api.image.repository` | Gravitee API image repository | `graviteeio/management-api` | | `api.image.tag` | Gravitee API image tag | `1.29.5` | | `api.image.pullPolicy` | K8s image pull policy | `Always` | | `api.image.pullSecrets` | K8s image pull secrets, used to pull both Gravitee Management API image and `extraInitContainers` | `null` | | `api.env` | Environment variables, defined as a list of `name` and `value` as specified in | `null` | | `api.service.type` | K8s publishing | `ClusterIP` | | `api.service.externalPort` | K8s service external port | `83` | | `api.service.internalPort` | K8s service internal port (container) | `8083` | | `api.service.internalPortName` | K8s service internal port name (container) | `http` | | `api.autoscaling.enabled` | Whether auto-scaling is enabled or not | `true` | | `api.autoscaling.minReplicas` | If `api.autoscaling.enabled` is `true`, what's the minimum number of replicas | `2` | | `api.autoscaling.maxReplicas` | If `api.autoscaling.enabled` is `true`, what's the maximum number of replicas | `3` | | `api.autoscaling.targetAverageUtilization` | If `api.autoscaling.enabled` what's the average target utilization (in %) before it auto-scale | `50` | | `api.ingress.enabled` | Whether Ingress is enabled or not | `true` | | `api.ingress.path` | The ingress path which should match for incoming requests to the management API. | `/management` | | `api.ingress.hosts` | If `api.ingress.enabled` is enabled, set possible ingress hosts | `[apim.example.com]` | | `api.ingress.annotations` | Supported Ingress annotations to configure ingress controller | `[kubernetes.io/ingress.class: nginx, ingress.kubernetes.io/configuration-snippet: "etag on;\nproxypassheader ETag;\nproxysetheader if-match \"\";\n"]` | | `api.ingress.tls.hosts` | | `[apim.example.com]` | | `api.ingress.tls.secretName` | Ingress TLS K8s secret name containing the TLS private key and certificate | `api-custom-cert` | | `api.resources.limits.cpu` | K8s pod deployment | `500m` | |

| K8s pod deployment limits definition for memory | `1024Mi` | | `api.resources.requests.cpu` | K8s pod deployment | `200m` | | `api.resources.requests.memory` | K8s pod deployment requests definition for memory | `512Mi` | | `api.lifecycle.postStart` | K8s pod deployment command definition | `null` | | `api.lifecycle.preStop` | K8s pod deployment command definition | `null` | | Parameter | Description | Default | |--| - | | | `gateway.name` | Gateway service name | `gateway` | | `gateway.logging.debug` | Whether to enable Gateway debug logging or not | `false` | | `gateway.ssl.enabled` | API exposition through HTTPS protocol activation | `false` | | `gateway.ssl.keystore.type` | Keystore type for API exposition through HTTPS protocol | `jks` | | `gateway.ssl.keystore.path` | Keystore path for API exposition through HTTPS protocol | `null` | | `gateway.ssl.keystore.password` | Keystore password for API exposition through HTTPS protocol | `null` | | `gateway.ssl.clientAuth` | Client authentication through 2 way TLS activation | `false` | | `gateway.ssl.truststore.type` | Truststore type for client authentication through 2 way TLS | `jks` | | `gateway.ssl.truststore.path` | Truststore path for client authentication through 2 way TLS | `null` | | `gateway.ssl.truststore.password` | Truststore password for client authentication through 2 way TLS | `null` | | `gateway.logging.graviteeLevel` | Logging level for Gravitee classes | `DEBUG` | | `gateway.logging.jettyLevel` | Logging level for Jetty classes | `INFO` | | `gateway.logging.stdout.encoderPattern` | Logback standard output encoder pattern | `%d{HH:mm:ss.SSS} [%thread] [%X{api}] %-5level %logger{36} - %msg%n` | | `gateway.logging.file.enabled` | Whether to enable file logging or not | `true` | | `gateway.logging.file.rollingPolicy` | Logback file rolling policy configuration | `TimeBasedRollingPolicy` for 30 days | | `gateway.logging.file.encoderPattern` | Logback file encoder pattern | `%d{HH:mm:ss.SSS} [%thread] [%X{api}] %-5level %logger{36} - %msg%n` | | `gateway.logging.additionalLoggers` | List of additional logback loggers. Each logger is defined by a `name` and `level` (TRACE, DEBUG, INFO, WARN, or ERROR) | `empty` | | `gateway.type` | Gateway deployment type: `deployment` or `statefulSet` | `deployment` | | `gateway.replicaCount` | How many replicas of the Gateway pod | `2` | | `gateway.image.repository` | Gravitee Gateway image repository | `graviteeio/gateway` | | `gateway.image.tag` | Gravitee Gateway image tag | `1.29.5` | | `gateway.image.pullPolicy` | K8s image pull policy | `Always` | | `gateway.image.pullSecrets` | K8s image pull secrets, used to pull both Gravitee Gateway image and `extraInitContainers` | `null` | | `gateway.env` | Environment variables, defined as a list of `name` and `value` as specified in | `null` | | `gateway.service.type` | K8s publishing | `ClusterIP` | | `gateway.service.externalPort` | K8s Gateway service external port | `82` | | `gateway.service.internalPort` | K8s Gateway service internal port (container) | `8082` | | `gateway.service.internalPortName` | K8s Gateway service internal port name (container) | `http` | | `gateway.autoscaling.enabled` | Whether auto-scaling is enabled or not | `true` | | `gateway.autoscaling.minReplicas` | If `gateway.autoscaling.enabled` is `true`, what's the minimum number of replicas | `2` | | `gateway.autoscaling.maxReplicas` | If `gateway.autoscaling.enabled` is `true`, what's the maximum number of replicas | `3` | | `gateway.autoscaling.targetAverageUtilization` | If `gateway.autoscaling.enabled` what's the average target utilization (in %) before it auto-scale | `50` | | `gateway.websocket` | Whether websocket protocol is enabled or not | `false` | | `gateway.apiKey.header` | Header used for the API Key. Set an empty value to prohibit its

| `X-Gravitee-Api-Key` | | `gateway.apiKey.param` | Query parameter used for the API Key. Set an empty value to prohibit its use. | `api-key` | | `gateway.sharding_tags` | Sharding tags (comma separated list) | `` | | `gateway.ingress.enabled` | Whether Ingress is enabled or not | `true` | | `gateway.ingress.path` | The ingress path which should match for incoming requests to the gateway. | `/gateway` | | `gateway.ingress.hosts` | If `gateway.ingress.enabled` is enabled, set possible ingress hosts | `[apim.example.com]` | | `gateway.ingress.annotations` | Supported Ingress annotations to configure ingress controller | `[kubernetes.io/ingress.class: nginx, nginx.ingress.kubernetes.io/ssl-redirect: "false", nginx.ingress.kubernetes.io/enable-rewrite-log: "true", kubernetes.io/app-root: /gateway, kubernetes.io/rewrite-target: /gateway]` | | `gateway.ingress.tls.hosts` | | `[apim.example.com]` | | `gateway.ingress.tls.secretName` | Ingress TLS K8s secret name containing the TLS private key and certificate | `api-custom-cert` | | `gateway.resources.limits.cpu` | K8s pod deployment | `500m` | | `gateway.resources.limits.memory` | K8s pod deployment limits definition for memory | `512Mi` | | `gateway.resources.requests.cpu` | K8s pod deployment | `200m` | | `gateway.resources.requests.memory` | K8s pod deployment requests definition for memory | `256Mi` | | `gateway.lifecycle.postStart` | K8s pod deployment command definition | `null` | | `gateway.lifecycle.preStop` | K8s pod deployment command definition | `null` | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, ```bash $ helm install --name my-release -f values.yaml gravitee ``` Tip: You can use the default The Gravitee.io API Management Helm Chart supports OpenShift > 3.10 This chart is only supporting Ingress standard objects and not the specific OpenShift Routes, reason why OpenShift is supported started from 3.10. There are two major considerations to have in mind when deploying Gravitee.io API Management within OpenShift: 1_ Use full host domain instead of paths for all the components (ingress paths are not well supported by OpenShift) 2_ Override the security context to let OpenShift to define automatically the user-id and the group-id to run the containers. Also, for Openshift to automatically create Routes from Ingress, you must define the ingressClassName to "none". Here is a standard values.yaml used to deploy Gravitee.io APIM into OpenShift: ```yaml api: ingress: management: ingressClassName: none path: /management hosts: api-graviteeio.apps.openshift-test.l8e4.p1.openshiftapps.com annotations: route.openshift.io/termination: edge portal: ingressClassName: none path: /portal hosts: api-graviteeio.apps.openshift-test.l8e4.p1.openshiftapps.com annotations: route.openshift.io/termination: edge securityContext: null deployment: securityContext: runAsUser: null runAsGroup: null runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: ["ALL"] seccompProfile: type: RuntimeDefault gateway: ingress: ingressClassName: none path: / hosts: gw-graviteeio.apps.openshift-test.l8e4.p1.openshiftapps.com annotations: route.openshift.io/termination: edge securityContext: null deployment: securityContext: runAsUser: null runAsGroup: null runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: ["ALL"] seccompProfile: type: RuntimeDefault portal: ingress: ingressClassName: none path: / hosts: portal-graviteeio.apps.openshift-test.l8e4.p1.openshiftapps.com annotations: route.openshift.io/termination: edge securityContext: null deployment: securityContext: runAsUser: null runAsGroup: null runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: ["ALL"] seccompProfile: type: RuntimeDefault ui: ingress: ingressClassName: none path: / hosts: console-graviteeio.apps.openshift-test.l8e4.p1.openshiftapps.com annotations: route.openshift.io/termination: edge securityContext: null deployment: securityContext: runAsUser: null runAsGroup: null runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: ["ALL"] seccompProfile: type: RuntimeDefault ``` By setting the value to `null` for `runAsUser` and `runAsGroup` it forces OpenShift to define the correct values for you while deploying the Helm Chart. Install `unittest` helm plugin ```shell helm plugin install https://github.com/quintush/helm-unittest --version 0.2.11 ``` Update dependencies ```shell helm dependency update ``` Inside `helm/` directory, run: ```shell helm unittest -3 -f 'tests//*_test.yaml' . ```