> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ditto.live/llms.txt
> Use this file to discover all available pages before exploring further.

# Self-Managed Portal

<Warning>
  The Self-Managed Portal is in **early preview**. We recommend using the self managed UI for **development only**, and welcome any feedback.

  Features and configuration options may change in future releases.
</Warning>

<Warning>
  The Ditto SDK v5 has renamed Application to Database and AppID to DatabaseID. The operator and Self Managed portal will update this terminology in a future release. This documentation uses the older Application terminology that matches the current release.
</Warning>

The Self-Managed Portal provides a web interface for managing your Ditto applications in self-managed deployments, similar to the [Ditto Cloud Portal](https://portal.ditto.live).

It enables you to view query data, configure SDK authentication, DataBridges, the Mongo Connector, and more.

This guide assumes you have followed the [Getting Started](./operator-quickstart) guide and have a Big Peer deployed with at least one App.

## Enabling the Portal

In this early iteration of the Self-Managed Portal, the client interacts directly with the Operator API and Big Peer API.

As such, there are a few steps required to allow the Portal to access these APIs.

<Steps>
  <Step title="Enable the Portal in the Operator">
    Upgrade the Ditto Operator Helm release to enable the portal:

    ```bash theme={null}
    helm upgrade ditto-operator                       \
      oci://quay.io/ditto-external/ditto-operator     \
      --namespace ditto                               \
      --reuse-values                                  \
      --set portal.enabled=true                       \
      --set portal.config.bigPeerName=example         \
      --set portal.config.operatorApiUrl=http://localhost:8081 \
      --set portal.config.bigPeerBaseUrl=http://localhost:8082
    ```

    Replace `example` with the name of your Big Peer.

    <Info>
      The `operatorApiUrl` and `bigPeerBaseUrl` values are configured for local port-forwarding, which we'll set up in a later step.
    </Info>
  </Step>

  <Step title="Configure CORS on your Big Peer">
    The Portal UI runs in your browser and makes requests to the Big Peer HTTP API. To allow these cross-origin requests, configure CORS on your Big Peer:

    ```bash theme={null}
    kubectl patch bigpeer example -n ditto --type=merge -p '{
      "spec": {
        "network": {
          "ingress": {
            "template": {
              "ingress": {
                "metadata": {
                  "annotations": {
                    "nginx.ingress.kubernetes.io/enable-cors": "true",
                    "nginx.ingress.kubernetes.io/cors-allow-origin": "*",
                    "nginx.ingress.kubernetes.io/cors-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
                    "nginx.ingress.kubernetes.io/cors-allow-headers": "X-DITTO-ENSURE-INSERT,X-HYDRA-ENSURE-INSERT,X-DITTO-ACTOR-ID,X-DITTO-CLIENT-ID,X-HYDRA-CLIENT-ID,X-DITTO-SDK-VERSION,Accept,Referer,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Forwarded-For"
                  }
                }
              }
            }
          }
        }
      }
    }'
    ```

    Replace `example` with the name of your Big Peer.
  </Step>

  <Step title="Set up port forwarding">
    The Portal requires access to three services. Set up port forwarding for each:

    ```bash theme={null}
    # Terminal 1: Portal UI
    kubectl port-forward svc/ditto-operator-portal 8080:80 -n ditto

    # Terminal 2: Operator API
    kubectl port-forward deployments/ditto-operator 8081:8080 -n ditto

    # Terminal 3: Big Peer API (through nginx for CORS)
    kubectl port-forward svc/ingress-nginx-controller 8082:80 -n ingress-nginx
    ```

    <Info>
      The Big Peer API port-forward goes through the nginx ingress controller to ensure CORS headers are applied. Direct port-forwarding to the Big Peer API pods would bypass nginx and result in CORS errors.
    </Info>
  </Step>

  <Step title="Access the Portal">
    Open [http://localhost:8080](http://localhost:8080) in your browser. The Portal login page should appear.
  </Step>
</Steps>

## Using the Portal

### Authenticating with the Operator API

When you first access the Portal, you'll be prompted to authenticate with the Operator API. The Portal uses a Kubernetes service account token for this.

Generate a token:

```bash theme={null}
kubectl create token default --audience=portal-self-managed -n ditto
```

Copy the token and paste it into the Portal when prompted. This token is short-lived and will need to be regenerated periodically.

## New Installation

To enable the portal as part of a new Operator installation:

```bash theme={null}
helm install ditto-operator                       \
  oci://quay.io/ditto-external/ditto-operator     \
  --namespace ditto                               \
  --create-namespace                              \
  --set portal.enabled=true                       \
  --set portal.config.bigPeerName=example         \
  --set portal.config.operatorApiUrl=http://localhost:8081 \
  --set portal.config.bigPeerBaseUrl=http://localhost:8082
```

## Configuration Options

| Option                         | Description                                       | Default        |
| ------------------------------ | ------------------------------------------------- | -------------- |
| `portal.enabled`               | Enable the self-managed portal UI                 | `false`        |
| `portal.config.bigPeerName`    | Name of the BigPeer resource to manage            | `''`           |
| `portal.config.operatorApiUrl` | URL for the Portal to reach the Operator API      | Auto-generated |
| `portal.config.bigPeerBaseUrl` | URL for the Portal to reach the Big Peer HTTP API | `''`           |
| `portal.replicaCount`          | Number of portal replicas                         | `1`            |
| `portal.image.tag`             | Override the portal image tag                     | `0.3.0`        |
| `portal.ingress.enabled`       | Enable ingress for external access                | `false`        |
