Skip to content

GliaX/helm-mattermost

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mattermost Helm Chart

Operator-based Helm chart for deploying Mattermost Enterprise Edition on Kubernetes with Redis caching and VPN sidecar support.

Features

  • Operator-based deployment using Mattermost CRD (installation.mattermost.com/v1beta1)
  • In-cluster Redis via Bitnami subchart for cluster caching
  • OpenVPN sidecar for internal network access with split-tunnel routing
  • TLS via cert-manager with automatic certificate management
  • GitHub Actions CI/CD with automated health checks and rollback

Prerequisites

  • Kubernetes 1.21+
  • Helm 3.x
  • Mattermost Operator installed in the cluster
  • cert-manager with a ClusterIssuer (e.g., letsencrypt-prod)
  • nginx ingress controller

Required Secrets (pre-existing)

Create these secrets in the target namespace before deploying:

Secret Keys Description
mysql-connection DB_CONNECTION_STRING PostgreSQL/MySQL connection string
s3-access-key accesskey, secretkey S3-compatible storage credentials
mattermost-license license Mattermost Enterprise license
openvpn-config config.ovpn OpenVPN client configuration file
openvpn-credentials username, password OpenVPN authentication

Create VPN Secrets

# OpenVPN configuration
kubectl -n mattermost create secret generic openvpn-config \
  --from-file=config.ovpn=/path/to/your/client.ovpn

# OpenVPN credentials
kubectl -n mattermost create secret generic openvpn-credentials \
  --from-literal=username='YOUR_VPN_USERNAME' \
  --from-literal=password='YOUR_VPN_PASSWORD'

Create Database Secret

kubectl -n mattermost create secret generic mysql-connection \
  --from-literal=DB_CONNECTION_STRING='postgres://user:pass@host:5432/dbname?sslmode=require'

Create S3 Secret

kubectl -n mattermost create secret generic s3-access-key \
  --from-literal=accesskey='YOUR_ACCESS_KEY' \
  --from-literal=secretkey='YOUR_SECRET_KEY'

Create License Secret

kubectl -n mattermost create secret generic mattermost-license \
  --from-file=license=/path/to/license.mattermost-license

Installation

Quick Start

# Update dependencies
helm dependency update ./charts/mattermost

# Install
helm upgrade --install mattermost ./charts/mattermost \
  --namespace mattermost \
  --timeout 5m \
  --atomic

Dry-run (validate templates)

helm install mattermost ./charts/mattermost \
  --namespace mattermost \
  --dry-run --debug

Template rendering

helm template mattermost ./charts/mattermost \
  --namespace mattermost \
  > rendered.yaml

Configuration

Key Configuration Options

Parameter Description Default
mattermost.version Mattermost version 11.1.1
mattermost.image Docker image mattermost/mattermost-enterprise-edition
mattermost.replicas Number of replicas 2
mattermost.size Size preset 5000users
mattermost.database.secret Database secret name mysql-connection
mattermost.fileStore.bucket S3 bucket name glia-group
mattermost.fileStore.url S3 endpoint nyc3.digitaloceanspaces.com
mattermost.fileStore.secret S3 credentials secret s3-access-key
mattermost.licenseSecret License secret name mattermost-license
redis.enabled Enable Redis subchart true
vpn.enabled Enable VPN sidecar true
vpn.routes CIDR ranges to route via VPN ["192.168.1.0/24"]
ingress.enabled Enable ingress true
ingress.host Primary hostname group.glia.org
redirectIngress.enabled Enable redirect ingress true
redirectIngress.host Redirect hostname group.emlondon.ca

Full values.yaml

mattermost:
  version: "11.1.1"
  image: mattermost/mattermost-enterprise-edition
  imagePullPolicy: IfNotPresent
  replicas: 2
  size: 5000users

  database:
    secret: mysql-connection

  fileStore:
    bucket: glia-group
    url: nyc3.digitaloceanspaces.com
    secret: s3-access-key

  licenseSecret: mattermost-license

  env:
    - name: MM_FILESETTINGS_AMAZONS3SSE
      value: "true"
    - name: MM_FILESETTINGS_AMAZONS3SSL
      value: "true"
    - name: MM_SERVICESETTINGS_ENABLEAPIUSERDELETION
      value: "true"
    - name: MM_LDAPSERVER
      value: auth.emlondon.ca

  dnsConfig:
    nameservers:
      - 8.8.8.8

  resources:
    limits:
      cpu: 4
      memory: 8Gi
    requests:
      cpu: 500m
      memory: 500Mi

redis:
  enabled: true
  auth:
    enabled: true
  master:
    persistence:
      enabled: false

vpn:
  enabled: true
  image: ghcr.io/wrmilling/openvpn-client:latest
  configSecret: openvpn-config
  credentialsSecret: openvpn-credentials
  routes:
    - 192.168.1.0/24

