# Deploy TREK on Kubernetes with Helm: Complete Installation Guide

> Deploy TREK on Kubernetes with its official Helm chart. Install the entire TREK application stack, including deployments, services, and PVCs, using a single Helm command.

- Repository: [Maurice/TREK](https://github.com/mauriceboe/TREK)
- Tags: how-to-guide
- Published: 2026-06-26

---

**TREK ships an official Helm chart that deploys the entire application stack—including the Deployment, Service, PersistentVolumeClaims, and optional Ingress—to any Kubernetes cluster with a single `helm install` command.**

The mauriceboe/TREK repository maintains a production-ready Helm chart in the `charts/trek/` directory that automates the deployment of TREK on Kubernetes. This guide explains how to deploy TREK on Kubernetes using the Helm chart by configuring encryption keys, persistent storage, and networking options through [`values.yaml`](https://github.com/mauriceboe/TREK/blob/main/values.yaml) or command-line overrides.

## Add the TREK Helm Repository

The chart is hosted on GitHub Pages. Add the repository to your local Helm client and update the index:

```bash
helm repo add trek https://mauriceboe.github.io/TREK
helm repo update

```

## Install the Chart and Configure Secrets

A basic installation creates a Deployment, a ClusterIP Service on port **3000**, two PersistentVolumeClaims (`data` and `uploads`), and a Secret for sensitive environment variables. However, TREK requires an `ENCRYPTION_KEY` to function.

### Generate an Encryption Key Automatically

The recommended approach lets the chart generate a secure random key during installation. Set `generateEncryptionKey=true` to create a 32-character key stored in [`templates/secret.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/secret.yaml) that persists across upgrades:

```bash
helm install trek trek/trek --set generateEncryptionKey=true

```

### Supply Your Own Encryption Key

Alternatively, provide an explicit hex-encoded key via command line:

```bash
helm install trek trek/trek \
  --set secretEnv.ENCRYPTION_KEY=$(openssl rand -hex 32)

```

### Use an Existing Kubernetes Secret

For production environments, create a Secret manually and reference it during installation:

```bash
kubectl create secret generic trek-secrets \
  --from-literal=ENCRYPTION_KEY=$(openssl rand -hex 32)

helm install trek trek/trek --set existingSecret=trek-secrets

```

## Configure Admin Access and Networking

### Set Initial Admin Credentials

Configure the first-boot admin account by passing environment variables to the `secretEnv` configuration:

```bash
helm install trek trek/trek \
  --set secretEnv.ADMIN_EMAIL=admin@example.com \
  --set secretEnv.ADMIN_PASSWORD=$(openssl rand -base64 12)

```

These values are stored in the Kubernetes Secret defined in [`templates/secret.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/secret.yaml) and injected into the Deployment as environment variables.

### Expose TREK with LoadBalancer or NodePort

By default, the chart creates a ClusterIP service. For external access, change the service type:

```bash
helm install trek trek/trek --set service.type=LoadBalancer

```

The [`templates/service.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/service.yaml) exposes port **3000** and can be configured for `LoadBalancer` or `NodePort` access via [`values.yaml`](https://github.com/mauriceboe/TREK/blob/main/values.yaml).

### Enable Ingress for HTTPS and WebSockets

For production deployments requiring HTTPS and WebSocket support, enable the Ingress resource defined in [`templates/ingress.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/ingress.yaml). This template includes critical annotations for `proxy-read-timeout` and `proxy-body-size` to support TREK’s long-running WebSocket connections and large backup restores:

```bash
helm install trek trek/trek \
  --set ingress.enabled=true \
  --set ingress.hosts[0].host=trek.example.com \
  --set ingress.hosts[0].paths[0].path=/ \
  --set ingress.tls[0].secretName=trek-tls \
  --set ingress.tls[0].hosts[0]=trek.example.com

```

## Customize with Values Files

For complex configurations, define a custom [`values.yaml`](https://github.com/mauriceboe/TREK/blob/main/values.yaml) file. The following example specifies a custom image, enables LoadBalancer service, and configures Ingress:

```yaml

# my-values.yaml

image:
  repository: myregistry/trek
  tag: v3.2.0

service:
  type: LoadBalancer

ingress:
  enabled: true
  hosts:
    - host: trek.mycompany.com
      paths:
        - /
  tls:
    - secretName: trek-tls
      hosts:
        - trek.mycompany.com

```

Apply the configuration:

```bash
helm install trek trek/trek -f my-values.yaml

```

All default values are documented in [`charts/trek/values.yaml`](https://github.com/mauriceboe/TREK/blob/main/charts/trek/values.yaml), which configures the container image, resource limits, persistence settings (1 Gi PVCs by default), and feature flags.

## Upgrade TREK

Upgrade the release to the latest chart version while preserving the generated encryption key and PVC data:

```bash
helm repo update
helm upgrade trek trek/trek

```

The [`templates/deployment.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/deployment.yaml) mounts the existing PersistentVolumeClaims (`data` and `uploads`) and references the existing Secret, ensuring data persistence across version updates.

## Summary

- The TREK Helm chart in `charts/trek/` deploys a complete application stack including a Deployment, Service, PVCs, and optional Ingress.
- You must provide an `ENCRYPTION_KEY` via `generateEncryptionKey=true`, explicit `--set` values, or an existing Secret.
- The [`templates/deployment.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/deployment.yaml) injects configuration from a ConfigMap (`env`) and Secret (`secretEnv`) as environment variables.
- Enable Ingress in [`templates/ingress.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/ingress.yaml) for WebSocket-aware HTTPS termination with proper timeout annotations.
- Data persists across upgrades via the `data` and `uploads` PersistentVolumeClaims mounted by the Deployment.

## Frequently Asked Questions

### What Kubernetes resources does the TREK Helm chart create?

The chart creates a Deployment ([`templates/deployment.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/deployment.yaml)), a Service ([`templates/service.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/service.yaml)), two PersistentVolumeClaims for `data` and `uploads`, and a Secret ([`templates/secret.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/secret.yaml)). Optionally, it creates an Ingress ([`templates/ingress.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/ingress.yaml)) and a ConfigMap for non-sensitive environment variables. All resources are defined in [`charts/trek/Chart.yaml`](https://github.com/mauriceboe/TREK/blob/main/charts/trek/Chart.yaml) and the corresponding template files.

### How do I handle the encryption key during upgrades?

If you used `generateEncryptionKey=true` during initial installation, the chart stores the key in the Kubernetes Secret and preserves it across `helm upgrade` operations. The upgrade command retrieves the existing Secret and maintains the same PVCs, ensuring TREK can continue to decrypt existing data without manual intervention.

### Can I deploy TREK without an Ingress?

Yes. The default configuration uses a ClusterIP service suitable for internal-only access or port-forwarding. You can change `service.type` to `LoadBalancer` or `NodePort` in [`values.yaml`](https://github.com/mauriceboe/TREK/blob/main/values.yaml) to expose TREK externally without configuring Ingress, though Ingress is recommended for production HTTPS and WebSocket support.

### How is data persistence handled in the TREK Helm chart?

The [`templates/deployment.yaml`](https://github.com/mauriceboe/TREK/blob/main/templates/deployment.yaml) mounts two PersistentVolumeClaims named `data` and `uploads` to store application data and file uploads respectively. By default, these request 1 Gi of storage each. These PVCs are retained during upgrades and can be backed up or migrated independently of the application pods.