1. Docs
  2. Self-Hosted
  3. 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.

Prepare your values file

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

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 or Accessing the Docker registry for authentication instructions.

For images hosted at oci.tines.com:

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:

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:

openssl rand -hex 64

Add the generated value to your configuration:

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:

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:

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:

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 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:

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 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:

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:

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

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

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:

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 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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

commandOverHttp:
  create: true

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

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

For standalone Command-over-HTTP or Tines Tunnel installations, see Deploying optional components.

Custom banner

Display a custom banner in the Tines UI:

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 to install Tines.

To apply changes to an existing installation, follow Upgrading Tines with Helm.

Was this helpful?