Helm configuration (v1.x)

[Edit this page](https://github.com/ClickHouse/clickhouse-docs/blob/main/docs/use-cases/observability/clickstack/deployment/oss/helm/v1/helm-configuration-v1.md)

Deprecated — v1.x chart

This page documents configuration for the **v1.x** inline-template Helm chart, which is in maintenance mode. For the v2.x chart, see [Helm configuration](/docs/use-cases/observability/clickstack/deployment/helm-configuration). To migrate, see the [Upgrade guide](/docs/use-cases/observability/clickstack/deployment/helm-upgrade).

This guide covers configuration options for ClickStack Helm deployments. For basic installation, see the [main Helm deployment guide](/docs/use-cases/observability/clickstack/deployment/helm-v1).

## API key setup[​](#api-key-setup "Direct link to API key setup")

After successfully deploying ClickStack, configure the API key to enable telemetry data collection:

1. **Access your HyperDX instance** via the configured ingress or service endpoint
2. **Log into the HyperDX dashboard** and navigate to Team settings to generate or retrieve your API key
3. **Update your deployment** with the API key using one of the following methods:

### Method 1: Update via Helm upgrade with values file[​](#api-key-values-file "Direct link to Method 1: Update via Helm upgrade with values file")

Add the API key to your `values.yaml`:

```
hyperdx:
  apiKey: "your-api-key-here"
```

Then upgrade your deployment:

```
helm upgrade my-clickstack clickstack/clickstack -f values.yaml
```

### Method 2: Update via Helm upgrade with --set flag[​](#api-key-set-flag "Direct link to Method 2: Update via Helm upgrade with --set flag")

```
helm upgrade my-clickstack clickstack/clickstack --set hyperdx.apiKey="your-api-key-here"
```

### Restart pods to apply changes[​](#restart-pods "Direct link to Restart pods to apply changes")

After updating the API key, restart the pods to pick up the new configuration:

```
kubectl rollout restart deployment my-clickstack-clickstack-app my-clickstack-clickstack-otel-collector
```

Note

The chart automatically creates a Kubernetes secret (`<release-name>-app-secrets`) with your API key. No additional secret configuration is needed unless you want to use an external secret.

## Secret management[​](#secret-management "Direct link to Secret management")

For handling sensitive data such as API keys or database credentials, use Kubernetes secrets.

### Using pre-configured secrets[​](#using-pre-configured-secrets "Direct link to Using pre-configured secrets")

The Helm chart includes a default secret template located at [`charts/clickstack/templates/secrets.yaml`](https://github.com/hyperdxio/helm-charts/blob/main/charts/clickstack/templates/secrets.yaml). This file provides a base structure for managing secrets.

If you need to manually apply a secret, modify and apply the provided `secrets.yaml` template:

```
apiVersion: v1
kind: Secret
metadata:
  name: hyperdx-secret
  annotations:
    "helm.sh/resource-policy": keep
type: Opaque
data:
  API_KEY: <base64-encoded-api-key>
```

Apply the secret to your cluster:

```
kubectl apply -f secrets.yaml
```

### Creating a custom secret[​](#creating-a-custom-secret "Direct link to Creating a custom secret")

Create a custom Kubernetes secret manually:

```
kubectl create secret generic hyperdx-secret \
  --from-literal=API_KEY=my-secret-api-key
```

### Referencing a secret in values.yaml[​](#referencing-a-secret "Direct link to Referencing a secret in values.yaml")

```
hyperdx:
  apiKey:
    valueFrom:
      secretKeyRef:
        name: hyperdx-secret
        key: API_KEY
```

## Ingress setup[​](#ingress-setup "Direct link to Ingress setup")

To expose the HyperDX UI and API via a domain name, enable ingress in your `values.yaml`.

### General ingress configuration[​](#general-ingress-configuration "Direct link to General ingress configuration")

```
hyperdx:
  frontendUrl: "https://hyperdx.yourdomain.com"  # Must match ingress host
  ingress:
    enabled: true
    host: "hyperdx.yourdomain.com"
```

Important configuration note

`hyperdx.frontendUrl` should match the ingress host and include the protocol (e.g., `https://hyperdx.yourdomain.com`). This ensures that all generated links, cookies, and redirects work correctly.

### Enabling TLS (HTTPS)[​](#enabling-tls "Direct link to Enabling TLS (HTTPS)")

To secure your deployment with HTTPS:

**1. Create a TLS secret with your certificate and key:**

```
kubectl create secret tls hyperdx-tls \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key
```

**2. Enable TLS in your ingress configuration:**

```
hyperdx:
  ingress:
    enabled: true
    host: "hyperdx.yourdomain.com"
    tls:
      enabled: true
      tlsSecretName: "hyperdx-tls"
```

### Example ingress configuration[​](#example-ingress-configuration "Direct link to Example ingress configuration")

For reference, here's what the generated ingress resource looks like:

```
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hyperdx-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: hyperdx.yourdomain.com
      http:
        paths:
          - path: /(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: my-clickstack-clickstack-app
                port:
                  number: 3000
  tls:
    - hosts:
        - hyperdx.yourdomain.com
      secretName: hyperdx-tls
```

### Common ingress pitfalls[​](#common-ingress-pitfalls "Direct link to Common ingress pitfalls")

**Path and rewrite configuration:**

- For Next.js and other SPAs, always use a regex path and rewrite annotation as shown above
- Don't use just `path: /` without a rewrite, as this will break static asset serving

**Mismatched `frontendUrl` and `ingress.host`:**

- If these don't match, you may experience issues with cookies, redirects, and asset loading

**TLS misconfiguration:**

- Ensure your TLS secret is valid and referenced correctly in the ingress
- Browsers may block insecure content if you access the app over HTTP when TLS is enabled

**Ingress controller version:**

- Some features (like regex paths and rewrites) require recent versions of nginx ingress controller
- Check your version with:

```
kubectl -n ingress-nginx get pods -l app.kubernetes.io/name=ingress-nginx -o jsonpath="{.items[0].spec.containers[0].image}"
```

## OTEL collector ingress[​](#otel-collector-ingress "Direct link to OTEL collector ingress")

If you need to expose your OTEL collector endpoints (for traces, metrics, logs) through ingress, use the `additionalIngresses` configuration. This is useful for sending telemetry data from outside the cluster or using a custom domain for the collector.

```
hyperdx:
  ingress:
    enabled: true
    additionalIngresses:
      - name: otel-collector
        annotations:
          nginx.ingress.kubernetes.io/ssl-redirect: "false"
          nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
          nginx.ingress.kubernetes.io/use-regex: "true"
        ingressClassName: nginx
        hosts:
          - host: collector.yourdomain.com
            paths:
              - path: /v1/(traces|metrics|logs)
                pathType: Prefix
                port: 4318
                name: otel-collector
        tls:
          - hosts:
              - collector.yourdomain.com
            secretName: collector-tls
```

- This creates a separate ingress resource for the OTEL collector endpoints
- You can use a different domain, configure specific TLS settings, and apply custom annotations
- The regex path rule allows you to route all OTLP signals (traces, metrics, logs) through a single rule

Note

If you don't need to expose the OTEL collector externally, you can skip this configuration. For most users, the general ingress setup is sufficient.

## Troubleshooting ingress[​](#troubleshooting-ingress "Direct link to Troubleshooting ingress")

**Check ingress resource:**

```
kubectl get ingress -A
kubectl describe ingress <ingress-name>
```

**Check ingress controller logs:**