ingress:
  enabled: true
  host: group.glia.org
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    kubernetes.io/ingress.class: nginx
  tlsSecret: mm-glia

redirectIngress:
  enabled: true
  host: group.emlondon.ca
  target: https://group.glia.org$request_uri
  tlsSecret: mm-redirect-emlondon-tls

crdName: mm-glia

Architecture

┌──────────────────────────────────────────────────────────────────┐
│                       Kubernetes Cluster                         │
│  Namespace: mattermost                                           │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │                     mm-glia Pod                              ││
│  │  ┌─────────────────┐  ┌─────────────────┐                  ││
│  │  │   mattermost    │  │  openvpn-client │                  ││
│  │  │   :8065 (app)   │  │    (tun0)       │                  ││
│  │  │   :8067 (metrics)│  │ 192.168.1.x→VPN│                  ││
│  │  │                 │  │  others→default │                  ││
│  │  └────────┬────────┘  └─────────────────┘                  ││
│  │           │ shared netns                                     ││
│  └───────────┼─────────────────────────────────────────────────┘│
│              │                                                    │
│  ┌───────────▼───────────┐    ┌─────────────────────────────┐   │
│  │    mm-glia Service    │    │      Redis Master           │   │
│  │    ClusterIP: None    │    │      :6379                  │   │
│  │    8065, 8067         │    │      (cluster cache)        │   │
│  └───────────┬───────────┘    └─────────────────────────────┘   │
│              │                                                    │
│  ┌───────────▼───────────┐                                       │
│  │       Ingress         │                                       │
│  │  group.glia.org       │                                       │
│  │  group.emlondon.ca →  │                                       │
│  │    redirect to glia   │                                       │
│  └───────────────────────┘                                       │
└──────────────────────────────────────────────────────────────────┘

GitHub Actions CI/CD

Setup

  1. Add a repository secret named KUBE_CONFIG containing a base64-encoded kubeconfig:
kubectl config view --raw --minify | base64 -w 0
  1. The workflow automatically:
    • Lints the Helm chart on PRs
    • Deploys on push to main
    • Waits for Mattermost CR to reach stable state
    • Rolls back on failure

Workflow Triggers

  • Push to main: Automatic deployment
  • Pull request: Lint only (no deployment)
  • Manual dispatch: Deploy via GitHub UI

Workflow Steps

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Lint      │ ──▶ │   Deploy    │ ──▶ │ Health Check│
└─────────────┘     └─────────────┘     └──────┬──────┘
                                               │
                                    ┌──────────▼──────────┐
                                    │  Success │ Rollback │
                                    └─────────────────────┘

Verification

Check deployment status

# Mattermost CR status
kubectl get mattermost -n mattermost

# Pod status
kubectl get pods -n mattermost -l "installation.mattermost.com/installation=mm-glia"

# Redis status
kubectl get pods -n mattermost -l "app.kubernetes.io/name=redis"

View logs

# Mattermost logs
kubectl logs -n mattermost -l "installation.mattermost.com/installation=mm-glia" -c mattermost -f

# VPN sidecar logs
kubectl logs -n mattermost -l "installation.mattermost.com/installation=mm-glia" -c openvpn-client -f

Test connectivity

# Port forward for local testing
kubectl port-forward -n mattermost svc/mm-glia 8065:8065

# Access at http://localhost:8065

Troubleshooting

Mattermost CR not reaching stable state

# Check CR events
kubectl describe mattermost mm-glia -n mattermost

# Check operator logs
kubectl logs -n mattermost -l "app=mattermost-operator" -f

VPN not working

# Check VPN sidecar logs
kubectl logs -n mattermost -l "installation.mattermost.com/installation=mm-glia" -c openvpn-client

# Verify secrets exist
kubectl get secrets -n mattermost openvpn-config openvpn-credentials

Redis connection issues

# Verify Redis is running
kubectl get pods -n mattermost -l "app.kubernetes.io/name=redis"

# Check Redis logs
kubectl logs -n mattermost -l "app.kubernetes.io/component=master" -f

# Test Redis connection from Mattermost pod
kubectl exec -n mattermost deployment/mm-glia -c mattermost -- \
  nc -zv mm-glia-redis-master 6379

Upgrading

# Update dependencies
helm dependency update ./charts/mattermost

# Upgrade
helm upgrade mattermost ./charts/mattermost \
  --namespace mattermost \
  --timeout 5m \
  --atomic

Uninstallation

helm uninstall mattermost --namespace mattermost

Note: This will not delete the pre-existing secrets or PVCs created by the operator.

License

This chart is provided as-is. Mattermost Enterprise requires a valid license.

About

Operator-based Helm chart for deploying Mattermost Enterprise Edition on Kubernetes with Redis caching and VPN sidecar support

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors