# Self-hosting

See [Architecture](https://github.com/root-signals/gitbook-docs/blob/main/architecture.md) for more details on the Scorable system architecture.

## Scorable Installation Guide

This document provides step-by-step instructions to deploy Scorable using Helm on your Kubernetes cluster.

{% hint style="info" %}
Self-hosting is available on the Scale plan. Contact Scorable at <hello@scorable.ai>
{% endhint %}

***

### Prerequisites

Before you begin, ensure the following components are installed and configured in your environment.

#### Required Components

* **Kubernetes Cluster**: A running Kubernetes cluster (v1.32 or higher recommended).
* **Helm 3/4**: Ensure you have [Helm](https://helm.sh/docs/intro/install/) installed.
* **PostgreSQL Database**: An accessible PostgreSQL instance within your cluster or network.
* **Redis Server**: An accessible Redis instance within your cluster or network.

#### Optional Components

* **Sealed Secrets Controller**: For secure management of secrets via encrypted files.
  * [Sealed Secrets Installation Guide](https://github.com/bitnami-labs/sealed-secrets#installation)
* **Ingress Controller**: Required if you plan to use ingress resources.
  * Traefik (recommended)
* **cert-manager**: For automatic management and issuance of TLS certificates.
  * [cert-manager Installation Guide](https://cert-manager.io/docs/installation/)

***

### Installation Steps

#### 1. Configure Values

Create a `my-values.yaml` file based on your environment. Refer to the Values File Example section below.

#### 2. Install the Chart

Install or upgrade the Scorable chart using Helm:

```bash
# 1. Log in to the Replicated registry. Scorable will provide information.
helm registry login registry.replicated.com --username <email> --password <password>
# 2. Install
helm upgrade --install --atomic --create-namespace --namespace scorable -f my-values.yaml scorable oci://registry.replicated.com/scorable
```

***

### Configuration Details

#### Values File Example

Below is an example `my-values.yaml` file to guide your configuration:

<pre class="language-yaml"><code class="lang-yaml"># Storage Configuration
useAzureStorage: true
azureStorageAccountName: "my-storage-account"
azureStoragePublicDataContainer: "my-public-container"
azureStorageCustomerDataContainer: "my-private-container"

# S3 Configuration (Set useS3 to true if using S3)
useS3: false
publicBucketName: "public-bucket"
privateBucketName: "private-bucket"
privateBucketPrefix: "private"

# Secrets Management
useSealedSecrets: true
# Alternatively, reference an existing Kubernetes secret
# secretRef: "my-secret"

# Image pull secret for Scorable application images
# Scorable will provide the value on onboarding
imagePullSecret: "scorable-image-pull-secret"

secrets:
  # Encrypted secrets (use `kubeseal` to encrypt your secrets)
  AZURE_OPENAI_API_KEY: "AgAVmYeIQ2DUaqtvd8wgGYs..."
  OPENAI_API_KEY: "Ag..."
  NEXTAUTH_SECRET: "Ag..."  # Do not change once set
  SECRET_KEY: "Ag..."       # Do not change once set
  POSTGRES_PASSWORD: "Ag..."
  REDIS_PASSWORD: "Ag..."
  AZURE_STORAGE_CONNECTION_STRING: "Ag..." # If using Azure Storage. Contact RS support if you want to use SAS token.
  AWS_ACCESS_KEY_ID: "Ag..." # If using S3
  AWS_SECRET_ACCESS_KEY: "Ag..." # If using S3

  # Optional Secrets
  ANTHROPIC_API_KEY: "Ag..."
  MISTRAL_API_KEY: "Ag..."
  VOYAGE_API_KEY: "Ag..."
  # Overwrites the hosts.redis + REDIS_PASSWORD combination
  CELERY_BROKER_URL: "Ag..."
  LITELLM_REDIS_URL: "Ag..."
  # For Google SSO
  GOOGLE_CLIENT_ID: "Ag..."
  GOOGLE_CLIENT_SECRET: "Ag..."

# sentryDsn: "https://your-sentry-dsn"  # Deployments can use

# Domain Configuration
domain: "localhost"  # Replace with your domain

# Host Configuration
hosts:
  redis: "redis-master.redis.svc.cluster.local"      # Update to match your setup
  postgres: "postgres.postgres.svc.cluster.local"    # Update to match your setup

# PostgreSQL Configuration
postgresUser: "scorable"
postgresDb: "scorable"

# Frontend Configuration
frontend:
  apiBaseUrl: "http://localhost:8000"  # Adjust to your environment
  ingress:
    enabled: false  # Set to true if using an NGINX ingress controller
    
# API Configuration
api:
  ingress:
    enabled: false  # Set to true if using an NGINX ingress controller
    
# Include additional resources
<strong>extraManifests: []
</strong>    
</code></pre>

**Notes:**

* **Storage**: Configure either Azure Blob Storage or AWS S3 based on your preference.
* **Secrets**: If `useSealedSecrets` is `true`, ensure your secrets are encrypted using the Sealed Secrets Controller.
* **Domain and Hosts**: Update the `domain` and `hosts` sections to match your environment.
* **Ingress**: If using an NGINX ingress controller + cert-manager, set `enabled: true` under the `ingress` sections.

#### Database

Create a database for the application

```sql
CREATE ROLE scorable
  LOGIN
  PASSWORD 'REPLACE_WITH_STRONG_PASSWORD';

CREATE DATABASE scorable
  OWNER scorable
  ENCODING 'UTF8';

\c scorable

CREATE SCHEMA llm_proxy AUTHORIZATION scorable;
```

#### Secrets Management

If `useSealedSecrets` is set to `true`, you need to encrypt your secrets using `kubeseal`. Install the Sealed Secrets CLI:

```bash
# On macOS with Homebrew
brew install kubeseal

# On other systems
# Refer to https://github.com/bitnami-labs/sealed-secrets#installation
```

Encrypt your secrets:

```bash
echo -n "your-secret-value" | kubeseal --scope cluster-wide --raw --from-file=/dev/stdin
```

Replace `your-secret-value` with your actual secret and follow the prompts. Repeat for each secret.

Alternatively, if you prefer to manage secrets via Kubernetes secrets, set `useSealedSecrets` to `false` and create a Kubernetes secret:

```bash
kubectl create secret generic my-secrets \
  --from-literal=POSTGRES_PASSWORD="your-postgres-password" \
  --from-literal=REDIS_PASSWORD="your-redis-password" \
  # ...
  --namespace scorable
```

Then, reference this secret in your `my-values.yaml`:

```yaml
useSealedSecrets: false
secretRef: "my-secrets"
```

***

### Accessing the Application

#### Using Ingress

It is recommended to deploy an ingress controller to access the application. You can use any ingress controller, such as Traefik

The example setup works with an NGINX ingress. You can enable it by enabling the ingress in the `api` and `frontend` sections of your values file.

In that setup, the domain in your values file is used. So for example:\
\
`domain: "mydomain.com"`\
\
Would make the application available in `mydomain.com` and `api.mydomain.com`

Alternatively, you can configure a custom ingress. In order for the application to work, you should enable access to the `api` and `frontend` k8s services in the namespace.

#### Using Port Forwarding

Alternatively, you can use `kubectl port-forward` to access the services locally:

```bash
# Forward the frontend service
kubectl port-forward --namespace scorable service/frontend 3000:80

# Forward the API service
kubectl port-forward --namespace scorable service/api 8000:80
```

Open your browser and navigate to <http://localhost:3000> to access the web UI.

***

### Monitoring and Logging

#### Sentry Integration

Scorable supports integration with [Sentry](https://sentry.io/) for error tracking and monitoring.

#### Prometheus Metrics

The application exposes metrics at `/metrics` endpoints, which can be scraped by [Prometheus](https://prometheus.io/). To set up Prometheus monitoring:

1. Deploy Prometheus in your cluster. You can use the [Prometheus Helm Chart](https://github.com/prometheus-community/helm-charts).
2. Configure Prometheus to scrape the metrics endpoints of Scorable services.

For detailed assistance, please get in touch with our support team.

***

### Updates

Scorable notifies customer contact persons when new versions of the Helm chart are available

***

### Support

If you encounter any issues or have questions, please reach out:

* **Email**: `support@scorable.ai`
* **Slack**

***

**Note**: Always ensure that your Kubernetes cluster and Helm are up to date to avoid compatibility issues. Regularly back up your configurations and data.
