Helm configuration

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

Chart version 2.x

This page documents the **v2.x** subchart-based Helm chart. If you are still using the v1.x inline-template chart, see [Helm configuration (v1.x)](/docs/use-cases/observability/clickstack/deployment/helm-configuration-v1). For migration steps, 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).

## Values organization[​](#values-organization "Direct link to Values organization")

The v2.x chart organizes values by Kubernetes resource type under the `hyperdx:` block:

```
hyperdx:
  ports:          # Shared port numbers (Deployment, Service, ConfigMap, Ingress)
    api: 8000
    app: 3000
    opamp: 4320

  frontendUrl: "http://localhost:3000"

  config:         # → clickstack-config ConfigMap (non-sensitive env vars)
    APP_PORT: "3000"
    HYPERDX_LOG_LEVEL: "info"

  secrets:        # → clickstack-secret Secret (sensitive env vars)
    HYPERDX_API_KEY: "..."
    CLICKHOUSE_PASSWORD: "otelcollectorpass"
    CLICKHOUSE_APP_PASSWORD: "hyperdx"
    MONGODB_PASSWORD: "hyperdx"

  deployment:     # K8s Deployment spec (image, replicas, probes, etc.)
  service:        # K8s Service spec (type, annotations)
  ingress:        # K8s Ingress spec (host, tls, annotations)
  podDisruptionBudget:  # K8s PDB spec
  tasks:          # K8s CronJob specs
```

All environment variables flow through two static-named resources shared by the HyperDX Deployment **and** the OTEL Collector via `envFrom`:

- **`clickstack-config`** ConfigMap — populated from `hyperdx.config`
- **`clickstack-secret`** Secret — populated from `hyperdx.secrets`

There is no longer a separate OTEL-specific ConfigMap. Both workloads read from the same sources.

## 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:
  secrets:
    HYPERDX_API_KEY: "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.secrets.HYPERDX_API_KEY="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
```

Note

The chart automatically creates a Kubernetes secret (`clickstack-secret`) with your configuration values. 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, the v2.x chart provides a unified `clickstack-secret` resource populated from `hyperdx.secrets`.

### Default secret values[​](#default-secret-values "Direct link to Default secret values")

The chart ships with default values for all secrets. Override them in your `values.yaml`:

```
hyperdx:
  secrets:
    HYPERDX_API_KEY: "your-api-key"
    CLICKHOUSE_PASSWORD: "your-clickhouse-otel-password"
    CLICKHOUSE_APP_PASSWORD: "your-clickhouse-app-password"
    MONGODB_PASSWORD: "your-mongodb-password"
```

### Using an external secret[​](#using-external-secret "Direct link to Using an external secret")

For production deployments where you want to keep credentials separate from Helm values, use an external Kubernetes secret:

```
# Create your secret
kubectl create secret generic my-clickstack-secrets \
  --from-literal=HYPERDX_API_KEY=my-secret-api-key \
  --from-literal=CLICKHOUSE_PASSWORD=my-ch-password \
  --from-literal=CLICKHOUSE_APP_PASSWORD=my-ch-app-password \
  --from-literal=MONGODB_PASSWORD=my-mongo-password
```

Then reference it in your values:

```
hyperdx:
  useExistingConfigSecret: true
  existingConfigSecret: "my-clickstack-secrets"
```

## 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.