# Install Self-Hosted on-premises

On-premises environments remain vital for many organizations. Through its Kubernetes-native architecture, UltiHash supports easy scaling and load balancing, ensuring that systems can handle fluctuating workloads with minimal reconfiguration. This design ensures that on-premises deployments remain flexible and customizable, allowing businesses to maintain control over their infrastructure.

This guide provides a detailed walkthrough for setting up an UltiHash cluster in a Kubernetes environment, whether on-premises or in a cloud environment. The process is divided into four main steps:

1. **Prerequisites**: Gather the necessary credentials, tools, and environment configurations.
2. **Cluster setup**: Configure your Kubernetes cluster, including creating namespaces and provisioning secrets.
3. **Helm installation**: Deploy UltiHash using Helm, customizing the setup for your specific environment.
4. **Post-installation**: Verify the installation.

<details>

<summary>System hardware requirements</summary>

* **Storage:** NVMe SSDs are required for optimal disk performance.
* **Network:** 10 Gbps interface minimum between nodes.
* **Kubernetes:** Version 1.20+ with Nginx Ingress and a CSI Controller installed.
* **Containerization:** Docker 19.03+ or Containerd 1.3+.
* **Helm:** Version 3.x.
* **On-Premises:** Minimum of 1 Kubernetes node with NVMe SSDs.

Resource needs will vary depending on the amount of data being stored and managed. For best performance, especially with larger datasets, it’s essential to provision additional resources accordingly.

</details>

## Step 1: Prerequisites

Before you begin the installation, ensure you have the following:

