---
title: Configuring Tines with Helm
url: https://www.tines.com/stories/docs/self-hosted/configuring-tines/configuring-tines-with-helm/
updated: 2026-11-09T23:40:40+00:00
---

*[tines.com](https://www.tines.com/llms.txt) › [Docs](https://www.tines.com/stories/docs/llms.txt) › [Self-Hosted](https://www.tines.com/llm/stories/docs/self-hosted.md) › [Configuring Tines](https://www.tines.com/llm/stories/docs/self-hosted/configuring-tines.md)*

# Configuring Tines with Helm

*[View on tines.com](https://www.tines.com/stories/docs/self-hosted/configuring-tines/configuring-tines-with-helm/)*

Configure Tines by creating a local `values.yaml` file that overrides the Helm chart defaults. This guide covers registry access, tenant setup, database and Redis connections, email, storage, networking, and optional components.

Before you begin, [add the Tines Helm repository](https://www.tines.com/stories/docs/self-hosted/getting-started/helm-charts/).

## Prepare your values file

Inspect the defaults for the chart version you plan to install. Replace `<chart-version>` with your selected version:

```shell
helm show values tines/tines --version <chart-version>
```

Create `values.yaml` with the overrides you need. The examples below are separate configuration fragments. Combine settings under a single top-level key, such as `tinesApp`, rather than repeating that key in the file.

Configuration options vary by chart version. Check that your selected version supports each option before using it.

## Use existing Kubernetes Secrets

The chart can read sensitive values from Kubernetes Secrets you manage. Create these Secrets in the installation namespace before installing or upgrading Tines. The sections below show how to reference them for registry access, application settings, database credentials, and nginx TLS.

> **Note:** When switching an existing installation to these references, copy any chart-created Secret to a different name first. The chart rejects `container-registry-secret`, `db-secret`, and `nginx-ssl-certs` as `existingSecret` names because Helm removes those resources when the chart stops creating them.

## Registry credentials

Use credentials for the registry that hosts your chart's images. See [Accessing the OCI registry](https://www.tines.com/stories/docs/self-hosted/getting-started/accessing-the-oci-registry/) or [Accessing the Docker registry](https://www.tines.com/stories/docs/self-hosted/getting-started/accessing-the-docker-registry/) for authentication instructions.

For images hosted at `oci.tines.com`:

```yaml
tinesContainerRegistryCredentials:
  registry: oci.tines.com
  username: "<your-oci-username>"
  password: "<your-oci-password>"
  email: "<your-email>"
```

The chart uses these values to create an image pull secret. If your chart uses `registry.tines.com`, set the registry and credentials to match.

To use an existing image pull Secret instead:

```yaml
tinesContainerRegistryCredentials:
  existingSecret: tines-registry
```

The Secret must have type `kubernetes.io/dockerconfigjson` and contain credentials for the image registry. Leave `username`, `password`, and `email` unset when using `existingSecret`; the chart rejects combining them.

If you use an internal registry mirror, update the relevant `deployments.*.image` settings to match the mirrored images. For OpenShift, update `deployments.*.openshiftImage` instead. Check the registry, repository, and tag for each image.

## App secret token

Generate a random 128-character token:

```shell
openssl rand -hex 64
```

Add the generated value to your configuration:

```yaml
tinesApp:
  serverConfiguration:
    APP_SECRET_TOKEN: "<128-character-token>"
```

The chart requires an app secret token. Keep the same token when upgrading an existing installation.

To read the token from a Secret instead:

```yaml
tinesApp:
  secretEnv:
    APP_SECRET_TOKEN:
      name: tines-app-secrets
      key: APP_SECRET_TOKEN
```

The Secret must contain the token at the specified key. Leave `serverConfiguration.APP_SECRET_TOKEN` unset when using this reference. More generally, a setting in `secretEnv` must not also be set in the chart's application configuration maps.

## Initial tenant configuration

Set the domain, tenant name, and details for the first administrator:

```yaml
tinesApp:
  initialTenantConfiguration:
    DOMAIN: tines.your-company.com
    SEED_EMAIL: admin@your-company.com
    SEED_EMAIL_PASSWORD: "<password>"
    SEED_FIRST_NAME: Admin
    SEED_LAST_NAME: User
    TENANT_NAME: your-company-name
```

> **Note:** `initialTenantConfiguration` seeds the first tenant and administrator. Changing these values in a later Helm upgrade does not update the existing tenant or user.

The `SEED_*` fields are optional. Set the fields needed for your initial administrator rather than relying on default credentials.

## Apply tenant configuration

Use `tinesApp.tenantConfiguration` to apply tenant settings during installation and upgrades. Enable it explicitly and create any referenced Secrets before running Helm:

```yaml
tinesApp:
  tenantConfiguration:
    enabled: true
    license:
      existingSecret: tines-license
      key: license
    limits:
      dailyStoryEvents: 250000
      dailyTenantEvents: 500000
    teams:
      - name: Security
        caseGroups:
          - name: Investigations
```

This example reads the license key from a Secret, sets daily event limits, and creates a root team with a case group as a child team. The action limit is defined by the license key.

The setup job applies the supported configuration after database migration, in one database transaction. Each upgrade applies the configured values again. Teams and case groups are matched by name; removing an entry from your values file leaves the saved entry in place. Leave a setting empty to keep its current value.

You can also configure:

- The primary SAML or OIDC configuration, SSO group mappings, and LDAP.
- Public access for pages, MCP, and AI Agent Chat, and whether personal teams are enabled.
- Login notices, direct credential access, Run Script, automatic mode, page branding, and change control.
- Story allocation, AI settings, event-limit alert thresholds, action egress rules, custom certificate authorities, and sender email addresses.
- Removal of the seed team, or removal or deactivation of the seed user.

Store the license, SSO certificates and client secrets, LDAP bind password, and custom certificate authorities in Secrets. For LDAP managed through `tenantConfiguration.ldap`, do not also set `LDAP_*` environment variables on the application pods.

See the chart's [tenant configuration reference](https://github.com/tines/helm-charts/blob/main/charts/tines/README.md#tenant-configuration) for complete examples and required fields. Match these options to the values in your selected chart version.

### Run a custom configuration script

For settings the supported tenant configuration does not cover, the setup job can run a Rails script from an existing ConfigMap or Secret:

```yaml
tinesApp:
  tenantConfiguration:
    customScript:
      existingConfigMap: customer-tenant-setup
      key: configure.rb
```

Set either `existingConfigMap` or `existingSecret`. The specified key must contain the script. The script runs after database migration and the supported tenant configuration, even if `tenantConfiguration.enabled` is false.

The script runs again on every upgrade, so it must be safe to repeat. If it fails, the setup job fails, but tenant settings already saved by the supported configuration remain in place. Use `customScript.env` for additional environment variables, including Secret and ConfigMap references; see the [configuration reference](https://github.com/tines/helm-charts/blob/main/charts/tines/README.md#tenant-configuration) for its format and restrictions.

## Database

Tines uses PostgreSQL for persistent data. The chart can deploy PostgreSQL in the cluster, or connect to a database you manage separately. We recommend a managed database service where possible to simplify scaling and backups.

### Use the bundled database

Provide the database credentials:

```yaml
tinesApp:
  databaseConfiguration:
    DATABASE_NAME: tines_production
    DATABASE_USERNAME: tines
    DATABASE_PASSWORD: "<password>"
    DATABASE_POOL: 20
    DATABASE_PORT: 5432
```

Leave `db.create` enabled and use the database host selected by your chart version. Chart defaults can change between versions. For example, chart 44.2.4 uses PostgreSQL 18 for new installations and preserves the database connection of existing installations during upgrades.

For the bundled database on OpenShift, set `PGDATA` to a subdirectory so PostgreSQL can initialize it with the required permissions:

```yaml
db:
  PGDATA: /var/lib/postgresql/data/userdata
```

Configure additional PostgreSQL server settings with `db.extraConfig`. The bundled database defaults to `max_connections: 500`:

```yaml
db:
  extraConfig:
    max_connections: 500
```

These settings apply to the bundled PostgreSQL instances. Configure an external database through its own management tools.

### Use an external database

Disable the bundled database and provide your database endpoint:

```yaml
db:
  create: false

tinesApp:
  databaseConfiguration:
    DATABASE_HOST: my-postgres.example.com
    DATABASE_NAME: tines_production
    DATABASE_USERNAME: tines
    DATABASE_PASSWORD: "<password>"
    DATABASE_POOL: 20
    DATABASE_PORT: 5432
```

For an existing PostgreSQL 14 installation, see [Upgrading from PostgreSQL 14 to PostgreSQL 18](https://www.tines.com/stories/docs/self-hosted/upgrade-tines/upgrading-from-postgresql-14-to-postgresql-18/) before changing the database version or host.

### Read database credentials from a Secret

For either a bundled or external database, reference a Secret containing the username and password:

```yaml
tinesApp:
  databaseConfiguration:
    existingSecret: tines-db
    usernameSecretKey: POSTGRES_USER
    passwordSecretKey: POSTGRES_PASSWORD
```

Remove `DATABASE_PASSWORD` from your values when using this reference. `DATABASE_USERNAME` may remain at its default. Continue configuring the database host, name, port, and pool as needed; use `databaseConfiguration.existingSecret` for database credentials rather than `secretEnv`.

For an existing database, the Secret must contain credentials that the database already accepts. Changing the Secret does not change the PostgreSQL role or password. A new bundled database is initialized from the Secret when its data directory is empty.

## Redis

Tines uses a Redis-compatible service for caching and job queues. The current chart's bundled service uses Valkey 7.2. Existing Redis image overrides remain supported. We recommend a managed service where possible to simplify scaling.

To use an external service, disable the bundled service and set the connection URL:

```yaml
redis:
  create: false

tinesApp:
  redisConfiguration:
    REDIS_URL: redis://my-redis.example.com:6379/0
```

## SMTP server

Configure an SMTP server to send invitations, notifications, monitoring emails, and emails from the Send Email action:

```yaml
tinesApp:
  emailConfiguration:
    SMTP_SERVER: smtp.your-company.com
    SMTP_DOMAIN: your-company.com
    SMTP_USER_NAME: smtp-user
    SMTP_PASSWORD: "<password>"
    SMTP_PORT: "587"
    SMTP_AUTHENTICATION: login
    SMTP_ENABLE_STARTTLS_AUTO: true
```

Adjust the port, authentication method, and TLS settings for your SMTP server. SMTP is required to invite the first administrator by email unless you set `SEED_EMAIL_PASSWORD`.

All SMTP fields are optional for chart installation. For an unauthenticated relay, omit the username and password and set `SMTP_AUTHENTICATION: none`. Without working SMTP, email-dependent features, including invitations and password resets, cannot send email.

To read the SMTP password from a Secret:

```yaml
tinesApp:
  secretEnv:
    SMTP_PASSWORD:
      name: tines-smtp
      key: SMTP_PASSWORD
```

Leave `emailConfiguration.SMTP_PASSWORD` unset when using this reference.

## Persistent storage

Your cluster needs a StorageClass that supports `ReadWriteOnce` persistent volumes.

Set the storage class for the components you deploy. Replace `your-storage-class` with the name of a StorageClass in your cluster:

```yaml
db:
  storageClassName: your-storage-class

redis:
  storageClassName: your-storage-class

deployments:
  pypiServer:
    storageClassName: your-storage-class
```

Storage defaults vary by chart version. Inspect the selected chart's values instead of assuming it uses your cluster's default StorageClass.

We recommend a StorageClass with a `Retain` reclaim policy to preserve the underlying persistent volume when its claim is deleted.

## Load balancer

Choose one of the following approaches to expose Tines. Your load balancer must support WebSockets for live updates in the UI.

### Use the bundled nginx proxy

The chart's nginx service exposes HTTP on port 30080 and HTTPS on port 30443 by default.

To terminate TLS at nginx, provide your certificate and private key:

```yaml
nginx:
  enabled: true
  tinesCrt: |
    -----BEGIN CERTIFICATE-----
    <your-certificate>
    -----END CERTIFICATE-----
  tinesKey: |
    -----BEGIN PRIVATE KEY-----
    <your-private-key>
    -----END PRIVATE KEY-----
```

To use a certificate and private key from an existing Secret instead:

```yaml
nginx:
  enabled: true
  existingSecret: tines-nginx-tls
  certSecretKey: tls.crt
  keySecretKey: tls.key
```

The Secret must contain the certificate and key under the specified keys. Leave `tinesCrt` and `tinesKey` unset when using `existingSecret`.

### Use Kubernetes Ingress

The optional Ingress routes traffic to the Tines web server on port 3000. Disable the bundled nginx proxy when using this approach:

```yaml
nginx:
  enabled: false

ingress:
  enabled: true
  className: nginx
  annotations: {}
  hosts:
    - host: tines.your-company.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: tines-tls
      hosts:
        - tines.your-company.com
```

This example uses an nginx Ingress controller. Set `className`, annotations, and TLS configuration for your controller. The chart defaults include annotation examples for AWS ALB, Azure Application Gateway, and Google Cloud Load Balancing.

### Use an OpenShift Route

To expose Tines with an OpenShift Route, disable nginx and configure the route:

```yaml
nginx:
  enabled: false

route:
  enabled: true
  annotations: {}
  host: tines.your-company.com
  path: /
  tls:
    termination: edge
    key: |
      -----BEGIN PRIVATE KEY-----
      <your-private-key>
      -----END PRIVATE KEY-----
    certificate: |
      -----BEGIN CERTIFICATE-----
      <your-certificate>
      -----END CERTIFICATE-----
    caCertificate: |
      -----BEGIN CERTIFICATE-----
      <your-ca-certificate>
      -----END CERTIFICATE-----
  wildcardPolicy: None
```

## Optional components

Contact your Account Executive or Customer Success Manager to confirm that your license includes an optional component before enabling it.

### Command-over-HTTP

To enable Command-over-HTTP in the main chart:

```yaml
commandOverHttp:
  create: true
```

If you use tunnel mode, also provide the tunnel secret:

```yaml
commandOverHttp:
  create: true
  tunnelSecret: "<your-cohttp-secret>"
```

For standalone Command-over-HTTP or Tines Tunnel installations, see [Deploying optional components](https://www.tines.com/stories/docs/self-hosted/deploying-tines/deploying-tines-with-helm/#deploy-optional-components).

## Custom banner

Display a custom banner in the Tines UI:

```yaml
tinesApp:
  optionalFeatureConfiguration:
    TINES_BANNER_ENABLED: true
    TINES_BANNER_COLOR: "#663399"
    TINES_BANNER_TEXT: "Internal use only"
```

Quote the hexadecimal color value in YAML.

## Command runner connections

The chart enables sticky connections for the command runner with `tinesApp.tinesCommandRunner.stickyConnections: true`. Keep this enabled when using custom runtimes; disabling it breaks custom runtime support.

## Next steps

With your values file prepared, follow [Deploying Tines with Helm](https://www.tines.com/stories/docs/self-hosted/deploying-tines/deploying-tines-with-helm/) to install Tines.

To apply changes to an existing installation, follow [Upgrading Tines with Helm](https://www.tines.com/stories/docs/self-hosted/upgrade-tines/upgrading-tines-with-helm/).
