Install Mattermost on Kubernetes

plans-img Available on all plans

deployment-img self-hosted deployments

You can install and deploy a production-ready Mattermost system on a Kubernetes cluster using the Mattermost Kubernetes Operator in practically any environment with less IT overhead and more automation.

You’ll need a Kubernetes cluster running a version that is currently supported with patch releases, Kubernetes CLI kubectl installed on local machine, and a basic understanding of Kubernetes concepts (such as deployments, pods) and actions (such as applying manifests, viewing pod logs). Running Mattermost in Kubernetes requires resources based on your total number of users. See the Mattermost Kubernetes Operator documentation to learn more about the minimum Kubernetes cluster resources Mattermost requires at different scales.

Tip

Install the operators

Nginx Ingress Controller

See the Kubernetes deployment documentation for details on installing the NGINX ingress controller in your Kubernetes cluster.

Mattermost Operator

There are multiple ways to install the Mattermost Kubernetes Operator. We recommend deploying with Helm, but installation instructions via the Kubernetes CLI can also be found below.

With Helm

  1. Install Helm. We recommend Helm v3.13.0 or later. For installation instructions, see the Helm quickstart documentation.

  2. Once Helm is installed and initialized, run the following:

helm repo add mattermost https://helm.mattermost.com
  1. Create a file named config.yaml, then copy and paste the content of the Mattermost operator file into it.

  2. Create a namespace for the Mattermost Operator:

kubectl create ns mattermost-operator
  1. Install your preferred version of the Mattermost Operator using the following command:

helm install <your-release-name> mattermost/mattermost-operator -n <namespace_name>

For example:

helm install mattermost-operator mattermost/mattermost-operator -n mattermost-operator

To install with any customized configuration you’ve made in your config.yaml file, use the -f flag:

helm install mattermost-operator mattermost/mattermost-operator -n mattermost-operator -f config.yaml

Tip

If no version is specified, the latest version of the Mattermost Operator will be installed.

With Kubernetes CLI

kubectl can be used to install the Mattermost Operator if using helm is not an option.

  1. Create a namespace for the Mattermost Operator:

kubectl create ns mattermost-operator
  1. Install the Mattermost Operator:

kubectl apply -n mattermost-operator -f https://raw.githubusercontent.com/mattermost/mattermost-operator/master/docs/mattermost-operator/mattermost-operator.yaml

Deploy Mattermost

  1. (Mattermost Enterprise only) Create a Mattermost license secret by opening a text editor and creating a secret manifest containing the Mattermost license. Replace [LICENSE_FILE_CONTENTS] below with the contents of your Mattermost license file. Save the file as mattermost-license-secret.yaml.

apiVersion: v1
kind: Secret
metadata:
  name: my-mattermost-license
type: Opaque
stringData:
  license: <LICENSE_FILE_CONTENTS>
  1. Create an installation manifest file mattermost-installation.yaml locally, and open it with a text editor. Copy and paste the YAML structure below, and make any necessary adjustments for your configuration and environment.

  apiVersion: installation.mattermost.com/v1beta1
  kind: Mattermost
  metadata:
    name: <INSTALLATION_NAME_HERE>                # Chose the desired installation name. Example = mm-example-full
  spec:
    size: <SIZE_VALUE_HERE>                       # Adjust to your requirements. Example = 5000users
    ingress:
      enabled: true
      host: <FULL_DOMAIN_NAME_HERE>               # Adjust to your domain. Example = example.mattermost-example.com
      annotations:
        kubernetes.io/ingress.class: nginx
    version: <VERSION_HERE>                       # Select a recent supported version of Mattermost. Example = 9.3.0
    licenseSecret: ""                             # If you created a license secret in step 1, put the secret name here

Note

While file names are provided, your file names can be different. The file names in this tutorial are used for clarity and organization.

Some of the most commonly-used fields include:

Field

Description

metadata.name

The name of your Mattermost as it will be shown in Kubernetes. The shorter the better.

spec.size

The size of your installation. This can be ‘100users’, ‘1000users, ‘5000users’, ‘10000users’, or ‘25000users’.

spec.ingress.host

The DNS for your Mattermost installation.

spec.version

The Mattermost version. Refer to the version archive page when selecting a Mattermost version.

spec.licenseSecret

The name of the Kubernetes secret containing your license (e.g., mattermost-license). Required for Enterprise deployments.

spec.mattermostEnv

List of custom environment variables for the Mattermost instance. Only required when tweaking Mattermost configuration is required.

spec.image

Docker image for the Mattermost app servers.

spec.imagePullPolicy

Image Pull policy used by Mattermost deployment.

spec.useServiceLoadBalancer

Set to true to use AWS or Azure load balancers instead of an NGINX controller.

spec.serviceAnnotations

Service annotations to use with AWS or Azure load balancers.

spec.ingress.enabled

Indicates if Ingress should be created by Mattermost Operator.

spec.ingress.annotations

Custom annotations propagated to Ingress resource.

spec.ingress.tlsSecret

Name of a Secret that contains TLS certificates for the ingress.

spec.database.external.secret