* **Skills:** good knowledge of Kubernetes, kubectl, and helm.
* **UltiHash Account**: Sign up at [ultihash.io/signup](https://ultihash.io/signup) and verify your email.
* **Credentials**: After signing up on the UltiHash website, you will get the following credentials on [your dashboard](https://www.ultihash.io/user/dashboard):
  * **Registry login and password** (referred to as `registry_login` and `registry_password`).
  * **Customer ID** (referred to as `customer_id`).
  * **Access token** (referred to as `access_token`).
  * **Monitoring token** (referred to as `monitoring_token`).
* **Kubernetes cluster**:
  * **Version**: Ensure you have a Kubernetes cluster running version 1.20 or higher.
  * **Controllers**:
    * **Ingress controller**: Exposes the UltiHash cluster API endpoint outside the Kubernetes cluster.
    * **CSI controller**: Manages persistent volumes.
  * Note: You can use any Kubernetes version starting from 1.20, and any CSI controller that dynamically provisions and attaches persistent volumes. For optimal performance, use a CSI controller that imposes the least disk performance degradation.
* **Local environment**:
  * **kubectl**: Ensure Kubernetes command line tool `kubectl` is installed and configured to access the cluster.
  * **Helm**: Install Kubernetes package manager Helm (version 3.x) to manage Kubernetes packages.

## Step 2: Cluster setup

1. **Namespace creation**:
   * Create a Kubernetes namespace for the UltiHash installation:

     ```bash
     kubectl create ns <namespace>

     ```
   * Replace `<namespace>` with your desired namespace name.
2. **Secrets provisioning**:
   * **Registry credentials**: Provision a secret in Kubernetes to store the UltiHash registry credentials:

     ```bash
     kubectl create secret docker-registry registry-credentials -n <namespace> --docker-server='registry.ultihash.io' --docker-username='<registry_login>' --docker-password='<registry_password>'

     ```
   * Replace `<namespace>` with the namespace name. Replace `<registry_login>`, and `<registry_password>` with the appropriate values obtained from your [dashboard](https://www.ultihash.io/user/dashboard) on the UltiHash website.
   * **Ultihash credentials and monitoring token**: Create a secret in Kubernetes for the license key and monitoring token:

     ```bash
     kubectl create secret generic ultihash -n <namespace> --from-literal=customer_id='<customer_id>' --from-literal=access_token='<access_token>' --from-literal=token='<monitoring_token>'

     ```
   * Replace `<namespace>` with the namespace name. Replace `<customer_id>,<access_token>,` and `<monitoring_token>` with the corresponding values found on your [UltiHash dashboard](https://www.ultihash.io/user/dashboard).

## Step 3: Helm installation

1. **Helm chart deployment**:
   * Log into the UltiHash registry with your `registry_login` and `registry_password` :

     ```bash
     helm registry login registry.ultihash.io
     ```
   * Deploy the Helm chart with a specific release name and namespace:

     ```bash
     helm install <release_name> oci://registry.ultihash.io/stable/ultihash-cluster -n <namespace> --values values.yaml --wait

     ```
   * Replace `<release_name>` and `namespace` with your chosen names. `values.yaml` should be configured as described below.
2. **Component configuration**:
   * Customize the `values.yaml` file with the necessary configurations:
     * **Storage class**: Specify the storage class name created by your CSI controller.
     * **Domain name**: Enter a valid domain name for your UltiHash cluster.
     * **Service replicas and storage size**: Adjust the number of replicas and storage size for services like `etcd`, `entrypoint`, `storage`, and `deduplicator` based on your requirements.

       ```yaml
       global:                           
         logLevel: INFO                  # Default log level for all UltiHash services. Valid values are DEBUG, INFO, WARN, ERROR, or FATAL
         telemetryExportInterval: 30000  # Export interval for UltiHash services telemetry (in milliseconds). Could be overriden individually for each UltiHash service

       etcd:
         replicaCount: <number_of_replicas>
         persistence:
           storageClass: <storage_class>

       database:
         primary:
           persistence:
             storageClass: <storage_class>
             size: <storage_size>

       entrypoint:
         replicas: <number_of_replicas>
         ingress:
           host: <domain_name>  # FQDN to expose the entrypoint outside the cluster

       storage:
         groups:
           - id: 0
             type: ROUND_ROBIN
             storages: 1
             storageClass: <storage_class>
             size: <storage_size>

       deduplicator:
         replicas: <number_of_replicas>
         storageClass: <storage_class>
         storageSize: <storage_size>

       exporter:
         enabled: true

       ```

## Step 4: Post-installation

1. **Verification**:
   * After deployment, verify that all services are running correctly by checking the Kubernetes namespace:

     ```bash
     kubectl get all -n <namespace>
     ```

     Replace `<namespace>` with the namespace where UltiHash cluster has been deployed.
   * Ensure that all pods are either in the `Running` or in the `Completed` state with no errors.
2. **Get access to the UltiHash cluster**:
   * Obtain the UltiHash root user credentials:

     ```bash
     # Obtain credentials for the UltiHash root user
     aws_access_key_id=`kubectl get secret <release_name>-super-user-credentials -n <namespace> -o jsonpath="{.data.access-key-id}" | base64 --decode`
     aws_secret_access_key=`kubectl get secret <release_name>-super-user-credentials -n <namespace> -o jsonpath="{.data.secret-key}" | base64 --decode`

     # Set the credentials for the UltiHash root user
     export AWS_ACCESS_KEY_ID=$aws_access_key_id
     export AWS_SECRET_ACCESS_KEY=$aws_secret_access_key
     ```
   * Replace `<release_name>` and `<namespace>` with the Helm release name and namespace name correspondingly.
   * Use AWS CLI and AWS SDK to interact with the UltiHash cluster:

     ```bash
     aws s3api list-buckets --endpoint-url <cluster-url>
     ```
   * Replace `<cluster-url>` with the appropriate scheme: either `https://<domain_name>` or `http://<domain_name>`, depending on whether your `entrypoint.ingress` object in the Helm values has been configured with or without TLS. The `<domain_name>` corresponds to the domain name chosen for the UltiHash cluster, as set in the `entrypoint.ingress.host` object.

***

### Frequent issues troubleshooting

<details>

<summary>Helm chart install or upgrade failure</summary>

**Symptoms:**

* `helm install` or `helm upgrade` hangs or returns an error
* Application pods do not start
* Helm status is stuck at `pending-install` or `failed`

**Steps to resolve:**

* **Inspect the Helm release status:**

  ```bash
  helm status <release_name> -n <namespace>
  ```
* **Check for resource creation errors or pending pods:**

  ```bash
  kubectl get pods -n <namespace>
  ```
* **Describe a failing pod to view events and errors:**

  ```bash
  kubectl describe pod <pod_name> -n <namespace>
  ```
* **Debug with Helm’s dry run mode:**

  ```bash
  helm upgrade <release_name> oci://registry.ultihash.io/stable/ultihash-cluster \
    -n <namespace> --dry-run --values values.yaml --debug
  ```
* After the issue has been found and eliminated, process with install or upgrade further.

**Recommendation:** Always use `--dry-run` and `--debug` to validate changes before applying them in production.

</details>

<details>

<summary>Missing or incorrect values in values.yaml</summary>

**Symptoms:**

* Helm fails with a rendering error
* Application fails at runtime due to missing config (e.g., secrets, ports, env vars)

**Steps to resolve:**

* **Compare your values file with the chart defaults:**

  ```
  helm show values oci://registry.ultihash.io/stable/ultihash-cluster
  ```
* **Test the rendered templates locally:**

  ```
  helm template <your_release_name> oci://registry.ultihash.io/stable/ultihash-cluster --values <your_values.yaml>
  ```
* **Reapply the corrected configuration:**

  ```
  helm upgrade <release_name> oci://registry.ultihash.io/stable/ultihash-cluster \
    -n <namespace> --values <your_values.yaml>
  ```

**Recommendation:** Use a version-controlled values file and validate changes in a staging environment before rolling out to production.

#### 3. Application pods stuck in `CrashLoopBackOff` or `ImagePullBackOff`

**Purpose:** Diagnose runtime pod failures due to misconfiguration or image issues.

**Symptoms:**

* Pods keep restarting or cannot pull the container image

**Steps to resolve:**

* **Inspect the pod state:**

  ```
  kubectl get pods -n <namespace>
  ```
* **Check the logs of the failing pod:**

  ```
  kubectl logs <pod_name> -n <namespace>
  ```
* **Correct the config causing failure, then upgrade:**

  ```
  helm upgrade <release_name> oci://registry.ultihash.io/stable/ultihash-cluster \
    -n <namespace> --values <your_values.yaml>
  ```

**Recommendation:** Ensure that image repositories are accessible and secrets for private registries are correctly configured in the cluster.

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ultihash.io/installation/install-self-hosted-on-premises.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
