# Deploy using Helm


> Deploy F5 NGINX Instance Manager on Kubernetes using the official Helm chart in standard or lightweight mode.


## Overview

You can deploy F5 NGINX Instance Manager on Kubernetes using Helm. This method is quick, scalable, and supports both standard and lightweight modes.

### New in 2.20.0

Starting with version 2.20.0, NGINX Instance Manager supports **lightweight mode**, which skips ClickHouse and disables metrics collection, ideal for simpler setups or resource-limited environments.

- Lightweight mode requires NGINX Agent v2.41.1 or later.

**Note:** 
Starting with version 2.20.0, the Helm chart was renamed from `nginx-stable/nms-hybrid` to `nginx-stable/nim`. Chart versioning was also reset; `v2.0.0` is the first release under the new name. Be sure to update your chart references if you’re using version `2.20.0` or later.

---

## Requirements

To deploy NGINX Instance Manager using a Helm chart, you need:

| Requirements                                 | Notes                                                                                                                                                                                                                  |
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Docker 20.10 or later (linux/amd64)          | [Docker documentation](https://docs.docker.com/get-docker/)                                                                                                                                                            |
| Kubernetes 1.21.3 or later (linux/amd64)     | Ensure your client can [access the Kubernetes API server](https://kubernetes.io/docs/concepts/overview/components/#kube-apiserver). Helm uses the default storage class for persistent volume provisioning.            |
| `kubectl` 1.21.3 or later                    | [kubectl documentation](https://kubernetes.io/docs/reference/kubectl/)                                                                                                                                                 |
| Helm 3.10.0 or later                         | [Helm installation guide](https://helm.sh/docs/intro/install/)                                                                                                                                                         |
| OpenSSL 1.1.1 or later                       | [OpenSSL source](https://www.openssl.org/source/)                                                                                                                                                                      |
| `tar` 1.20 or later                          | The `tar` tool is usually installed by default. Check with `tar --version`.                                                                                                                                            |
| `values.yaml` file with `nmsClickhouse.mode` | Optional. Defaults to `internal`. Set to `external` or `disabled` to use an external ClickHouse instance or enable lightweight mode. In `external` mode, set `nim.externalClickhouse.address` to your ClickHouse host. |
| NGINX subscription JWT                       | Required to authenticate with `private-registry.nginx.com` to pull the image. Download your JWT from [MyF5](https://my.f5.com/manage/s/) under **My Products & Plans > Subscriptions**.                                |

---

## Set up image registry access for NGINX Instance Manager

You can use your NGINX JWT as a Docker configuration secret with Helm charts.

Create a Docker registry secret on the cluster, using the JWT token as the username and `none` as the password. The Docker server is `private-registry.nginx.com`.

**Note:** 
Make sure there are no extra characters or spaces when copying the JWT token. They can invalidate the token and cause 401 errors during authentication.

### Kubernetes

```shell
kubectl create namespace nim
kubectl create secret docker-registry regcred \
  --docker-server=private-registry.nginx.com \
  --docker-username=<NGINX_JWT_TOKEN> \
  --docker-password=none \
  -n nim
```

### OpenShift

```shell
oc new-project nim && \
oc create secret docker-registry regcred \
  --docker-server=private-registry.nginx.com \
  --docker-username=<NGINX_JWT_TOKEN> \
  --docker-password=none \
  -n nim
```

**Note:** 
You might see a warning that `--password` is insecure. In this case, it’s safe to ignore—none is used as a placeholder.

As a best practice, you can delete the JWT token and clear your shell history after deployment if others have access to the system.

### Confirm the secret

- Kubernetes

    ```shell
    kubectl get secret regcred --output=yaml -n nim
    ```

- OpenShift

    ```shell
    oc get secret regcred --output=yaml -n nim
    ```

You can now use this secret for Helm deployments and point the chart to the private registry.

---

## Add the repository {#add-repository}

Run the following commands to add the official NGINX Helm repository and update your local chart list.

```shell
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update
```

---

## Create a values.yaml file {#configure-values-yaml}

Create a file named `values.yaml` using the following example. This file customizes your NGINX Instance Manager deployment with Helm.

The values file lets you:

- Set the deployment mode
- Provide registry credentials
- Specify image sources for each NIM service

Set `nmsClickhouse.mode` to control ClickHouse deployment:

| Mode       | Description                                                                                |
|------------|--------------------------------------------------------------------------------------------|
| `internal` | Deploys ClickHouse in the cluster (default).                                               |
| `external` | Connects to an external ClickHouse instance and requires `nim.externalClickhouse.address`. |
| `disabled` | Disables ClickHouse and enables lightweight mode (no metrics).                             |

**Note:** 
See the [Helm chart configuration settings](
https://docs.nginx.com/nginx-instance-manager/deploy/kubernetes/helm-config-settings/
) guide for a complete list of chart parameters.

```yaml
# When openshift.enabled is set, the chart deploys to OpenShift.
# If it’s unset or left as-is, it defaults to a Kubernetes deployment.
# openshift:
#   enabled: false

nmsClickhouse:
  mode: internal # options: internal, external, disabled

# when mode is external, uncomment and set this:
# externalClickhouse:
#   address: <CLICKHOUSE_HOST>:<PORT>

imagePullSecrets:
  - name: regcred

apigw:
  image:
    repository: private-registry.nginx.com/nms/apigw
core:
  image:
    repository: private-registry.nginx.com/nms/core
dpm:
  image:
    repository: private-registry.nginx.com/nms/dpm
ingestion:
  image:
    repository: private-registry.nginx.com/nms/ingestion
integrations:
  image:
    repository: private-registry.nginx.com/nms/integrations
secmon:
  image:
    repository: private-registry.nginx.com/nms/secmon
utility:
  image:
    repository: private-registry.nginx.com/nms/utility
```

The values required to pull images from the NGINX private registry are now automatically resolved, including image tags. Each image’s `tag:` is set by default to the latest NGINX Instance Manager version. See the [Helm chart table in the chart installation section](/nim/deploy/kubernetes/deploy-using-helm.md#install-the-chart) for version details.

Use the file with the `-f values.yaml` flag when installing the chart.

**Note:** 
OpenShift support is available in NGINX Instance Manager 2.19 and later. To enable it, add `openshift.enabled: true` to your `values.yaml` file. In NGINX Instance Manager 2.22 and later, NGINX Instance Manager supports the default Security Context Constraints (SCC) on OpenShift.
For more details, see [Appendix: OpenShift security constraints](#appendix-openshift-security-constraints).

---

## Install the chart

Install NGINX Instance Manager using Helm. The `adminPasswordHash` sets the default admin password.

```shell
helm install nim nginx-stable/nim \
  -n nim \
  --create-namespace \
  --set adminPasswordHash=$(openssl passwd -6 '<YOUR_PASSWORD>') \
  -f <YOUR_VALUES_FILE> \
  --version <CHART_VERSION> \
  --wait
```

- Replace `<YOUR_PASSWORD>` with your preferred admin password.
- Replace `<YOUR_VALUES_FILE>` with the path to your customized values.yaml file.
- Replace `<CHART_VERSION>` with the version you want to install (for example, `2.1.0`).

**Note:** You can set the ClickHouse mode at install time instead of editing `values.yaml`:

For lightweight mode (no ClickHouse):

```shell
--set nmsClickhouse.mode=disabled
```

For external ClickHouse:

```shell
--set nmsClickhouse.mode=external \
--set nim.externalClickhouse.address=<CLICKHOUSE_HOST>:<PORT>
```

**Validate the deployment**

After installation, run the following command to confirm the deployment was successful:

```shell
helm status nim -n nim
```

You should see `STATUS: deployed` in the output.

To find the right NGINX Instance Manager chart version, see the following table:

| NGINX Instance Manager chart | Chart                      | Instance Manager |
|------------------------------|----------------------------|------------------|
| 2.2.1                        | nginx-stable/nim           | 2.22.1           |
| 2.2.0                        | nginx-stable/nim           | 2.22.0           |
| 2.1.1                        | nginx-stable/nim           | 2.21.1           |
| 2.1.0                        | nginx-stable/nim           | 2.21.0           |
| 2.0.1                        | nginx-stable/nim           | 2.20.1           |
| 2.0.0                        | nginx-stable/nim           | 2.20.0           |
| 2.19.3                       | nginx-stable/nms-hybrid    | 2.19.3           |
| 2.19.2                       | nginx-stable/nms-hybrid    | 2.19.2           |
| 2.19.1                       | nginx-stable/nms-hybrid    | 2.19.1           |
| 2.19.0                       | nginx-stable/nms-hybrid    | 2.19.0           |
| 1.15.1                       | nginx-stable/nms           | 2.18.1           |
| 1.15.0                       | nginx-stable/nms           | 2.18.0           |
| 1.14.4                       | nginx-stable/nms           | 2.17.4           |
| 1.14.0                       | nginx-stable/nms           | 2.17.0           |
| 1.13.0                       | nginx-stable/nms           | 2.16.0           |
| 1.12.1                       | nginx-stable/nms           | 2.15.1           |
| 1.12.0                       | nginx-stable/nms           | 2.15.0           |
| 1.11.0                       | nginx-stable/nms           | 2.14.0           |
| 1.10.1                       | nginx-stable/nms           | 2.13.1           |
| 1.10.0                       | nginx-stable/nms           | 2.13.1           |
| 1.9.0                        | nginx-stable/nms           | 2.13.0           |

---

## Access the web interface

You can access the NGINX Instance Manager web interface using the external IP address for the API Gateway.

1. To look up the external IP address for the API Gateway, run the following command:

   ```shell
   kubectl -n nim get svc apigw
   ```

   This `kubectl` command shows details for the `apigw` service in the `nim` namespace. You’ll see the service type, port, cluster IP, and external IP addresses.

   The default service type is `ClusterIP` and the output looks similar to the following example:

   ```text
   NAME    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
   apigw   ClusterIP   10.108.57.167   <none>        443/TCP   32s
   ```

   Using the `CLUSTER-IP` value, go to `https://<CLUSTER-IP>:443/ui`.

   For example, `https://10.108.57.167/ui`.

   This IP address might not be reachable, depending on how the Kubernetes cluster networking was configured. If so, the `apigw` service type can be changed to a more suitable option, such as `LoadBalancer`, by changing the [Configurable Helm Setting](/nim/deploy/kubernetes/helm-config-settings.md) value for `apigw.service.type`.

---

## Add a license

A valid license is required to use all NGINX Instance Manager features.

For instructions on downloading and applying a license, see [Add a License](/nim/licensing-and-reporting/add-license-connected-deployment.md).

---

### Upgrade NGINX Instance Manager

To upgrade your deployment:

1. [Update the Helm repository list](#add-repository).
2. [Review and adjust your `values.yaml` file](#configure-values-yaml) as needed.
3. Run the following command to upgrade the deployment. This command uses the current chart version from the `nginx-stable/nim` repository and applies the configuration from your `values.yaml` file.

```shell
helm upgrade nim nginx-stable/nim \
  -n nim \
  --set adminPasswordHash=$(openssl passwd -6 '<YOUR_PASSWORD>') \
  -f <PATH_TO_VALUES_FILE> \
  --version <CHART_VERSION> \
  --wait
```

- Replace `<YOUR_PASSWORD>` with your preferred admin password.
- Replace `<YOUR_VALUES_FILE>` with the path to your customized values.yaml file.
- Replace `<CHART_VERSION>` with the version you want to install (for example, `2.1.0`).

**Note:** 
Only the encrypted version of the admin password is stored in Kubernetes. If you lose it, it can’t be recovered or reset.
Make sure to save the password in a secure place.

**Note:** 
If you’re upgrading from a deployment that used the legacy `nms` chart or release name, you’ll need to update the chart reference and adjust the release name as needed.
The latest chart is now called `nginx-stable/nim`, and `nim` is the recommended release name.

---

## Uninstall NGINX Instance Manager {#helm-uninstall-nim}

To uninstall NGINX Instance Manager, run:

```shell
helm uninstall <RELEASE_NAME> -n <NAMESPACE>
```

This command removes the deployment and all Kubernetes resources managed by the Helm chart.

For example, if you used the default release and namespace names:

```shell
helm uninstall nim -n nim
```

---

## Manage network policies

If you plan to use network policies, make sure your Kubernetes cluster has a supported [network plugin](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) installed **before** you install the Helm chart.

By default, the Helm chart creates a set of network policies for NGINX Instance Manager in the deployment namespace.

To view them:

- **Kubernetes**:

    ```shell
    kubectl get netpol -n <NAMESPACE>
    ```

- **OpenShift**:

    ```shell
    oc get netpol -n <NAMESPACE>
    ```

The number and names of network policies vary depending on the deployment mode (standard vs. lightweight). For example, in standard mode, you might see output like this:

```text
NAME         POD-SELECTOR                     AGE
apigw        app.kubernetes.io/name=apigw     2m
core         app.kubernetes.io/name=core      2m
dpm          app.kubernetes.io/name=dpm       2m
ingestion    app.kubernetes.io/name=ingestion 2m
secmon       app.kubernetes.io/name=secmon    2m
```

If you’re using lightweight mode, your output may include fewer entries.

To disable network policies, add the following to your `values.yaml` file:

```yaml
networkPolicies:
  enabled: false
```

---

## Helm deployment for NGINX Instance Manager 2.19

### Create a Helm deployment values.yaml file

The `values.yaml` file customizes the Helm chart installation without changing the chart itself. You can use it to set image repositories, environment variables, resource requests, and other options.

1. Create a `values.yaml` file like this example:

   - In the `imagePullSecrets` section, add your private Docker registry credentials.
   - Set the `tag:` field to the version of NGINX Instance Manager you want to install. You can find supported versions in the Helm chart table.

For details on creating a secret, see the Kubernetes [Pull an Image from a Private Registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) guide.

```yaml
imagePullSecrets:
  - name: regcred

apigw:
  image:
    repository: private-registry.nginx.com/nms/apigw
    tag: <VERSION>
core:
  image:
    repository: private-registry.nginx.com/nms/core
    tag: <VERSION>
dpm:
  image:
    repository: private-registry.nginx.com/nms/dpm
    tag: <VERSION>
ingestion:
  image:
    repository: private-registry.nginx.com/nms/ingestion
    tag: <VERSION>
integrations:
  image:
    repository: private-registry.nginx.com/nms/integrations
    tag: <VERSION>
secmon:
  image:
    repository: private-registry.nginx.com/nms/secmon
    tag: <VERSION>
utility:
  image:
    repository: private-registry.nginx.com/nms/utility
    tag: <VERSION>
```

2. Save and close the `values.yaml` file.

---

### Install the chart

Run the `helm install` command to deploy NGINX Instance Manager:

1. Replace `<PATH_TO_VALUES_FILE>` with the path to your `values.yaml` file.
2. Replace `<YOUR_PASSWORD>` with a secure password (containing a mix of uppercase, lowercase letters, numbers, and special characters).

   **Note:**  Remember to save the password for future use. Only the encrypted password is stored, and there's no way to recover or reset it if lost. 

```shell
helm install -n nms-hybrid \
--set adminPasswordHash=$(openssl passwd -6 '<YOUR_PASSWORD>') \
nms nginx-stable/nms-hybrid \
--create-namespace \
-f <PATH_TO_VALUES_FILE> \
--version <CHART_VERSION> \
--wait
```

---

### Upgrade NGINX Instance Manager

To upgrade:

1. [Update the Helm repository list](#add-repository).
2. [Adjust your `values.yaml` file](#configure-values-yaml) if needed.
3. To upgrade the NGINX Instance Manager deployment, run the following command. This command updates the `nms` deployment with a new version from the `nginx-stable/nms-hybrid` repository. It also hashes the provided password and uses the `values.yaml` file at the path you specify.
4. Replace `<CHART_VERSION>` with the desired chart version of NGINX Instance Manager 2.19.x referring the Helm chart table. 

   ```shell
    helm upgrade -n nms \
    --set nms-hybrid.adminPasswordHash=$(openssl passwd -6 '<YOUR_PASSWORD>') \
    nms nginx-stable/nms-hybrid \
    -f <PATH_TO_VALUES_FILE> \
    --version <CHART_VERSION> \
    --wait
   ```

   - Replace `<PATH_TO_VALUES_FILE>` with the path to the `values.yaml` file you created](/nim/deploy/kubernetes/deploy-using-helm.md#configure-chart).
   - Replace `<YOUR_PASSWORD>` with a secure password that includes uppercase and lowercase letters, numbers, and special characters.

      **Note:**  Save this password for future use. Only the encrypted password is stored in Kubernetes, and you can’t recover or reset it later. 

**Note:** 
If you're upgrading from version 2.18.0 or earlier to 2.19.x, note the following changes:

- If you used the legacy `nms` chart or release name, update the chart reference and adjust the release name if needed.
- The structure of the `values.yaml` file has changed in this release.

---

## Helm Deployment for NGINX Instance Manager 2.18 or lower

### Create a Helm deployment values.yaml file

The `values.yaml` file customizes the Helm chart installation without modifying the chart itself. You can use it to specify image repositories, environment variables, resource requests, and other settings.

1. Create a `values.yaml` file similar to this example:

    - In the `imagePullSecrets` section, add the credentials for your private Docker registry.
    - Change the version tag to the version of NGINX Instance Manager you would like to install. See "Install the chart" below for versions.

    **Note:**  For details on creating a secret, see Kubernetes [Pull an Image from a Private Registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). 

    ```yaml
    nms-hybrid:
        imagePullSecrets:
            - name: regcred
        apigw:
            image:
                repository: private-registry.nginx.com/nms/apigw
                tag: <VERSION>
        core:
            image:
                repository: private-registry.nginx.com/nms/core
                tag: <VERSION>
        dpm:
            image:
                repository: private-registry.nginx.com/nms/dpm
                tag: <VERSION>
        ingestion:
            image:
                repository: private-registry.nginx.com/nms/ingestion
                tag: <VERSION>
        integrations:
            image:
                repository: private-registry.nginx.com/nms/integrations
                tag: <VERSION>
        utility:
            image:
                repository: private-registry.nginx.com/nms/utility
                tag: <VERSION>
    ```

2. Save and close the `values.yaml` file.

---

### Install the chart

Run the `helm install` command to deploy NGINX Instance Manager:

1. Replace `<path-to-your-values.yaml>` with the path to your `values.yaml` file.
2. Replace `YourPassword123#` with a secure password (containing a mix of uppercase, lowercase letters, numbers, and special characters).

   **Note:**  Remember to save the password for future use. Only the encrypted password is stored, and there's no way to recover or reset it if lost. 

3. (Optional) Replace `<CHART_VERSION>` with the desired chart version. If omitted, the latest version will be installed.

```shell
helm install -n nms \
--set nms-hybrid.adminPasswordHash=$(openssl passwd -6 'YourPassword123#') \
nms nginx-stable/nms \
--create-namespace \
-f <PATH_TO_VALUES_FILE> \
--version <CHART_VERSION> \
--wait
```

---

### Upgrade NGINX Instance Manager

To upgrade:

1. [Update the Helm repository list](#add-repository).
2. [Adjust your `values.yaml` file](#configure-values-yaml) if needed.
3. To upgrade the NGINX Instance Manager deployment, run the following command. This command updates the `nms` deployment with a new version from the `nginx-stable/nms` repository. It also hashes the provided password and uses the `values.yaml` file at the path you specify.
4. Replace `<CHART_VERSION>` with the desired chart version 1.15.0 or lower. If omitted, it will lead to an unsuccessful deployment as it will try to upgrade to the latest vesrion 1.16.0 or later.

   ```shell
    helm upgrade -n nms \
    --set nms-hybrid.adminPasswordHash=$(openssl passwd -6 'YourPassword123#') \
    nms nginx-stable/nms \
    -f <PATH_TO_VALUES_FILE> \
    --version <CHART_VERSION> \
    --wait
   ```

   - Replace `<PATH_TO_VALUES_FILE>` with the path to the `values.yaml` file you created](/nim/deploy/kubernetes/deploy-using-helm.md#configure-chart).
   - Replace `YourPassword123#` with a secure password that includes uppercase and lowercase letters, numbers, and special characters.

      **Note:**  Save this password for future use. Only the encrypted password is stored in Kubernetes, and you can’t recover or reset it later. 

---

## Troubleshooting

For instructions on creating a support package to share with NGINX Customer Support, see [Create a Support Package from a Helm Installation](nim/support/k8s-support-package.md).

---

## Appendix: OpenShift security constraints {#appendix-openshift-security-constraints}

OpenShift restricts containers from running as root by default.

To enable OpenShift support in the NGINX Instance Manager Helm chart, set the following value:

```yaml
openshift:
  enabled: true
```

With this setting enabled, NGINX Instance Manager deploys on OpenShift. In NGINX Instance Manager 2.22.0 and later, the chart no longer creates or requires a custom [Security Context Constraints (SCC)](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/authentication_and_authorization/managing-pod-security-policies))). Instead, NGINX Instance Manager runs with the default SCC that OpenShift applies to the NGINX Instance Manager service account. The chart no longer uses fixed UIDs (**1000** for `nms`, and **101** for `nginx` and `clickhouse`).

This deployment has been tested with OpenShift v4.19.0 Server.

---

## Next steps

- [Add NGINX Open Source and NGINX Plus instances to NGINX Instance Manager](nim/nginx-instances/add-instance.md)