Name of a Kubernetes secret containing connection string to an external database.

spec.fileStore.external.url

External File Storage URL.

spec.fileStore.external.bucket

File Storage bucket name.

spec.fileStore.external.secret

Name of a Kubernetes secret that contains credentials to external file storage.

spec.elasticSearch.host

Elasticsearch hostname.

spec.elasticSearch.username

Username to log into Elasticsearch.

spec.elasticSearch.password

Password to log into Elasticsearch.

spec.scheduling.resources

Resource requests and limits of pod and container (Kubernetes).

spec.scheduling.nodeSelector

Node selector for assigning pods to nodes (Kubernetes).

spec.scheduling.affinity

Affinity and anti-affinity for assigning pods to nodes (Kubernetes).

More information on these additional fields can be found in this example. If you have previous experience with Kubernetes Custom Resources, you can also check the Custom Resource Definition.

  1. Create a file mattermost-database-secret.yaml to house secrets related to your installation’s database. The database secret needs to be created in the namespace that will hold the Mattermost installation. The secret should contain the following data:

apiVersion: v1
data:
  DB_CONNECTION_CHECK_URL: <DB_CONNECTION_CHECK_URL>
  DB_CONNECTION_STRING: <DB_CONNECTION_STRING>
  MM_SQLSETTINGS_DATASOURCEREPLICAS: <MM_SQLSETTINGS_DATASOURCEREPLICAS>
kind: Secret
metadata:
  name: my-postgres-connection
type: Opaque

Key

Description

Required

DB_CONNECTION_STRING

Connection string to the database.

Yes

MM_SQLSETTINGS_DATASOURCEREPLICAS

Connection string to read replicas of the database.

No

DB_CONNECTION_CHECK_URL

The URL used for checking that the database is accessible.

No

Here’s an example of a secret for AWS Aurora with PostgreSQL:

apiVersion: v1
data:
  DB_CONNECTION_CHECK_URL: cG9zdGdyZXM6Ly91c2VyOnN1cGVyX3NlY3JldF9wYXNzd29yZEBteS1kYXRhYmFzZS5jbHVzdGVyLWFiY2QudXMtZWFzdC0xLnJkcy5hbWF6b25hd3MuY29tOjU0MzIvbWF0dGVybW9zdD9jb25uZWN0X3RpbWVvdXQ9MTAK
  DB_CONNECTION_STRING: cG9zdGdyZXM6Ly91c2VyOnN1cGVyX3NlY3JldF9wYXNzd29yZEBteS1kYXRhYmFzZS5jbHVzdGVyLWFiY2QudXMtZWFzdC0xLnJkcy5hbWF6b25hd3MuY29tOjU0MzIvbWF0dGVybW9zdD9jb25uZWN0X3RpbWVvdXQ9MTAK
  MM_SQLSETTINGS_DATASOURCEREPLICAS: cG9zdGdyZXM6Ly91c2VyOnN1cGVyX3NlY3JldF9wYXNzd29yZEBteS1kYXRhYmFzZS5jbHVzdGVyLXJvLWFiY2QudXMtZWFzdC0xLnJkcy5hbWF6b25hd3MuY29tOjU0MzIvbWF0dGVybW9zdD9jb25uZWN0X3RpbWVvdXQ9MTAK
kind: Secret
metadata:
  name: my-postgres-connection
type: Opaque

Note

For PostgreSQL databases, the connection is checked with pg_isready so the DB_CONNECTION_CHECK_URL is the same as connection string.

  1. Create a file mattermost-filestore-secret.yaml to house secrets related to your installation’s filestore. The filestore secret needs to be created in the namespace that will hold the Mattermost installation. The secret should contain the following data:

apiVersion: v1
data:
  accesskey: <accesskey>
  secretkey: <secretkey>
kind: Secret
metadata:
  name: <name>
type: Opaque

Key

Description

Required

accesskey

Filestore access key.

Yes

secretkey

Filestore secret key.

Yes

metadata.name

The name of the secret.

Yes

Here’s an example of a secret for Amazon S3:

apiVersion: v1
data:
  accesskey: QUNDRVNTX0tFWQo=
  secretkey: U1VQRVJfU0VDUkVUX0tFWQo=
kind: Secret
metadata:
  name: my-s3-iam-access-key
type: Opaque
  1. Adjust installation manifest.

Tip

For more information on where in the YAML structure to make the below updates, reference the supported fields in step 2.

In order for the Mattermost Operator to utilize your external database, you must modify the Mattermost manifest (inside the mattermost-installation.yaml file) by adding the following fields:

spec:
...
  database:
    external:
      secret: <secret name> # The name of the secret containing the database connection string. You set this value in step 3. Example = my-postgres-connection

Now, point the Mattermost Operator at your external filestore. Modify the Mattermost manifest (inside the mattermost-installation.yaml file) by adding the following fields:

spec:
...
  fileStore:
    external:
      url: s3.amazonaws.com
      bucket: my-s3-bucket
      secret: <secret name> # The name of the secret containing the filestore access and secret keys. You set this value in step 4. Example = my-s3-iam-access-key

Additionally when using Amazon S3, set the MM_FILESETTINGS_AMAZONS3SSE and MM_FILESETTINGS_AMAZONS3SSL environment variables to true:

spec:
...
  mattermostEnv:
    ...
    - name: MM_FILESETTINGS_AMAZONS3SSE
      value: "true"
    - name: MM_FILESETTINGS_AMAZONS3SSL
      value: "true"

If you’ve configured your Mattermost Enterprise Edition installation manifest with a custom PostgreSQL database, and an Amazon S3 filestore, your installation manifest should look something like this:

apiVersion: installation.mattermost.com/v1beta1
kind: Mattermost
metadata:
  name: mm-example-external-db
spec:
  size: 5000users
  ingress:
    enabled: true
    host: example.mattermost-example.com
    annotations:
      kubernetes.io/ingress.class: nginx
  version: 9.3.0
  licenseSecret: my-mattermost-license
  database:
    external:
      secret: my-postgres-connection
  fileStore:
    external:
      url: s3.amazonaws.com
      bucket: my-s3-bucket
      secret: my-s3-iam-access-key
  mattermostEnv:
  - name: MM_FILESETTINGS_AMAZONS3SSE
    value: "true"
  - name: MM_FILESETTINGS_AMAZONS3SSL
    value: "true"
  1. Apply the installation manifest file. Manifests are applied with kubectl. Before running the commands make sure you are connected to your Kubernetes cluster.

  1. Create a namespace for this new Mattermost installation:

kubectl create ns mattermost
  1. (Mattermost Enterprise only) apply the license file by specifying the path to the file you created in step 1:

kubectl apply -n mattermost -f [PATH_TO_LICENCE_SECRET_MANIFEST]
  1. Apply the installation file by specifying the path to the file you created in step 2:

kubectl apply -n mattermost -f [PATH_TO_MATTERMOST_MANIFEST]

The deployment process can be monitored in the Kubernetes user interface or in command line by running:

kubectl -n mattermost get mm -w

The installation should be deployed successfully, when the Custom Resource reaches the stable state.

  1. Configure DNS and use Mattermost.

  1. When the deployment is complete, obtain the hostname or IP address of your Mattermost deployment using the following command:

kubectl -n mattermost get ingress
  1. Copy the resulting hostname or IP address from the ADDRESS column, open your browser, and connect to Mattermost.

  2. Use your domain registration service to create a canonical name or IP address record for the ingress.host in your manifest, pointing to the address you just copied. For example, on AWS you would do this within a hosted zone in Route53.

  3. Navigate to the ingress.host URL in your browser and use Mattermost.

Note

If you just want to try it out on your local machine without configuring the domain, run the following command, and then navigate to http://localhost:8065.

kubectl -n mattermost port-forward svc/[YOUR_MATTERMOST_NAME] 8065:8065

Frequently asked questions

What’s the difference between the Mattermost Operator and Helm Charts?

The Mattermost Operator is a self-contained set of application/product-specific instructions that runs inside Kubernetes and facilitates application management and deployment.

Helm is a tool used to deploy Kubernetes manifests to a cluster, but does not facilitate application management.

We provide a helm chart that can be used to to install the Mattermost Operator.

Does the Mattermost Operator replace the Mattermost Helm Chart?

Although the Mattermost Operator is the recommended deployment option for running Mattermost in Kubernetes, a helm chart for directly deploying Mattermost resources is still available.

What database and filestore should I use for Mattermost?

Always refer to the Mattermost server documentation for what databases and filestores are supported.

The following documentation on scaling for enterprise is a good place to start.

What are the Operator-Managed database and filestore options?

The Mattermost Operator provides an option to directly provision a database and filestore for a Mattermost installation to use, but this option is only meant for validation and testing. These options rely on specific releases of operators that we don’t maintain. For production deployments of Mattermost, one of the other database and filestore configuration options should be chosen.

In particular, the Operator-Managed database option relies on a MySQL operator and MySQL databases are now deprecated in Mattermost.

Note that you can choose to manage your Mattermost database and filestore in Kubernetes with other operators, but these should be provisioned separately first and then connected to the Mattermost installation as external backends.

Can you use blue-green deployments with different database schemas?

Currently this is not supported as it introduces the possibility of missing a data entry in the database.

Are environment variables supported?

Yes. However, config.json file settings will be overridden if the $MM_SQLSETTINGS_DATASOURCE environment variable is set. See the Environment Variables configuration settings documentation for details.

Issues configuring login with SAML on Kubernetes

For some SAML authentication configurations, 502 status code response can appear during login attempts due to requests being too large. This can be caused by the default proxy-buffer-size setting for NGINX Ingress being too low. To fix this issue, configure an appropriate buffer size (8k or 16k should be sufficient for most cases) with NGINX annotation by adding it to the Mattermost manifest under spec.ingressAnnotations:

...
spec:
...
  ingress:
  ...
    annotations:
      nginx.ingress.kubernetes.io/proxy-buffer-size: 16k
...

Use caution when changing the buffer size as it may slightly impact NGINX performance. Exact values are machine-dependent.