snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-16 00:29:55 +05:00
commit 240db4e2a7
15309 changed files with 2173406 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
---
title: "Configure for Air-Gapped Operation"
sidebar_position: 3
description: Server settings that depend on internet access and should be disabled or adjusted for an air-gapped deployment.
---
<EditionAvailability tiers="free,professional,enterprise,enterprise-advanced" />
<DeploymentAvailability modes="self-hosted,air-gapped" />
After successful deployment, you'll need to configure Mattermost for air-gapped operation. The following sections describe features that rely on internet access and offer recommendations for settings.
## Mobile push notifications
Mattermost can use mobile push notifications to notify users of new messages and activity. These notifications require a server component to be deployed to send the notifications to mobile devices. By default, Mattermost uses the public push notification service, which isn't available in an air-gapped environment. We recommend disabling push notifications in **System Console > Environment > [Push Notification Server](/administration-guide/configure/environment-configuration-settings#push-notification-server)**.
## Email
Unless you've set up an internal air-gapped email service, we recommend disabling email invitations and email verification from **System Console > Authentication > Signup**.
## Website link previews
Website link previews require a connection to the internet to fetch the content of the links. We recommend [disabling website link previews](/administration-guide/configure/site-configuration-settings#enable-website-link-previews) in **System Console > Site Configuration > Posts**.
## GIF picker
The GIF picker relies on a third-party service which has a dependency on external internet access. You can disable it in **System Console > Integrations > GIF**.
## Notices
[In-product notices](/administration-guide/manage/in-product-notices) require internet access to periodically inform administrators and end users of new product improvements, features, and releases. You can disable notices in **System Console > Site Configuration > Notices**.
## Telemetry
To avoid log errors, we recommend disabling [telemetry-related features](/administration-guide/manage/telemetry), including the security update check, and error and diagnostics reporting features.

View File

@@ -0,0 +1,25 @@
---
title: "Air-Gapped Operations"
description: Deploy and operate Mattermost in a self-hosted air-gapped environment with no direct internet access.
---
<EditionAvailability tiers="free,professional,enterprise,enterprise-advanced" />
<DeploymentAvailability modes="self-hosted,air-gapped" />
An air-gapped environment is one that's isolated from the public internet, requiring all necessary components to be available locally. This section outlines what you'll need to deploy and operate Mattermost in a self-hosted air-gapped environment — preparation, deployment guidance, and the configuration changes required for a successful deployment.
Deploying Mattermost in an air-gapped environment requires preparing all necessary software, container images, and configuration resources in advance, since the target system has no direct internet access; transferring these artifacts to the isolated network using secure media; and then installing, configuring, and validating the deployment within the air-gapped environment.
<Tip>
Consider [talking to a Mattermost expert](https://mattermost.com/contact-sales/) if your organization needs support deploying Mattermost and supporting services in an air-gapped environment.
</Tip>
## In this section
- [Air-gapped deployment runbook](/deployment-guide/air-gapped-operations/quick-start-runbook) — the high-level steps to prepare for and complete an air-gapped install.
- [Bill of Materials and Registry Mirroring](/deployment-guide/air-gapped-operations/mirror-package-repositories) — what to gather before you cross the air gap, and how to set up a private package mirror or container registry.
- [Configure for Air-Gapped Operation](/deployment-guide/air-gapped-operations/disable-phone-home-features) — server settings that depend on internet access and should be disabled or adjusted.
For the architectural context — when an organization needs an air gap, and which Mattermost capabilities it rules out — see the [Deploy in Air-Gapped Environments](/deployment-guide/deployment-scenarios/air-gapped-deployment) deployment scenario.

View File

@@ -0,0 +1,391 @@
---
title: "Bill of Materials and Registry Mirroring"
sidebar_position: 2
description: Gather the packages, images, and certificates you need before crossing the air gap, and set up a private registry or package mirror.
---
import Tabs from '@theme/Tabs';
<EditionAvailability tiers="free,professional,enterprise,enterprise-advanced" />
<DeploymentAvailability modes="self-hosted,air-gapped" />
On an internet-connected machine, you must gather all required packages, container images, and dependencies needed for the installation process. The resources you'll need will depend on your deployment method.
## Bill of materials
<Tabs>
<TabItem value="linux" label="Linux">
Using our provided tarball is recommended as the simplest installation method for air-gapped environments. You can install the Mattermost Server in a few minutes on any air-gapped 64-bit Linux system.
**Prerequisites**
- [Mattermost tarball](/product-overview/version-archive). We recommend using the latest [ESR](/product-overview/release-policy#extended-support-releases) for extended support where server upgrades may be infrequent.
- Database: PostgreSQL [installation packages](https://www.postgresql.org/download/) or container images for your Linux distribution.
- File Storage: Local filesystem storage is sufficient for deployments under 2,000 users. For larger deployments requiring high availability, we recommend using an S3-compatible object storage solution or an NFS (Network File System) server for shared storage needs.
- Load balancer: If you already have a load balancer running in your air-gapped environment you can skip this resource, otherwise we recommend deploying [NGINX](/deployment-guide/server/setup-nginx-proxy) from these [Linux packages](https://nginx.org/en/linux_packages.html).
- Desktop app: Download the [required package](https://github.com/mattermost/desktop/releases) based on your deployment method.
**(Optional) Supporting services**
Consider downloading these additional resources if you plan to enable these optional components:
- [Mattermost Calls](/deployment-guide/calls/calls-deployment-guide): [mattermost-calls-offloader](https://github.com/mattermost/calls-offloader/releases) (required for recording, transcription, and live captions) and [mattermost-rtcd](https://github.com/mattermost/rtcd/releases) (required for performance and scalability).
- [Elasticsearch](https://www.elastic.co/downloads/elasticsearch) can be [deployed](https://www.elastic.co/docs/deploy-manage/deploy/self-managed/installing-elasticsearch) for enhanced search performance at scale.
- [Prometheus](https://prometheus.io/download/) and [Grafana](https://grafana.com/grafana/download) for monitoring and observability.
</TabItem>
<TabItem value="kubernetes" label="Kubernetes">
Kubernetes is recommended for a highly scalable and robust deployment if your organization is already running a Kubernetes cluster in the air-gapped environment.
**Prerequisites**
- [Mattermost Operator](https://github.com/mattermost/mattermost-helm/tree/master/charts/mattermost-operator) and [values](https://github.com/mattermost/mattermost-helm/blob/master/charts/mattermost-operator/values.yaml).
- Database: We recommend options such as the [Postgres Operator](https://access.crunchydata.com/documentation/postgres-operator/latest/quickstart) from Crunchy Data, [CloudNativePG](https://cloudnative-pg.io/documentation/1.27/installation_upgrade/), or [pgEdge](https://github.com/pgEdge/pgedge-helm).
- File Storage: We recommend using an S3-compatible storage service or a mounted NFS volume for shared storage needs.
- Load balancer: If you already have a load balancer running in your air-gapped environment you can skip this resource, otherwise we recommend deploying [NGINX](/deployment-guide/server/setup-nginx-proxy), using the [NGINX Ingress Controller operator](https://docs.nginx.com/nginx-ingress-controller/installation/installing-nic/installation-with-operator/).
- Desktop app: Download the [required package](https://github.com/mattermost/desktop/releases) based on your deployment method.
**(Optional) Supporting services**
Consider downloading these additional resources if you plan to enable these optional components:
- [Mattermost Calls](/deployment-guide/calls/calls-deployment-guide) helm charts: [mattermost-calls-offloader](https://github.com/mattermost/mattermost-helm/tree/master/charts/mattermost-calls-offloader) and [values](https://github.com/mattermost/mattermost-helm/blob/master/charts/mattermost-calls-offloader/values.yaml) (required for recording, transcription, and live captions), [mattermost-rtcd](https://github.com/mattermost/mattermost-helm/tree/master/charts/mattermost-rtcd) and [values](https://github.com/mattermost/mattermost-helm/blob/master/charts/mattermost-rtcd/values.yaml) (required for performance and scalability).
- [Elasticsearch](https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s) can be [deployed in air-gapped k8s environments](https://www.elastic.co/guide/en/cloud-on-k8s/2.8/k8s-air-gapped.html) for enhanced search performance at scale.
- [Prometheus](https://github.com/prometheus-operator/prometheus-operator) and [Grafana](https://github.com/grafana/grafana-operator) operators for monitoring and observability.
</TabItem>
<TabItem value="docker" label="Docker">
Docker can be used if you don't have a running Kubernetes cluster in the air-gapped environment, but want to use containers for simplified installation and dependency management. Docker is not recommended for production environments at high scale, as it doesn't support clustered deployments or High Availability (HA) configurations out-of-the-box.
**Prerequisites**
- [Mattermost Enterprise Edition](https://hub.docker.com/r/mattermost/mattermost-enterprise-edition) image.
- Database: [PostgreSQL](https://hub.docker.com/_/postgres) image.
- Load balancer: If you already have a load balancer running in your air-gapped environment you can skip this resource, otherwise we recommend deploying [NGINX](/deployment-guide/server/setup-nginx-proxy) from these [images](https://hub.docker.com/_/nginx).
- Desktop app: Download the [required package](https://github.com/mattermost/desktop/releases) based on your deployment method.
**(Optional) Supporting services**
Consider downloading these additional resources if you plan to enable these optional components:
- [Mattermost Calls](/deployment-guide/calls/calls-deployment-guide) images: [calls-offloader](https://hub.docker.com/r/mattermost/calls-offloader) (required for recording, transcription, and live captions) and [rtcd](https://hub.docker.com/r/mattermost/rtcd) (required for performance and scalability).
- [Elasticsearch](https://hub.docker.com/_/elasticsearch) image for enhanced search performance at scale.
- [Prometheus](https://hub.docker.com/r/prom/prometheus) and [Grafana](https://hub.docker.com/r/grafana/grafana) images for monitoring and observability.
</TabItem>
</Tabs>
## Mattermost plugins
Mattermost includes a number of [pre-built integrations](/integrations-guide/popular-integrations) for mission-critical tools. If you'd like to use any plugins beyond those that are pre-built in the Mattermost package, you'll need to download the plugin binaries from the [Mattermost Marketplace](https://mattermost.com/marketplace/). Once you have Mattermost deployed, these plugin binaries can be uploaded directly in the System Console.
## SSL/TLS certificates and keys
If your deployment requires SSL, ensure you have the necessary certificates. This includes certificates and keys for enabling HTTPS with Mattermost, as well as any CA files or certificates needed to access internal services such as LDAP or SAML. See [Setup TLS](/deployment-guide/server/setup-tls) for configuration details.
## Local documentation
Mattermost documentation can be built and served locally so that installation and configuration guidance is available inside the air-gapped environment. Clone the [mattermost/mattermost repository](https://github.com/mattermost/mattermost) on your internet-connected machine, build the documentation site, and transfer the generated static output across the air gap alongside the rest of your bill of materials.
**Prerequisites**
- Git [\[download\]](https://git-scm.com/downloads)
- Node.js 20 or later [\[download\]](https://nodejs.org/en/download)
```bash
git clone https://github.com/mattermost/mattermost.git
cd mattermost/docs/site
npm ci
npm run build
```
The build writes a self-contained static site to `docs/site/build/`, which you can serve from any web server in the air-gapped environment. See the [documentation site README](https://github.com/mattermost/mattermost/blob/master/docs/site/README.md) for the full build options, including how to skip the API reference generation step if you don't need it.
## Set up a private registry or mirror
A private container registry securely stores the Docker images necessary for air-gapped deployments, ensuring compliance with data isolation requirements. Similarly, a private package mirror stores operating system packages necessary for air-gapped deployments in Ubuntu or RHEL/CentOS Linux environments. Setting up a local registry or mirror is a critical step in deploying Mattermost to ensure all images, dependencies, and packages are available to you in the air-gapped environment. The steps below outline the process required to set up a local registry or mirror, depending on the deployment method you are using. These steps are a rough guide, and can be supplemented with online resources depending on your specific deployment needs.
<Tabs>
<TabItem value="linux" label="Linux">
**(Ubuntu) Set up a private Debian package mirror**
We will use Aptly to create a local mirror, although you can also use other options such as debmirror.
1. **Install Aptly** (on an internet-connected machine):
```bash
apt-get update
apt-get install aptly gnupg
```
2. **Create a GPG key for signing packages**:
```bash
gpg --gen-key
```
3. **Create a mirror configuration**:
```bash
aptly mirror create -architectures=amd64 debian-bullseye http://deb.debian.org/debian bullseye main contrib non-free
```
4. **Update the mirror to download packages**:
```bash
aptly mirror update debian-bullseye
```
5. **Create and publish a snapshot**:
```bash
aptly snapshot create debian-bullseye-$(date +%Y%m%d) from mirror debian-bullseye
aptly publish snapshot debian-bullseye-$(date +%Y%m%d)
```
6. **Serve the repository**:
```bash
aptly serve
```
7. **Client configuration:** Configure apt to use your local mirror:
```bash
cat > /etc/apt/sources.list << EOF
deb http://mirror.example.com/debian bullseye main contrib non-free
EOF
```
**(RHEL/CentOS) Set up a private RHEL package mirror**
We will use reposync for a local mirror.
1. **Install required tools** (on an internet-connected RHEL system):
```bash
yum install yum-utils createrepo
```
2. **Download packages**:
```bash
mkdir -p /var/www/html/repos/rhel8
reposync -p /var/www/html/repos/rhel8 --download-metadata --repo=rhel-8-for-x86_64-baseos-rpms
reposync -p /var/www/html/repos/rhel8 --download-metadata --repo=rhel-8-for-x86_64-appstream-rpms
```
3. **Create repository metadata**:
```bash
createrepo /var/www/html/repos/rhel8/rhel-8-for-x86_64-baseos-rpms
createrepo /var/www/html/repos/rhel8/rhel-8-for-x86_64-appstream-rpms
```
4. **Set up a web server**:
```bash
yum install httpd
systemctl enable httpd
systemctl start httpd
```
5. **Client configuration:** Disable existing repositories:
```bash
cd /etc/yum.repos.d/
mkdir backup
mv *.repo backup/
```
6. **Client configuration:** Create new repository files:
```bash
cat > /etc/yum.repos.d/local-baseos.repo << EOF
[local-baseos]
name=Red Hat Enterprise Linux 8 BaseOS
baseurl=http://mirror.example.com/repos/rhel8/rhel-8-for-x86_64-baseos-rpms
enabled=1
gpgcheck=0
EOF
cat > /etc/yum.repos.d/local-appstream.repo << EOF
[local-appstream]
name=Red Hat Enterprise Linux 8 AppStream
baseurl=http://mirror.example.com/repos/rhel8/rhel-8-for-x86_64-appstream-rpms
enabled=1
gpgcheck=0
EOF
```
7. **Client configuration:** Clear cache and test:
```bash
yum clean all
yum repolist
```
</TabItem>
<TabItem value="kubernetes" label="Kubernetes">
**Set up a self-hosted private container registry**
1. **Install Docker Registry**:
```bash
docker run -d -p 5000:5000 --restart=always --name registry registry:2
```
2. **Configure persistent storage**:
```bash
docker run -d -p 5000:5000 --restart=always --name registry \
-v /mnt/registry:/var/lib/registry \
registry:2
```
3. **Add TLS security** (recommended):
a. Generate self-signed certificates:
```bash
mkdir -p certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt
```
b. Run the registry with TLS:
```bash
docker run -d -p 5000:5000 --restart=always --name registry \
-v /mnt/registry:/var/lib/registry \
-v $(pwd)/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
```
**Configure Kubernetes to use private image registries**
When using Kubernetes in an air-gapped environment, you need to configure it to use your private registry.
1. **Create a Kubernetes secret for registry authentication**:
```bash
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com:5000 \
--docker-username=your_username \
--docker-password=your_password \
--docker-email=your_email@example.com
```
2. **Reference the secret in pod specifications**:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mattermost-pod
spec:
containers:
- name: mattermost
image: registry.example.com:5000/mattermost/mattermost-enterprise-edition:latest
imagePullSecrets:
- name: regcred
```
3. **For Helm deployments**, specify the registry in `values.yaml`:
```yaml
image:
repository: registry.example.com:5000/mattermost/mattermost-enterprise-edition
tag: latest
pullPolicy: IfNotPresent
imagePullSecrets:
- name: regcred
```
</TabItem>
<TabItem value="docker" label="Docker">
**Set up a self-hosted private container registry**
1. **Install Docker Registry**:
```bash
docker run -d -p 5000:5000 --restart=always --name registry registry:2
```
2. **Configure persistent storage**:
```bash
docker run -d -p 5000:5000 --restart=always --name registry \
-v /mnt/registry:/var/lib/registry \
registry:2
```
3. **Add TLS security** (recommended):
a. Generate self-signed certificates:
```bash
mkdir -p certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt
```
b. Run the registry with TLS:
```bash
docker run -d -p 5000:5000 --restart=always --name registry \
-v /mnt/registry:/var/lib/registry \
-v $(pwd)/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
```
**Populate your private registry**
Ensure the required images from the [Bill of Materials](#bill-of-materials) are downloaded and pushed to the private registry.
**Configure Docker to use private image registries**
Configure Docker on all hosts to trust and use your private registry.
1. **Add your registry to Docker's trusted registries**:
Edit or create `/etc/docker/daemon.json`:
```json
{
"insecure-registries": ["registry.example.com:5000"]
}
```
For registries using self-signed certificates:
```bash
mkdir -p /etc/docker/certs.d/registry.example.com:5000
cp domain.crt /etc/docker/certs.d/registry.example.com:5000/ca.crt
```
2. **Restart Docker daemon**:
```bash
systemctl restart docker
```
3. **Test the configuration**:
```bash
docker pull registry.example.com:5000/mattermost/mattermost-enterprise-edition:latest
```
</TabItem>
</Tabs>

View File

@@ -0,0 +1,30 @@
---
title: Air-gapped deployment runbook
sidebar_position: 1
description: The high-level steps to prepare for and complete a self-hosted air-gapped Mattermost deployment.
---
<EditionAvailability tiers="free,professional,enterprise,enterprise-advanced" />
<DeploymentAvailability modes="self-hosted,air-gapped" />
This is a summary of the steps involved in deploying Mattermost in an air-gapped environment.
1. **Select your preferred Mattermost deployment option.** This step is often dictated by the infrastructure already running in your air-gapped environment. If you're deploying from scratch, review our [server deployment documentation](/deployment-guide/server/deploy-server#deployment-options) to select the optimal option given your organization's needs.
2. **Set up a private container registry or package mirror.** Ideally the air-gapped environment already has a private container registry or package mirror available. If not, see [Bill of Materials and Registry Mirroring](./mirror-package-repositories) for setup guidance.
3. **Prepare your Bill of Materials.** Depending on your deployment method, you'll need to download, tag, and push required materials into your private registry or mirror.
4. **Transfer materials into the air-gapped environment.** If the private registry cannot access the public internet, you can prepare an archive of the registry data on your internet-connected machine and securely transfer it using approved data transfer methods — for example, burning to a disk.
5. **Install Mattermost Server.** Once you have all the necessary resources in your air-gapped environment, you can move forward with deployment following the instructions for [Linux](/deployment-guide/server/deploy-linux), [Kubernetes](/deployment-guide/server/deploy-kubernetes), or [Docker](/deployment-guide/server/deploy-containers).
6. **Install Mattermost Desktop Apps.** Since air-gapped devices cannot access the publicly available app stores, you'll need to install the apps directly from the latest [packages available on our GitHub release page](https://github.com/mattermost/desktop/releases). You'll find [installation instructions](/deployment-guide/desktop/desktop-app-deployment) in our documentation based on your desired deployment method.
7. **Configure Mattermost for air-gapped operation.** See [Configure for Air-Gapped Operation](./disable-phone-home-features) for the settings that accommodate the lack of internet access.
<Tip>
Consider [talking to a Mattermost expert](https://mattermost.com/contact-sales/) if your organization needs support deploying Mattermost and supporting services in an air-gapped environment.
</Tip>

View File

@@ -0,0 +1,165 @@
---
title: "Application architecture"
---
import useBaseUrl from '@docusaurus/useBaseUrl';
Mattermost is an open-source collaboration platform that offers secure messaging, file sharing, and integrations for team communication. It's self-hosted, providing IT admins full control over data, security, integrations, and customization. The platform is built with modular components to ensure scalability, flexibility, and extensibility.
<img src={useBaseUrl('/images/network-diagram.svg')} class="bg-white" alt="Mattermost network diagram shows how the components can be deployed. Includes optional configurations for scaling for larger enterprise organizations." />
## Workflow overview
Users connect through various access points (web, mobile, desktop, email). Their requests are processed by the application layer (Mattermost Server), which manages API communications, authentication, notifications, and data workflows.
The backend infrastructure supports these operations by storing all data and files in well-architected storage systems.
Extendability and security layers ensure that the platform integrates seamlessly with enterprise systems while protecting sensitive data.
## Core components
The technical architecture revolves around 3 main layers: [Access layer](#access-layer), [Application layer](#application-layer), and [Backend infrastructure](#backend-infrastructure).
### Access layer
The Access Layer includes all the ways users interact with Mattermost, ensuring secure, scalable, and reliable communication across preferred platforms. High availability measures provide uninterrupted functionality for users, even in the face of server or network failures.
- **Web Interface**: Users can access Mattermost through a web browser (Chrome, Firefox, Safari, Edge). The web client communicates with the Mattermost server over HTTPS protocols. High availability for web interfaces can be achieved through load-balanced reverse proxies (e.g., NGINX or HAProxy) that distribute user traffic across multiple Mattermost server instances. Backup proxy servers can ensure failover scenarios to keep the web interface operational during outages.
- **Desktop and Mobile Apps**: Native apps for iOS, Android, macOS, Windows, and Linux provide seamless functionality across devices. These apps rely on secure APIs to interact with the server for real-time messaging and updates. High availability can be ensured by deploying redundant server clusters to handle API requests, along with failover mechanisms that automatically redirect traffic to healthy servers. Mobile apps also benefit from retry mechanisms and fallback services for push notifications to maintain real-time responsiveness.
- **Email Interaction**: Support for email clients like Outlook, Gmail, or Thunderbird enables integration of email notifications (e.g., new message alerts, invitations) into users' typical workflows. The Access Layer ensures that users are always connected via platforms of their choice while maintaining secure, synchronized communication paths. Email services can be configured with multiple SMTP servers for redundancy, ensuring that notifications are sent without delay even if a primary mail server becomes unavailable.
The Access Layer plays a critical role in ensuring that users are always connected via the platforms of their choice while maintaining secure, synchronized communication paths. With high availability measures in place, organizations can guarantee a seamless user experience, regardless of the scale or complexity of their deployment.
### Application layer
The Mattermost Server is the heart of the platform and responsible for processing all user and system operations. It's composed of multiple modular elements as follows:
<img src={useBaseUrl('/images/architecture_basics.png')} class="bg-white" alt="Mattermost architecture basics" />
**RESTful JSON Web Service**: Handles all incoming API requests (from web clients, apps, and integrations) and ensures that responses are formatted in JSON. Acts as the communication bridge between the clients (Access Layer) and backend systems. To ensure high availability, this layer can be distributed across multiple servers and load-balanced, preventing service disruptions due to high traffic or server failure.
**Authentication client**: Manages user authentication, ensuring secure login sessions. Integrates with traditional username/password-based authentication or enterprise-grade solutions like SSO (Single Sign-On) through Active Directory/LDAP. High availability is maintained through redundant authentication nodes and failover mechanisms, ensuring uninterrupted access even if a primary authentication service fails.
**Authentication Provider**: Provides pluggable authentication frameworks to support OAuth, SSO, and third-party identity services. Particularly important for enterprise environments with centralized identity management. Redundancy and failover strategies ensure reliability by distributing authentication frameworks across multiple servers and offering fallback options for seamless identity management.
**Notification Service**: Sends notifications through supported mediums:
- **Push Notifications**: Real-time notifications to iOS and Android devices (via a Push Notification Service). High availability is ensured through multiple notification servers and retry mechanisms, guaranteeing that notifications are delivered even in the event of service disruptions.
- **Email Notifications**: Delivered to users when they are offline or need event alerts. Load balancing and backup mail server configurations help ensure email delivery remains consistent and reliable.
**Data Management Service**: Responsible for managing message data, metadata, user profiles, and logs. Ensures the integrity of data passed between the database and the server. This layer serves as the operational core of the platform, orchestrating user activities with data handling and integration capabilities.
High availability is achieved through database replication, failover strategies, and distributed data handling mechanisms. These measures ensure uninterrupted access to data and protect against component failures or downtime. The Data Management Service serves as the operational core of the platform, orchestrating user activities with scalable and fault-tolerant data handling capabilities.
### Backend infrastructure
The backend infrastructure provides the storage and data handling capabilities required for Mattermost operations. It consists of the following components:
**Database Systems**: Mattermost uses PostgreSQL as its primary database (supports Amazon RDS for cloud-hosted PostgreSQL) to store all persistent data, such as:
- Messages
- User accounts and credentials
- Configuration settings
- Team/channel metadata
To ensure high availability, database systems can leverage clustering, replication, and failover mechanisms. PostgreSQL supports features like synchronous and asynchronous replication to create replicas for redundancy. Cloud-hosted solutions like Amazon RDS provide automatic failover and backup capabilities, ensuring continuous operation during system failures.
**File Storage**: Manages all multimedia assets (e.g., file uploads, images, videos) shared across channels. Storage solutions include the following options:
- **Local Storage**: Files stored directly on the server's filesystem. For high availability, redundancy can be achieved using RAID configurations or backups to recover from disk failures.
- **Network Attached Storage (NAS)**: Common for enterprises centralizing file storage within their network. NAS setups can include fault-tolerant configurations like distributed systems or replication for uninterrupted access.
- **S3**: Offers cloud-based scalable storage for larger environments or organizations with distributed deployments. The database and file storage handle scalability, ensuring efficient support for millions of messages and files while guaranteeing data consistency. S3 inherently supports high availability by distributing data across multiple availability zones, ensuring no single point of failure.
High availability measures ensure scalable and fail-safe support for millions of messages and files while guaranteeing data consistency.
**System Extensions**: Mattermost is not only a collaboration tool but also a platform designed for extensibility. Key extensibility features include:
**Self-Hosted Integrations**: Connect Mattermost to other local or cloud-based systems like Jira, GitLab, or any custom integrations your team needs. Leverage built-in APIs and webhooks to automate workflows and trigger system-to-system communications. For high availability, integrations can employ redundant communication channels and retry mechanisms to handle transient failures gracefully.
**Third-Party Authentication**: Bind integrations to third-party platforms (e.g., Slack-importing APIs, OAuth services). Third-party identity services ensure consistent and secure user access flows. Third-party identity services can leverage load-balancing and failover strategies to ensure consistent and secure user access flows, even under high traffic or outages.
**Security and Scalability Features**: Security and scalability are baked into the architecture, making Mattermost ideal for enterprise use cases:
**Security**
- A reverse proxy like NGINX or a hardware proxy is deployed to manage external traffic. It protects servers, enforces HTTPS, and handles load balancing.
- Configurable SSL/TLS encryption ensures data security during transmission.
- Granular user permissions and roles secure sensitive information within teams.
**Scalability and High Availability**: The Enterprise Edition supports deploying multiple Mattermost servers in a clustered environment to balance user requests across multiple servers for reliability and performance in large organizations. Clustering ensures automatic failover so that user traffic is shifted to functioning servers in case of outages.
**Notifications and communication services**: Mattermost supports asynchronous and real-time communication, enhanced by notification systems tailored for different workflows:
- **Push Notifications**: Delivered to mobile devices for message alerts or mentions. High availability is achieved with backup notification services and retry mechanisms for reliable delivery.
- **Email Integration**: Provides regular notifications when users are offline or inactive. Failover mail servers and distributed configurations ensure email notifications are sent without interruption.
These services ensure continuous engagement and communication.
### Communication protocols
There are also communication protocols (HTTPS and WS) that define the type of connection the user makes with the Mattermost server. High availability measures ensure reliable and resilient connections between clients and the Mattermost server, especially in production environments.
**HTTPS Connection** (Secure Hypertext Transfer Protocol)
- HTTPS connections to the Mattermost server render pages and provide access to core platform functionality, but do not include real-time interactivity (which is enabled by WSS connections).
- HTTPS is a secure, encrypted protocol and is highly recommended for production. Unencrypted HTTP connections may be used in initial testing and configuration, but should never be used in a production environment. For high availability, HTTPS traffic should be handled by a reverse proxy (e.g., NGINX or HAProxy) with load balancer configurations to distribute connections across multiple Mattermost server instances. Redundant proxy servers ensure failover capabilities, providing uninterrupted service.
**WSS Connection** (Secure WebSocket Protocol)
Secure WebSocket (WSS) connections to the Mattermost Server enable real-time updates and notifications between clients and the server.
If a WSS connection is not available and HTTPS is substituted, the system will appear to work but real-time updates and notifications will not. In this mode of operation, updates will only appear on a page refresh. WSS has a persistent connection to the Mattermost server when a client is connected, while HTTPS has an intermittent connection and only connects to the server when a page or file is requested.
High availability for WSS connections can be achieved through clustering Mattermost servers and load balancing WebSocket connections across those cluster nodes. Proxy servers and WebSocket-specific configurations (such as sticky sessions or connection persistence) are essential to maintain real-time interactivity during server or network failures.
<img src={useBaseUrl('/images/architecture_with_protocol.png')} class="bg-white" alt="Mattermost architecture with protocol connections" />
By incorporating high availability strategies into communication protocols, the platform ensures secure, scalable, and reliable connections for both regular user interactions (via HTTPS) and real-time updates (via WSS). These measures are critical for mission-critical environments and distributed deployments where continuous communication is necessary.
**Behind a VPN**
Mattermost is intended to be installed within a private network which can offer multiple factors of authentication, including secure access to computing devices and physical locations. If outside access is required, a virtual private network client (VPN), such as [OpenVPN](https://openvpn.net/), with additional authentication used to connect to Mattermost for web, desktop, and mobile experiences, is recommended.
**Non-VPN setup**
If Mattermost is accessible from the open internet, the following is recommended:
1. An IT admin should be assigned to set up appropriate network security, subscribe to [the Mattermost security bulletin](https://mattermost.com/security-updates/#sign-up), and [apply new security updates](/administration-guide/upgrade/upgrading-mattermost-server).
2. The organization enables [SAML Single Sign-on](/administration-guide/onboard/sso-saml) or enable [MFA](/administration-guide/onboard/multi-factor-authentication).
If Mattermost is accessible from the open internet with no VPN or MFA set up, we recommended using it only for non-confidential, unimportant conversations where impact of a compromised system is not essential.
#### Mattermost services ports
The following tables list the Mattermost services ports for Mattermost Server, push proxy, and mobile app clients. System admins with clients that need to speak to the Mattermost server without a proxy can open specific firewall ports as needed.
**Mattermost Server**
*Inbound ports*
| Service | Config Setting | Port (default) | Protocol | Notes |
|---|---|---|---|---|
| HTTP/WebSocket | `ServiceSettings.ListenAddress` | 8065 / 80 / 443 (TLS) | TCP | External (no proxy) / Internal (with proxy). Ports 80 and 443 are typically used when running HTTPS. |
| Cluster (HA) | `ClusterSettings.GossipPort` | 8074 | TCP/UDP | Internal only. Must be reachable between all Mattermost Server nodes. Both TCP and UDP must be open. HA only. |
| Metrics | `MetricsSettings.ListenAddress` | 8067 | TCP | Internal only. Restrict access to trusted monitoring hosts (e.g., Prometheus). Must not be exposed to the public internet. Only required when metrics collection is enabled. |
*Outbound ports*
| Service | Config Setting | Port (default) | Protocol | Notes |
|---|---|---|---|---|
| Database | `SqlSettings.DataSource` | 5432 (PostgreSQL) | TCP | Usually internal (recommended). |
| LDAP | `LdapSettings.LdapPort` | 389 | TCP/UDP | |
| S3 Storage | `FileSettings.AmazonS3Endpoint` | 443 (TLS) | TCP | |
| SMTP | `EmailSettings.SMTPPort` | 10025 | TCP/UDP | |
| Push Notifications | `EmailSettings.PushNotificationServer` | 443 (TLS) | TCP | |
**Push Proxy**
*Inbound ports*
| Service | Config Setting | Port (default) | Protocol | Notes |
|---|---|---|---|---|
| Push Proxy | `ListenAddress` | 8066 | TCP | Internal only. Must be reachable only from Mattermost Server nodes. Required when running a self-hosted push proxy. |
**Mobile Clients**
To receive push notifications, your network must allow traffic on [port 5223 for iOS devices](https://support.apple.com/en-us/102266) and [ports 5228-5230 for Android](https://firebase.google.com/docs/cloud-messaging/concept-options#messaging-ports-and-your-firewall).

View File

@@ -0,0 +1,90 @@
---
title: "Backup and disaster recovery"
---
<PlanAvailability slug="all-commercial" />
Options to protect your Mattermost server from different types of failures range from simple backups to sophisticated disaster recovery deployments and automation.
## Backup
The state of your Mattermost server is contained in multiple data stores that need to be backed up and restored separately to fully recover your system from failure.
To back up your Mattermost server:
1. Back up your Mattermost database using standard procedures depending on your database version. [PostgreSQL SQL Dump backup documentation](https://www.postgresql.org/docs/10/backup-dump.html) is available online. Use the navigation at the top of the page to select your PostgreSQL version.
2. Back up your server settings stored in `config/config.json`. If you are using SAML configuration for Mattermost, your SAML certificate files will be saved in the `config` directory. Therefore, we recommend backing up the entire directory.
3. Back up files stored by your users with one of the following options:
> - If you use local storage using the default `./data` directory, back up this directory.
> - If you use local storage using a non-default directory specified in the `Directory` setting in `config.json`, back up files in that location.
> - If you store your files in S3, you can typically keep the files where they are located without backup.
<Note>
To make a clean backup, you must stop Mattermost during the duration of the backup, otherwise the database and files may become out of sync.
</Note>
To restore a Mattermost instance from backup, restore your database, `config.json` file, and optionally the locally stored user files into the locations from which they were backed up.
## Disaster recovery
An appropriate disaster recovery plan weighs the benefits of mitigating specific risks against the cost and complexity of setting up disaster recovery infrastructure and automation.
<Note>
**High availability (HA) vs. disaster recovery (DR)**
HA and DR are distinct concepts that are often confused. HA refers to a clustered deployment within a single site that eliminates single points of failure and keeps Mattermost running through individual component outages (e.g., a failed app node or database replica). DR addresses the broader scenario of an entire site or region becoming unavailable, and typically requires a secondary deployment in a separate data center or cloud region.
Mattermost supports active/passive DR, where a secondary site is kept in sync but only activated during a failover. Mattermost does not support active/active deployments, where both sites serve live traffic simultaneously.
</Note>
### Automated backup
Automating backups for a Mattermost server provides a copy of the server's state at a particular point in time, which can be restored if a failure in the future leads to loss of data. Options include:
- Automation to periodically back up the Mattermost server, which may include all the components listed above or a subset depending on what you choose to protect.
- Automation to restore a server from backup, or deploy a new server, to reduce recovery time.
- Automation to verify a backup has been successfully produced to protect against backup automation failures.
- Storing backups off-site, to protect against physical loss of onsite systems.
Recovering from a failure using a backup is typically a manual process and will incur downtime. The alternative is to automate recovery using a high availability deployment.
### Active/passive DR deployment
For step-by-step instructions on setting up Mattermost in an active/passive DR configuration across two data centers, including how to replicate the database, file storage, and search indices, and how to perform a failover, see the platform-specific guide:
### Failover from Single Sign-On outage
When using Single Sign-on with Mattermost Enterprise Edition, an outage to your SSO provider can cause a partial outage on your Mattermost instance.
**What happens during an SSO outage?**
- **Most people can still log in.** By default, when a user logs in to Mattermost they receive a session token lasting 30 days (the duration can be configured in the System Console). During an SSO outage, users with valid session tokens can continue using Mattermost uninterrupted.
- **Some people can't log in.** During an SSO outage, there are two situations under which a user cannot log in:
- Users whose session token expires during the outage.
- Users trying to log in to new devices.
In each case, the user cannot reach the SSO provider, and cannot log in. In either case, several mitigations are available:
#### Configure your SSO provider for High Availability
If you're using a self-hosted Single Sign-on provider, several options are available for [High Availability configurations that protect your system from unplanned outages](https://learn.microsoft.com/en-us/microsoft-identity-manager/pam/high-availability-disaster-recovery-considerations-bastion-environment).
For SaaS-based authentication providers, while you still have a dependency on service uptime, you can set up redundancy in source systems from which data is being pulled. For example, with the OneLogin SaaS-based authentication service, you can set up High Availability LDAP connectivity to further reduce the chances of an outage.
#### Set up your own IDP to provide an automated or manual SSO failover option
Create a custom Identity Provider for SAML authentication that connects to both an active and a standby authentication option, that can be manually or automatically switched in case of an outage.
In this configuration, security should be carefully reviewed to prevent the standby SSO option from weakening your authentication protocols.
#### Set up a manual failover plan for SSO outages
When users are unable to reach your organization's SSO provider during an outage, an error message directing them to contact your support link (defined in your System Console settings) is displayed.
Once IT is contacted about an SSO outage, they can temporarily change a user's account from SSO to email-password using the System Console, and the end user can use their email and password to claim the account until the SSO outage is over and the account can be converted back to SSO.
When the outage is over, it's critical to switch everyone back to SSO from email-password to maintain consistency and security.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
---
title: "Calls Deployment on Kubernetes"
---
<PlanAvailability slug="all-commercial" />
This guide provides detailed information for deploying Mattermost Calls on Kubernetes environments.
## Overview
Mattermost Calls has been designed to integrate with Kubernetes for improved scalability and control over the deployment. Using the RTCD service is the only supported deployment model.
## Architecture
![Calls deployed in a Kubernetes cluster](/images/calls-deployment-kubernetes.png)
This diagram shows how the RTCD standalone service can be deployed in a Kubernetes cluster. In this architecture:
1. Calls traffic is handled by dedicated RTCD pods
2. Scaling is managed through Kubernetes deployment configurations
3. Call recording and transcription is handled by the calls-offloader service (see [Calls Offloader Setup and Configuration](calls-offloader-setup.mdx))
If Mattermost isn't already deployed in your Kubernetes cluster and you want to use this deployment type, visit the [Kubernetes operator guide](/deployment-guide/server/deploy-kubernetes).
## Helm Chart Deployment
The recommended way to deploy Calls-related components in a Kubernetes environment is to use the officially provided Helm charts:
### RTCD Helm Chart
The RTCD Helm chart deploys the RTCD service needed for call media handling:
```bash
helm repo add mattermost https://helm.mattermost.com
helm repo update
helm install mattermost-rtcd mattermost/mattermost-rtcd \
--set service.annotations."service\\.beta\\.kubernetes\\.io/aws-load-balancer-backend-protocol"=udp
```
For complete configuration options, see the [RTCD Helm chart documentation](https://github.com/mattermost/mattermost-helm/tree/master/charts/mattermost-rtcd).
### Calls-Offloader Helm Chart
If you need call recording and transcription capabilities, deploy the calls-offloader service:
```bash
helm install mattermost-calls-offloader mattermost/mattermost-calls-offloader \
--set ingress.enabled=true \
--set ingress.host=calls-offloader.example.com
```
For complete configuration options, see the [Calls-Offloader Helm chart documentation](https://github.com/mattermost/mattermost-helm/tree/master/charts/mattermost-calls-offloader).
## Kubernetes-Specific Configuration
### Network Configuration
For Kubernetes deployments, you need to ensure specific connectivity paths:
1. **Client to RTCD connectivity**: UDP and TCP traffic on port 8443 is properly routed from clients to RTCD pods (for media, with TCP acting as a fallback).
2. **Mattermost to RTCD API connectivity**: There needs to be a clear connectivity path between Mattermost and RTCD on the API port (TCP 8045)
3. **Network policies**: Network policies must allow the required communications between Mattermost and RTCD services
### Resource Requirements
Resource requirements for RTCD pods depend heavily on the expected call volume, participant count, and whether screen sharing is used.
We strongly recommend reviewing the [Performance Baselines](calls-metrics-monitoring.mdx#performance-baselines) to determine the appropriate CPU, memory, and network requests and limits for your specific deployment needs rather than relying on generic defaults.
### Scaling Considerations
Horizontal scaling of RTCD pods is possible, but remember:
1. Each call is hosted entirely on a single RTCD pod
2. DNS A records should be set up for all RTCD pods so server can discover RTCD servers.
3. Health checks should ensure that only healthy pods are reported via DNS
4. Calls remain on their assigned pod for their entire duration
### Limitations
Due to the inherent complexities of hosting a WebRTC service, some limitations apply when deploying Calls in a Kubernetes environment.
One key requirement is that each `rtcd` process must live in a dedicated Kubernetes node. This is necessary to forward the data correctly while allowing for horizontal scaling. Data should generally direct directly to the pod running the `rtcd` process, as routing this traffic through a standard ingress is not recommended for RTCD deployments.
The general recommendation is to expose one external IP address per `rtcd` instance (Kubernetes node). This makes it simpler to scale as the application is able to detect its own external address (through STUN) and advertise it to clients to achieve connectivity with minimal configuration.
## Monitoring and Metrics
For detailed information on metrics collection and monitoring, see the [Calls Metrics and Monitoring](calls-metrics-monitoring.mdx) guide.
## Troubleshooting
For Kubernetes-specific troubleshooting:
1. Check pod logs: `kubectl logs -f deployment/mattermost-rtcd`
2. Verify service connectivity: `kubectl port-forward service/mattermost-rtcd 8045:8045`
3. Ensure UDP and TCP traffic is properly routed through your load balancer
4. Verify network policies allow required communication paths
For detailed logging guidance, see the [Calls Logging](calls-logging.mdx) guide.
## Other Calls Documentation
- [Calls Deployment Guide](calls-deployment-guide.mdx): Overview of deployment options and architecture
- [RTCD Setup and Configuration](calls-rtcd-setup.mdx): Comprehensive guide for setting up the dedicated RTCD service
- [Calls Offloader Setup and Configuration](calls-offloader-setup.mdx): Setup guide for call recording and transcription
- [Calls Metrics and Monitoring](calls-metrics-monitoring.mdx): Guide to monitoring Calls performance using metrics and observability
- [Calls Logging](calls-logging.mdx): Detailed guidance for collecting Calls logs and client diagnostics

View File

@@ -0,0 +1,34 @@
---
title: "Calls Logging"
---
<PlanAvailability slug="all-commercial" />
When troubleshooting Mattermost Calls, gathering the appropriate log files for analysis is critical. The required logs include:
## RTCD logs
The location of the RTCD log file is determined by the settings in your RTCD `config.toml` file. If you are running Calls using the integrated RTCD, these logs are included within the standard Mattermost server logs.
## Client logs
You can retrieve basic client logs by running the `/call logs` slash command to output the log for the most recent call. However, capturing the JavaScript console logs is often more helpful. The method for capturing these logs depends on your client:
- **Desktop App:** While a call is in progress, navigate to **View > Developer Tools > Developer Tools for Call Widget**. Next to the **Filter** field, select **Verbose** from the log level drop-down menu to view the debug output. To save the log, right-click within the console and select **Save as...**.
![Developer Tools for Call Widget](/images/developer-tools-call-widget.png)
- **Chrome browser:** Select the **More menu** (three vertical dots) next to the address bar, then go to **More Tools > Developer Tools**. Select the **Console** tab to view the output. Next to the **Filter** field, select **Verbose** from the log level drop-down menu to view the debug output. To save the log, right-click within the console and select **Save as...**.
## Client statistics
You can gather client call statistics by running the `/call stats` slash command. While you can run this command during an active call, it is best to run it immediately after a call concludes. This command provides valuable information regarding the negotiated connection between the client and RTCD, as well as statistics on media packets sent and lost.
## Mattermost server logs
The Mattermost server logs often contain entries related to the Calls plugin. If you are using an external RTCD instance, these logs are generally less critical than the RTCD and client logs.
<Note>
Interpreting RTCD and client logs can be challenging, as the Interactive Connectivity Establishment (ICE) negotiation during call setup often logs expected and benign failure or error messages. We strongly recommend providing the complete set of logs to Mattermost Support for analysis.
</Note>

View File

@@ -0,0 +1,416 @@
---
title: "Calls Metrics and Monitoring"
---
<PlanAvailability slug="ent-plus" />
This guide provides detailed information on monitoring Mattermost Calls performance and health through metrics and observability tools. Effective monitoring is essential for maintaining optimal call quality and quickly addressing any issues that arise.
- [Metrics overview](#metrics-overview)
- [Setting up monitoring](#setting-up-monitoring)
- [Key metrics to monitor](#key-metrics-to-monitor)
- [Performance baselines](#performance-baselines)
- [Troubleshooting metrics collection](#troubleshooting-metrics-collection)
## Metrics Overview
Mattermost Calls provides metrics through Prometheus for both the Calls plugin and the RTCD service. These metrics help track:
- Active call sessions and participants
- Media track statistics
- Connection states and errors
- Resource utilization (CPU, memory, network)
- WebSocket connections and events
The metrics are exposed through HTTP endpoints:
- **Calls Plugin**: `/plugins/com.mattermost.calls/metrics`
- **RTCD Service**: `/metrics` (default) or a configured endpoint
Resource utilization metrics (CPU, memory, network) are mainly provided by an external service ([`node-exporter`](https://prometheus.io/docs/guides/node-exporter/)).
> Metrics for the calls plugin are exposed through the `/plugins/com.mattermost.calls/metrics` subpath under the existing Mattermost server metrics endpoint. This is controlled by the [Listen address for performance](/administration-guide/configure/environment-configuration-settings#listen-address-for-performance) configuration setting. It defaults to port 8067. For example: `http://localhost:8067/plugins/com.mattermost.calls/metrics`
> The RTCD Service `/metrics` endpoint is exposed on the HTTP API (e.g. `http://localhost:8045/metrics`).
## Setting Up Monitoring
For instructions on deploying Prometheus and Grafana for Mattermost, please refer to the [Deploy Prometheus and Grafana for performance monitoring](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring) guide.
Once Prometheus and Grafana are set up, you will need to configure Prometheus to scrape metrics from the Calls-related services.
### Prometheus Scrape Configuration
Add the following jobs to your `prometheus.yml` configuration:
```yaml
scrape_configs:
- job_name: 'calls-plugin'
metrics_path: /plugins/com.mattermost.calls/metrics
static_configs:
- targets: ['MATTERMOST_SERVER_IP:8067']
labels:
service_name: 'calls-plugin'
- job_name: 'rtcd'
metrics_path: /metrics
static_configs:
- targets: ['RTCD_SERVER_IP:8045']
labels:
service_name: 'rtcd'
- job_name: 'rtcd-node-exporter'
metrics_path: /metrics
static_configs:
- targets: ['RTCD_SERVER_IP:9100']
labels:
service_name: 'rtcd'
- job_name: 'calls-offloader-node-exporter'
metrics_path: /metrics
static_configs:
- targets: ['CALLS_OFFLOADER_SERVER_IP:9100']
labels:
service_name: 'offloader'
```
Replace the placeholder IP addresses with your actual server addresses:
- `MATTERMOST_SERVER_IP`: IP address of your Mattermost server
- `RTCD_SERVER_IP`: IP address of your RTCD server
- `CALLS_OFFLOADER_SERVER_IP`: IP address of your calls-offloader server (if deployed)
<Important>
**Metrics Configuration Notice**: Use the `service_name` labels as shown in the configuration above. These labels help organize metrics in dashboards and enable proper service identification.
</Important>
<Note>
- **node_exporter**: Optional but recommended for system-level metrics (CPU, memory, disk, network). See [node_exporter setup guide](https://prometheus.io/docs/guides/node-exporter/) for installation instructions.
- **calls-offloader**: Only needed if you have call recording/transcription enabled.
</Note>
### Mattermost Calls Grafana Dashboard
You can use the official [Mattermost Calls Performance Monitoring](https://grafana.com/grafana/dashboards/23225-mattermost-calls-performance-monitoring/) dashboard to visualize these metrics.
- To import it directly into Grafana, use dashboard ID: `23225`.
- The dashboard is also available as JSON source from the [Mattermost performance assets repository](https://github.com/mattermost/mattermost-performance-assets/blob/master/grafana/mattermost-calls-performance-monitoring.json) for manual import or customization.
## Key Metrics to Monitor
### RTCD Metrics
#### Process Metrics
These metrics help monitor the health and resource usage of the RTCD process:
- `rtcd_process_cpu_seconds_total`: Total CPU time spent
- `rtcd_process_open_fds`: Number of open file descriptors
- `rtcd_process_max_fds`: Maximum number of file descriptors
- `rtcd_process_resident_memory_bytes`: Memory usage in bytes
- `rtcd_process_virtual_memory_bytes`: Virtual memory used
#### WebRTC Connection Metrics
These metrics track the WebRTC connections and media flow:
- `rtcd_rtc_conn_states_total{state="X"}`: Count of connections in different states
- `rtcd_rtc_errors_total{type="X"}`: Count of RTC errors by type
- `rtcd_rtc_rtp_tracks_total{direction="X"}`: Count of RTP tracks (incoming/outgoing)
- `rtcd_rtc_sessions_total`: Total number of active RTC sessions
#### WebSocket Metrics
These metrics track the signaling channel:
- `rtcd_ws_connections_total`: Total number of active WebSocket connections. This is about RTCD &lt;-> MM, so the connection count should match the number of MM nodes.
- `rtcd_ws_messages_total{direction="X"}`: Count of WebSocket messages (sent/received)
### Calls Plugin Metrics
Similar metrics are available for the Calls plugin with the following prefixes:
- Process metrics: `mattermost_plugin_calls_process_*`
- WebRTC connection metrics: `mattermost_plugin_calls_rtc_*`
- WebSocket metrics: `mattermost_plugin_calls_websocket_*`
- Store metrics: `mattermost_plugin_calls_store_ops_total`
## Performance Baselines
The following performance benchmarks provide baseline metrics for RTCD deployments under various load conditions and configurations.
**Deployment specifications**
- 1x r6i.large nginx proxy
- 3x c5.large MM app nodes (HA)
- 2x db.x2g.xlarge RDS Aurora MySQL v8 (one writer, one reader)
- 1x (c7i.xlarge, c7i.2xlarge, c7i.4xlarge) RTCD
- 2x c7i.2xlarge load-test agents
**App specifications**
- Mattermost v9.6
- Mattermost Calls v0.28.0
- RTCD v0.16.0
- load-test agent v0.28.0
**Media specifications**
- Speech sample bitrate: 80Kbps
- Screen sharing sample bitrate: 1.6Mbps
**Results**
Below are the detailed benchmarks based on internal performance testing:
<table border="1" class="network-requirements">
<thead>
<tr>
<th>Calls</th>
<th>Participants/call</th>
<th>Unmuted/call</th>
<th>Screen sharing</th>
<th>CPU (avg)</th>
<th>Memory (avg)</th>
<th>Bandwidth (in/out)</th>
<th>Instance type (RTCD)</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1000</td>
<td>2</td>
<td>no</td>
<td>47%</td>
<td>1.46GB</td>
<td>1Mbps / 194Mbps</td>
<td>c7i.xlarge</td>
</tr>
<tr>
<td>1</td>
<td>800</td>
<td>1</td>
<td>yes</td>
<td>64%</td>
<td>1.43GB</td>
<td>2.7Mbps / 1.36Gbps</td>
<td>c7i.xlarge</td>
</tr>
<tr>
<td>1</td>
<td>1000</td>
<td>1</td>
<td>yes</td>
<td>79%</td>
<td>1.54GB</td>
<td>2.9Mbps / 1.68Gbps</td>
<td>c7i.xlarge</td>
</tr>
<tr>
<td>10</td>
<td>100</td>
<td>1</td>
<td>yes</td>
<td>74%</td>
<td>1.56GB</td>
<td>18.2Mbps / 1.68Gbps</td>
<td>c7i.xlarge</td>
</tr>
<tr>
<td>100</td>
<td>10</td>
<td>2</td>
<td>no</td>
<td>49%</td>
<td>1.46GB</td>
<td>18.7Mbps / 175Mbps</td>
<td>c7i.xlarge</td>
</tr>
<tr>
<td>100</td>
<td>10</td>
<td>1</td>
<td>yes</td>
<td>84%</td>
<td>1.73GB</td>
<td>171Mbps / 1.53Gbps</td>
<td>c7i.xlarge</td>
</tr>
<tr>
<td>1</td>
<td>1000</td>
<td>2</td>
<td>no</td>
<td>20%</td>
<td>1.44GB</td>
<td>1.4Mbps / 194Mbps</td>
<td>c7i.2xlarge</td>
</tr>
<tr>
<td>1</td>
<td>1000</td>
<td>2</td>
<td>yes</td>
<td>49%</td>
<td>1.53GB</td>
<td>3.6Mbps / 1.79Gbps</td>
<td>c7i.2xlarge</td>
</tr>
<tr>
<td>2</td>
<td>1000</td>
<td>1</td>
<td>yes</td>
<td>73%</td>
<td>2.38GB</td>
<td>5.7Mbps / 3.06Gbps</td>
<td>c7i.2xlarge</td>
</tr>
<tr>
<td>100</td>
<td>10</td>
<td>2</td>
<td>yes</td>
<td>60%</td>
<td>1.74GB</td>
<td>181Mbps / 1.62Gbps</td>
<td>c7i.2xlarge</td>
</tr>
<tr>
<td>150</td>
<td>10</td>
<td>1</td>
<td>yes</td>
<td>72%</td>
<td>2.26GB</td>
<td>257Mbps / 2.30Gbps</td>
<td>c7i.2xlarge</td>
</tr>
<tr>
<td>150</td>
<td>10</td>
<td>2</td>
<td>yes</td>
<td>79%</td>
<td>2.34GB</td>
<td>271Mbps / 2.41Gbps</td>
<td>c7i.2xlarge</td>
</tr>
<tr>
<td>250</td>
<td>10</td>
<td>2</td>
<td>no</td>
<td>58%</td>
<td>2.66GB</td>
<td>47Mbps / 439Mbps</td>
<td>c7i.2xlarge</td>
</tr>
<tr>
<td>1000</td>
<td>2</td>
<td>2</td>
<td>no</td>
<td>78%</td>
<td>2.31GB</td>
<td>178Mbps / 195Mbps</td>
<td>c7i.2xlarge</td>
</tr>
<tr>
<td>2</td>
<td>1000</td>
<td>2</td>
<td>yes</td>
<td>41%</td>
<td>2.6GB</td>
<td>7.23Mbps / 3.60Gbps</td>
<td>c7i.4xlarge</td>
</tr>
<tr>
<td>3</td>
<td>1000</td>
<td>2</td>
<td>yes</td>
<td>63%</td>
<td>3.53GB</td>
<td>10.9Mbps / 5.38Gbps</td>
<td>c7i.4xlarge</td>
</tr>
<tr>
<td>4</td>
<td>1000</td>
<td>2</td>
<td>yes</td>
<td>83%</td>
<td>4.40GB</td>
<td>14.5Mbps / 7.17Gbps</td>
<td>c7i.4xlarge</td>
</tr>
<tr>
<td>250</td>
<td>10</td>
<td>2</td>
<td>yes</td>
<td>79%</td>
<td>3.49GB</td>
<td>431Mbps / 3.73Gbps</td>
<td>c7i.4xlarge</td>
</tr>
<tr>
<td>500</td>
<td>2</td>
<td>2</td>
<td>yes</td>
<td>71%</td>
<td>2.54GB</td>
<td>896Mbps / 919Mbps</td>
<td>c7i.4xlarge</td>
</tr>
</tbody>
</table>
## Troubleshooting Metrics Collection
### Verify RTCD Metrics are Being Collected
To verify that Prometheus is successfully collecting RTCD metrics, use this command:
```bash
curl http://PROMETHEUS_IP:9090/api/v1/label/__name__/values | jq '.' | grep rtcd
```
This command queries Prometheus for all available metric names and filters for RTCD-related metrics.
If no RTCD metrics appear, check:
1. RTCD is running
2. Prometheus is configured to scrape the RTCD metrics endpoint
3. RTCD metrics port is accessible from Prometheus (default: 8045)
### Check Prometheus Scrape Targets
To verify all Calls-related services are being scraped successfully:
1. Open the Prometheus web interface (typically `http://PROMETHEUS_IP:9090`)
2. Navigate to **Status > Targets**
3. Look for your configured Calls services:
- Mattermost server (for Calls plugin metrics)
- RTCD service
Each target should show status "UP" in green. If a target shows "DOWN" or errors:
- Verify the service is running
- Check network connectivity between Prometheus and the target
- Verify the metrics endpoint is accessible
## Other Calls Documentation
- [Calls Deployment Guide](calls-deployment-guide.mdx): Overview of deployment options and architecture
- [RTCD Setup and Configuration](calls-rtcd-setup.mdx): Comprehensive guide for setting up the dedicated RTCD service
- [Calls Offloader Setup and Configuration](calls-offloader-setup.mdx): Setup guide for call recording and transcription
- [Calls Deployment on Kubernetes](calls-kubernetes.mdx): Detailed guide for deploying Calls in Kubernetes environments
- [Calls Logging](calls-logging.mdx): Detailed guidance for collecting Calls logs and client diagnostics
**Note:**
Configure Prometheus storage accordingly to balance disk usage with retention needs. If you need to be tight on storage, you can use a short retention period. If you have lots of storage you can keep the retention length longer.

View File

@@ -0,0 +1,504 @@
---
title: "Calls Offloader Setup and Configuration"
---
<PlanAvailability slug="ent-plus" />
This guide provides detailed instructions for setting up, configuring, and validating the Mattermost calls-offloader service used for call recording and transcription features.
- [Overview](#overview)
- [Prerequisites](#prerequisites)
- [Installation and deployment](#installation-and-deployment)
- [Configuration](#configuration)
- [Validation and testing](#validation-and-testing)
- [Integration with Mattermost](#integration-with-mattermost)
- [Troubleshooting](#troubleshooting)
- [Air-Gapped Deployments](#air-gapped-installation-of-calls-offloader)
## Overview
The calls-offloader service is a dedicated microservice that handles resource-intensive tasks for Mattermost Calls, including:
- **Call recording**: Captures audio and screen sharing content from calls
- **Call transcription**: Provides automated transcription of recorded calls
- **Live captions** (Experimental): Real-time transcription during active calls
By offloading these tasks to a dedicated service, the main Mattermost server and RTCD service can focus on core functionality while maintaining optimal performance.
## Prerequisites
Before deploying calls-offloader, ensure you have:
- A Mattermost Enterprise license
- A properly configured Mattermost Calls deployment (either integrated or with RTCD)
- A moderately powerful server with Docker installed and running
- Sufficient storage space for recordings (see [Storage Requirements](#storage-requirements))
### System Requirements
For detailed system requirements and performance recommendations, refer to the [calls-offloader performance documentation](https://github.com/mattermost/calls-offloader/blob/master/docs/performance.md).
### Storage Requirements
Call recordings can consume significant storage space. Based on average recording sizes with screen sharing on (including one audio track), storage usage by quality chosen is approximately:
- **Low**: ~0.5GB/hour (or ~8MB/minute)
- **Medium**: ~0.7GB/hour (or ~12MB/minute)
- **High**: ~1.2GB/hour (or ~20MB/minute)
*Note: Audio-only recordings consume approximately 1MB per minute per participant.*
## Installation and Deployment
### Bare Metal or VM Deployment
<Tip>
Looking for an automated setup? Check out these community-maintained [Calls Installation Scripts](https://github.com/bgardner8008/calls-install-scripts) for quick provisioning of the Calls Offloader service on Ubuntu/Debian systems.
</Tip>
1. Download the latest release from the [calls-offloader GitHub repository](https://github.com/mattermost/calls-offloader/releases)
2. Create the necessary directories:
```bash
sudo mkdir -p /opt/calls-offloader/data/db
sudo useradd --system --home /opt/calls-offloader calls-offloader
sudo chown -R calls-offloader:calls-offloader /opt/calls-offloader
```
3. Create a configuration file (`/opt/calls-offloader/config.toml`):
```toml
[api]
http.listen_address = ":4545"
http.tls.enable = false
http.tls.cert_file = ""
http.tls.cert_key = ""
security.allow_self_registration = true
security.enable_admin = false
security.admin_secret_key = ""
security.session_cache.expiration_minutes = 1440
[store]
data_source = "/opt/calls-offloader/data/db"
[jobs]
api_type = "docker"
max_concurrent_jobs = 100
failed_jobs_retention_time = "30d"
image_registry = "mattermost"
[logger]
enable_console = true
console_json = false
console_level = "INFO"
enable_file = true
file_json = true
file_level = "DEBUG"
file_location = "/opt/calls-offloader/calls-offloader.log"
enable_color = true
```
4. Create a systemd service file (`/etc/systemd/system/calls-offloader.service`):
```ini
[Unit]
Description=Mattermost Calls Offloader Service
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User=calls-offloader
WorkingDirectory=/opt/calls-offloader
ExecStart=/opt/calls-offloader/calls-offloader --config /opt/calls-offloader/config.toml
Restart=always
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
```
5. Enable and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable calls-offloader
sudo systemctl start calls-offloader
```
6. Check the service status:
```bash
sudo systemctl status calls-offloader
```
7. Verify the service is responding:
```bash
curl http://localhost:4545/version
# Example output:
# {"buildDate":"2025-03-10 19:13","buildVersion":"v0.9.2","buildHash":"a4bd418","goVersion":"go1.23.6"}
```
## Configuration
### API Configuration
The API section controls how the service accepts requests:
- **http.listen_address**: The address and port where the service listens (default: `:4545`)
- **http.tls.enable**: Whether to use TLS encryption for the API
- **security.allow_self_registration**: Allow clients to self-register for job management
- **security.enable_admin**: Enable admin functionality
- **security.admin_secret_key**: Secret key for admin authentication (change from default!)
### Store Configuration
Controls persistent data storage:
- **data_source**: Path to directory for storing client (i.e., connecting Mattermost nodes) IDs and credentials
### Jobs Configuration
Controls job processing behavior:
- **api_type**: Job execution backend (`docker` or `kubernetes`)
- **max_concurrent_jobs**: Maximum number of simultaneous recording/transcription jobs
- **failed_jobs_retention_time**: How long to keep failed job data before cleanup
- **image_registry**: Docker registry for job runner images (typically `mattermost`)
### Logger Configuration
Controls logging output:
- **enable_console**: Log to console output
- **console_json**: Use JSON format for console logs
- **console_level**: Log level for console (DEBUG, INFO, WARN, ERROR)
- **enable_file**: Log to file
- **file_location**: Path to log file
- **enable_color**: Use colored output for console logs
### Private Network Configuration
When the Mattermost deployment is running in a private network, additional configuration may be necessary for the jobs spawned by the calls-offloader service to reach the Mattermost server.
In such cases, you can override the site URL used by recorder jobs or transcriber jobs to connect to Mattermost by setting the following environment variables on the Mattermost server:
- **MM_CALLS_RECORDER_SITE_URL**: Override the site URL used by recording jobs
- **MM_CALLS_TRANSCRIBER_SITE_URL**: Override the site URL used by transcription jobs
<Note>
When these Site URL overrides are used, the `ServiceSettings.AllowCorsFrom` setting on your Mattermost server may need to be adjusted accordingly to ensure CORS does not block requests.
This override configuration lets the recorder and transcriber jobs connect to mattermost server using HTTP instead of HTTPS, which should only be used in a private network.
</Note>
Example configuration:
Create or edit the Mattermost environment file (`/opt/mattermost/config/mattermost.environment`):
```bash
MM_CALLS_RECORDER_SITE_URL="http://internal-mattermost-server:8065"
MM_CALLS_TRANSCRIBER_SITE_URL="http://internal-mattermost-server:8065"
```
Then ensure your Mattermost systemd service references this environment file:
```ini
[Unit]
Description=Mattermost
After=network.target
[Service]
Type=notify
EnvironmentFile=/opt/mattermost/config/mattermost.environment
ExecStart=/opt/mattermost/bin/mattermost
TimeoutStartSec=3600
KillMode=mixed
Restart=always
RestartSec=10
WorkingDirectory=/opt/mattermost
User=mattermost
Group=mattermost
[Install]
WantedBy=multi-user.target
```
This is particularly useful when:
- The calls-offloader service runs in a different network segment than clients
- Internal DNS resolution differs from external URLs
- You need to use internal load balancer endpoints for job communication
## Validation and Testing
After deploying calls-offloader, validate the installation:
1. **Check service status**:
```bash
# For systemd
sudo systemctl status calls-offloader
```
2. **Test API connectivity**:
**From the calls-offloader server (localhost test)**:
```bash
curl http://localhost:4545/version
# Should return version information
# Example: {"buildDate":"2025-03-10 19:13","buildVersion":"v0.9.2","buildHash":"a4bd418","goVersion":"go1.23.6"}
```
**From the Mattermost server**:
```bash
curl http://YOUR_CALLS_OFFLOADER_SERVER:4545/version
# Should return the same version information
# This confirms network connectivity from Mattermost to calls-offloader
```
If the localhost test works but the Mattermost server test fails, check:
- Firewall rules or SELinux policies on the calls-offloader server (port 4545 must be accessible)
- Network connectivity between Mattermost and calls-offloader servers
3. **Verify Docker service** (if using docker api_type):
```bash
# Check that system user running calls-offloader can access Docker
sudo -u calls-offloader docker ps
```
## Integration with Mattermost
Once calls-offloader is properly set up and validated, configure Mattermost to use it:
1. Go to **System Console > Plugins > Calls**
2. In the **Job Service** section:
- Set **Job Service URL** to your calls-offloader service (e.g., `http://calls-offloader-server:4545`)
3. Enable recording and transcription features as needed:
- **Enable Call Recordings**: Toggle to allow call recordings
- **Enable Call Transcriptions**: Toggle to allow call transcriptions
- **Enable Live Captions** (Experimental): Toggle to allow real-time transcription
4. Save the configuration
5. Restart the Calls plugin to re-establish state:
- Go to **System Console > Plugins > Plugin Management**
- Find the **Calls** plugin and click **Disable**
- Wait a few seconds, then click **Enable**
6. Test by starting a call and starting a recording
## Troubleshooting
### Common Issues
**"failed to create recording job: max concurrent jobs reached"**
This error occurs when the calls-offloader service has reached its configured job limit, and it will usually result in a failure message on the Mattermost Calls plugin side (such as a timeout).
Solutions:
- Increase `max_concurrent_jobs` in the configuration
- Check if jobs are hanging and restart the service
- Monitor system resources and scale up if needed
**Jobs not processing**
Check the following:
- Verify the calls-offloader service is running: `sudo systemctl status calls-offloader`
- Ensure network connectivity between Mattermost and calls-offloader
- Check Docker daemon is running and accessible by the user running the Calls Offloader service (E.g., user: ``calls-offloader``)
- Verify authentication configuration matches between services
- Review service logs for specific error messages
**Docker permission issues**
If using Docker API and seeing permission errors:
```bash
# Add calls-offloader user to docker group
sudo usermod -a -G docker calls-offloader
sudo systemctl restart calls-offloader
```
### Debugging Commands
Monitor calls-offloader job containers:
```bash
# View running job containers
docker ps --format "{{.ID}} {{.Image}}" | grep "calls"
# Follow logs for debugging
docker ps --format "{{.ID}} {{.Image}}" | grep "calls" | awk '{print $1}' | xargs -I {} docker logs -f {}
# View completed job containers
docker ps -a --filter "status=exited"
```
Monitor service health:
```bash
# Check service version and health
curl http://localhost:4545/version
```
Check service logs:
```bash
# View recent logs
sudo journalctl -u calls-offloader -f
# View log file (if file logging enabled)
tail -f /opt/calls-offloader/calls-offloader.log
```
### Performance Monitoring
Monitor calls-offloader performance and resource usage to ensure optimal operation. See [Calls Metrics and Monitoring](calls-metrics-monitoring.mdx) for details on setting up metrics and observability.
## Air-Gapped Installation of `calls-offloader`
This guide covers deploying `calls-offloader` in an environment without internet access. The process uses scripts from the [calls-install-scripts](https://github.com/bgardner8008/calls-install-scripts) repository and follows a two-phase workflow: preparing a transfer bundle on an internet-connected machine, then deploying it on the isolated target machine.
### Overview
Because `calls-offloader` relies on Docker images for the recorder and transcriber jobs, an air-gapped deployment requires that those images be pre-pulled and packaged alongside the `calls-offloader` binary before being transferred to the target environment.
The install scripts handle this in two stages:
1. **Prepare** (internet-connected machine) — `setup-airgap-offloader.sh` pulls the required Docker images and downloads the `calls-offloader` binary, then packages everything into a transfer bundle and generates a ready-to-run deployment script.
2. **Deploy** (air-gapped machine) — Transfer the bundle and run the generated `deploy-airgap-offloader.sh` script, which loads the Docker images into a local registry and installs the service.
### Prerequisites
- An internet-connected Linux machine with Docker installed (for the preparation phase)
- A target air-gapped Linux machine with:
- systemd
- Docker installed
- Root or sudo access
- The [calls-install-scripts](https://github.com/bgardner8008/calls-install-scripts) repository cloned on the internet-connected machine
### Phase 1: Prepare the Transfer Bundle
On the **internet-connected machine**, run `setup-airgap-offloader.sh` specifying the versions of each component to package:
```bash
./setup-airgap-offloader.sh \
--offloader v0.9.5 \
--recorder v0.9.0 \
--transcriber v0.3.0 \
--arch amd64
```
| Flag | Description | Default |
|------|-------------|---------|
| `--offloader VERSION` | `calls-offloader` binary version (e.g. `v0.9.5`) | required |
| `--recorder VERSION` | `calls-recorder` Docker image version | required |
| `--transcriber VERSION` | `calls-transcriber` Docker image version | required |
| `--arch amd64\|arm64` | Target CPU architecture | `amd64` |
The script will:
1. Pull the `calls-recorder` and `calls-transcriber` Docker images from Docker Hub
2. Download the `calls-offloader` binary from GitHub releases
3. Save the Docker images as `.tar` archives
4. Generate a `deploy-airgap-offloader.sh` deployment script configured for the selected versions
5. Produce a transfer bundle containing all of the above
### Phase 2: Transfer to the Air-Gapped Machine
Copy the generated bundle to the target machine using whatever transfer mechanism is available in your environment (USB drive, secure file transfer, etc.):
```bash
scp calls-offloader-airgap-bundle.tar.gz user@airgap-host:/tmp/
```
On the air-gapped machine, extract the bundle:
```bash
tar -xzf calls-offloader-airgap-bundle.tar.gz
cd calls-offloader-airgap-bundle/
```
### Phase 3: Deploy on the Air-Gapped Machine
Run the generated deployment script with root or sudo privileges:
```bash
sudo ./deploy-airgap-offloader.sh
```
This script will:
1. Configure the local Docker daemon to use a local image registry
2. Load the packaged Docker images into that registry
3. Install the `calls-offloader` binary to `/usr/local/bin/`
4. Create the `mattermost` system user and add it to the `docker` group
5. Generate and enable a systemd service unit
6. Start the service and verify it is running
Once complete, verify the service is up:
```bash
curl http://localhost:4545/version
```
### Connecting to Mattermost
Configure the Mattermost Calls plugin to use the offloader service via **System Console > Plugins > Calls > Job service URL**, setting it to `http://<offloader-host>:4545`.
> [!NOTE]
> The first time Mattermost connects to the offloader it will self-register and store its authentication key in the database, provided `API_SECURITY_ALLOWSELFREGISTRATION=true` is set (the default in the deployment script).
### Private Network Considerations
In air-gapped environments the recorder and transcriber containers typically need to reach the Mattermost server via an internal URL. Set the following environment variables on the **Mattermost server** to override the site URL used by spawned jobs:
```
MM_CALLS_RECORDER_SITE_URL=http://internal-mattermost-server:8065
MM_CALLS_TRANSCRIBER_SITE_URL=http://internal-mattermost-server:8065
```
You may also need to add the internal URL to [`ServiceSettings.AllowCorsFrom`](https://docs.mattermost.com/configure/integrations-configuration-settings.html#enable-cross-origin-requests-from) in the Mattermost server configuration.
> [!NOTE]
> In particularly restrictive environments (e.g., VMs with strict network isolation), set `DOCKER_NETWORK=host` in the `calls-offloader` service environment so that job containers can reach the Mattermost server via its local address.
### Custom Docker Registry
If your air-gapped environment already has an internal Docker registry, you can point `install-offloader.sh` at it directly instead of using the local registry set up by the deployment script:
```bash
sudo ./install-offloader.sh \
--binary ./calls-offloader-linux-amd64 \
--image-registry registry.internal.example.com/mattermost \
--arch amd64
```
The `--image-registry` flag sets the registry prefix used when the offloader pulls recorder and transcriber images for each job.
## Other Calls Documentation
- [Calls Deployment Guide](calls-deployment-guide.mdx): Overview of deployment options and architecture
- [RTCD Setup and Configuration](calls-rtcd-setup.mdx): Comprehensive guide for setting up the dedicated RTCD service
- [Calls Metrics and Monitoring](calls-metrics-monitoring.mdx): Guide to monitoring Calls performance using metrics and observability
- [Calls Deployment on Kubernetes](calls-kubernetes.mdx): Detailed guide for deploying Calls in Kubernetes environments
- [Calls Logging](calls-logging.mdx): Detailed guidance for collecting Calls logs and client diagnostics
- [calls-offloader performance documentation](https://github.com/mattermost/calls-offloader/blob/master/docs/performance.md): Detailed performance tuning and monitoring recommendations

View File

@@ -0,0 +1,540 @@
---
title: "RTCD Setup and Configuration"
---
<PlanAvailability slug="ent-plus" />
This guide provides detailed instructions for setting up, configuring, and validating a Mattermost Calls deployment using the dedicated RTCD service.
## Prerequisites
Before deploying RTCD, ensure you have:
- A Mattermost Enterprise license
- A server or VM with sufficient CPU and network capacity (see the [Performance baselines](calls-metrics-monitoring.mdx#performance-baselines) section for sizing guidance)
## Network Requirements
The following network connectivity is required:
<style>
table.network-requirements &#123;
border-collapse: collapse;
width: 100%;
font-size: 0.95em;
&#125;
table.network-requirements th, table.network-requirements td &#123;
border: 1px solid #888;
padding: 6px 8px;
vertical-align: top;
&#125;
/* Dark mode border color */
body:not([data-custom-theme="light"]) table.network-requirements th,
body:not([data-custom-theme="light"]) table.network-requirements td &#123;
border-color: #666;
&#125;
table.network-requirements th &#123;
background: #f2f2f2;
font-weight: bold;
text-align: left;
&#125;
/* Dark mode support for table headers */
body:not([data-custom-theme="light"]) table.network-requirements th &#123;
background: #444;
color: #fff;
&#125;
</style>
<table class="network-requirements">
<thead>
<tr>
<th>Service</th>
<th>Ports</th>
<th>Protocols</th>
<th>Source</th>
<th>Target</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td>API (Calls plugin)</td>
<td>80,443</td>
<td>TCP (incoming)</td>
<td>Mattermost clients (web/desktop/mobile)</td>
<td>Mattermost instance (Calls plugin)</td>
<td>To allow for HTTP and WebSocket connectivity from clients to Calls plugin. This API is exposed on the same connection as Mattermost, so there's likely no need to change anything.</td>
</tr>
<tr>
<td>RTC (Calls plugin or <code>rtcd</code>)</td>
<td>8443</td>
<td>UDP (incoming)</td>
<td>Mattermost clients (Web/Desktop/Mobile) and calls-offloader</td>
<td>Mattermost instance or <code>rtcd</code> service</td>
<td>To allow clients to establish connections that transport calls related media (e.g. audio, video). This should be open on any network component (e.g. NAT, firewalls) in between the instance running the plugin (or <code>rtcd</code>) and the clients joining calls so that UDP traffic is correctly routed both ways (from/to clients).</td>
</tr>
<tr>
<td>RTC (Calls plugin or <code>rtcd</code>)</td>
<td>8443</td>
<td>TCP (incoming)</td>
<td>Mattermost clients (Web/Desktop/Mobile) and calls-offloader</td>
<td>Mattermost instance or <code>rtcd</code> service</td>
<td>To allow clients to establish connections that transport calls related media (e.g. audio, video). This should be open on any network component (e.g. NAT, firewalls) in between the instance running the plugin (or <code>rtcd</code>) and the clients joining calls so that TCP traffic is correctly routed both ways (from/to clients). This can be used as a backup channel in case clients are unable to connect using UDP. It requires <code>rtcd</code> version >= v0.11 and Calls version >= v0.17.</td>
</tr>
<tr>
<td>API (<code>rtcd</code>)</td>
<td>8045</td>
<td>TCP (incoming)</td>
<td>Mattermost instance(s) (Calls plugin)</td>
<td><code>rtcd</code> service</td>
<td>To allow for HTTP/WebSocket connectivity from Calls plugin to <code>rtcd</code> service. Can be exposed internally as the service only needs to be reachable by the instance(s) running the Mattermost server.</td>
</tr>
<tr>
<td>STUN (Calls plugin or <code>rtcd</code>)</td>
<td>3478</td>
<td>UDP (outgoing)</td>
<td>Mattermost Instance(s) (Calls plugin) or <code>rtcd</code> service</td>
<td>Configured STUN servers</td>
<td>(Optional) To allow for either Calls plugin or <code>rtcd</code> service to discover their instance public IP. Only needed if configuring STUN/TURN servers. This requirement does not apply when manually setting an IP or hostname through the <a href="/administration-guide/configure/plugins-configuration-settings#ice-host-override">ICE Host Override</a> config option.</td>
</tr>
</tbody>
</table>
## Installation and Deployment
There are multiple ways to deploy RTCD, depending on your environment. We recommend the following order based on production readiness and operational control:
### Bare Metal or VM Deployment (Recommended)
This is the recommended deployment method for non-Kubernetes production environments, as it provides the best performance and operational control. For Kubernetes deployments, see the [Calls Deployment on Kubernetes](calls-kubernetes.mdx) guide.
<Warning>
These community-maintained scripts aren't published or reviewed by Mattermost. Review the script contents yourself before running them, and confirm they're suitable for your environment.
</Warning>
<Tip>
Looking for an automated setup? Check out these community-maintained [Calls Installation Scripts](https://github.com/bgardner8008/calls-install-scripts) for quick provisioning of the RTCD service on Ubuntu/Debian systems.
</Tip>
1. **Download and install the RTCD binary**:
Download the latest release from the [RTCD GitHub repository](https://github.com/mattermost/rtcd/releases):
```bash
# Create the RTCD directory structure
sudo mkdir -p /opt/rtcd
# Download the latest RTCD binary (adjust URL for your architecture)
# For Linux x86_64:
wget https://github.com/mattermost/rtcd/releases/latest/download/rtcd-linux-amd64
# Make the binary executable and move it to the installation directory
chmod +x rtcd-linux-amd64
sudo mv rtcd-linux-amd64 /opt/rtcd/rtcd
```
<Note>
Replace `rtcd-linux-amd64` with the appropriate binary for your system architecture (e.g., `rtcd-linux-arm64` for ARM64 systems). The binary should be placed at `/opt/rtcd/rtcd` as this is the expected location referenced in systemd service files and other documentation.
</Note>
2. **Create a configuration file** (`/opt/rtcd/rtcd.toml`):
Mattermost recommends using the official [config.sample.toml](https://github.com/mattermost/rtcd/blob/master/config/config.sample.toml) as a starting point. Download this file and use it as your base configuration.
3. Create a dedicated user for the RTCD service:
```bash
sudo useradd --system --no-create-home --shell /bin/false mattermost
```
4. Create the data directory and set ownership:
```bash
sudo mkdir -p /opt/rtcd/data/db
sudo chown -R mattermost:mattermost /opt/rtcd
```
5. Create a systemd service file (`/etc/systemd/system/rtcd.service`):
```ini
[Unit]
Description=Mattermost RTCD Server
After=network.target
[Service]
Type=simple
User=mattermost
Group=mattermost
ExecStart=/opt/rtcd/rtcd --config /opt/rtcd/rtcd.toml
Restart=always
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
```
6. Enable and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable rtcd
sudo systemctl start rtcd
```
7. Check the service status:
```bash
sudo systemctl status rtcd
```
### Docker Deployment
Docker deployment is suitable for development, testing, or containerized production environments:
1. Run the RTCD container with basic configuration:
```bash
docker run -d --name rtcd \
-e "RTCD_LOGGER_ENABLEFILE=true" \
-p 8443:8443/udp \
-p 8443:8443/tcp \
-p 8045:8045/tcp \
mattermost/rtcd:latest
```
<Note>
If you optionally use the `RTCD_API_SECURITY_ALLOWSELFREGISTRATION` setting, please note that it defaults to `false`. If enabled, it allows anyone who can connect to the service on the API port (8045) to successfully initiate calls. Understand the security implications of this setting before enabling it.
</Note>
2. For debugging purposes, you can enable more detailed logging:
```bash
docker run -d --name rtcd \
-e "RTCD_LOGGER_ENABLEFILE=true" \
-e "RTCD_LOGGER_CONSOLELEVEL=DEBUG" \
-p 8443:8443/udp \
-p 8443:8443/tcp \
-p 8045:8045/tcp \
mattermost/rtcd:latest
```
To view the logs:
```bash
docker logs -f rtcd
```
You can also use a mounted configuration file instead of environment variables:
```bash
docker run -d --name rtcd \
-p 8045:8045 \
-p 8443:8443/udp \
-p 8443:8443/tcp \
-v /path/to/config.toml:/rtcd/config/config.toml \
mattermost/rtcd:latest
```
For a complete sample configuration file, see the [RTCD config.sample.toml](https://github.com/mattermost/rtcd/blob/master/config/config.sample.toml) in the official repository.
### Kubernetes Deployment
For detailed information on deploying RTCD in Kubernetes environments, including Helm chart configurations, resource requirements, and scaling considerations, see the [Calls Deployment on Kubernetes](calls-kubernetes.mdx) guide.
## Configuration
### RTCD Configuration File
The RTCD service uses a TOML configuration file. Mattermost recommends using the official [config.sample.toml](https://github.com/mattermost/rtcd/blob/master/config/config.sample.toml) as your base configuration file.
<Note>
A notable setting to be aware of is `ice_host_override` under the `[rtc]` section. You may need to configure this setting explicitly, particularly when RTCD is deployed behind NAT, in complex network topologies, or when automatic address discovery via STUN is unreliable. Setting `ice_host_override` directly to your server's public IP address or hostname is the preferred approach.
</Note>
### TURN Configuration
For clients behind strict firewalls, you may need to configure TURN servers. In the RTCD configuration file, reference your TURN servers as follows:
```toml
[rtc]
# TURN server configuration
ice_servers = [
{ urls = ["turn:turn.example.com:3478"], username = "turnuser", credential = "turnpassword" }
]
```
We recommend using [coturn](https://github.com/coturn/coturn) for your TURN server implementation.
### System Tuning
For high-volume deployments, tune your Linux system:
1. Add the following to `/etc/sysctl.conf`:
```bash
# Increase UDP buffer sizes
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.optmem_max = 16777216
```
2. Apply the settings:
```bash
sudo sysctl -p
```
## Validation and Testing
After deploying RTCD, validate the installation:
1. **Check service status and version**:
```bash
curl http://YOUR_RTCD_SERVER:8045/version
# Should return a JSON object with service information
# Example: {"build_hash":"abc123","build_date":"2023-01-15T12:00:00Z","build_version":"0.11.0","goVersion":"go1.20.4"}
```
2. **Test UDP connectivity**:
Before testing, ensure the RTCD service is stopped, as it binds to the same port.
```bash
sudo systemctl stop rtcd
```
On the RTCD server:
```bash
sudo ncat -u -l -k -p 8443 -c '/bin/cat'
```
On a client machine:
```bash
sudo nmap -sU -p 8443 RTCD_SERVER_IP
```
If UDP connectivity is working, `nmap` reports as `open`.
Restart RTCD after the test:
```bash
sudo systemctl start rtcd
```
3. **Test TCP connectivity** (if enabled):
Run this check from a client machine:
```bash
nmap -p 8443 RTCD_SERVER_IP
```
If TCP fallback is enabled and reachable, `nmap` reports as `open`.
4. **Monitor metrics**:
Refer to [Calls Metrics and Monitoring](calls-metrics-monitoring.mdx) for setting up Calls metrics and monitoring.
## Horizontal Scaling
To scale RTCD horizontally:
1. **Deploy multiple RTCD instances**:
Deploy multiple RTCD servers, each with their own unique IP address.
2. **Configure DNS record**:
Set up a DNS record that points to multiple RTCD IP addresses:
```bash
rtcd.example.com. IN A 10.0.0.1
rtcd.example.com. IN A 10.0.0.2
rtcd.example.com. IN A 10.0.0.3
```
3. **Configure health checks**:
Set up health checks to automatically remove unhealthy RTCD instances from DNS.
4. **Configure Mattermost**:
In the Mattermost System Console, set the **RTCD Service URL** to your DNS name (e.g., `rtcd.example.com`).
When a call starts, the Mattermost server examines the available RTCD servers (via the configured DNS record) and starts the call on the RTCD server with the lowest CPU usage. All participants in the call will connect to that RTCD server; a single call cannot be shared across multiple servers.
## Upgrading RTCD
RTCD is released and upgraded independently of the Mattermost server. An upgrade consists of replacing the binary or container image and restarting the service. There's no database or schema migration involved. The two things to plan for are preserving the data store and timing the restart so that calls in progress aren't dropped.
Releases are published to the [RTCD GitHub repository](https://github.com/mattermost/rtcd/releases) as `rtcd-linux-amd64` and `rtcd-linux-arm64` binaries, and to Docker Hub as the [mattermost/rtcd](https://hub.docker.com/r/mattermost/rtcd) image.
### Preserve the Data Store
RTCD keeps a small local store at the path set by `data_source` in the `[store]` section of the configuration file, which defaults to `/tmp/rtcd_db`. It holds the client IDs registered by Mattermost servers along with a bcrypt hash of each client's authentication key. This is the only state RTCD persists, and it has to survive the upgrade:
- **Bare metal or VM.** The store lives outside the binary, so replacing the binary in place preserves it. Verify that `data_source` doesn't point at a location cleared on reboot: the default `/tmp/rtcd_db` is on a temporary filesystem on many distributions.
- **Docker.** The store is inside the container filesystem unless it's mounted, so recreating the container discards it. Mount a volume over the `data_source` path to keep it across image replacements.
Back the store up by copying its directory while the service is stopped.
<Warning>
If the store is lost, the credentials the Calls plugin holds no longer match anything on the RTCD side, and the plugin can't authenticate. Recovery depends on `allow_self_registration` under `[api.security]`:
- When it's disabled, which is the default, registration itself requires authenticating first, so the plugin can neither authenticate nor re-register. Calls stays broken until the store is restored or new credentials are provisioned.
- When it's enabled, the plugin detects the failure and registers again automatically, so a lost store recovers on its own.
Enabling `allow_self_registration` lets any client that can reach the API port register without authenticating. Leave it disabled on any RTCD service reachable from the internet, and enable it only on a private, access-controlled network.
</Warning>
<Important>
The Calls plugin opens its connection to RTCD when the plugin starts, and fails to start if the service isn't reachable. The same applies to the `calls-offloader` service when recording, transcription, or live captions are configured. RTCD therefore has to be up and running before the Mattermost server starts, or before Calls is re-enabled.
Failures at startup and failures later on behave differently:
- **During plugin activation**, an initial connection failure leaves Calls deactivated, and the server's plugin health check doesn't retry it, because it only monitors plugins that activated successfully. Once RTCD is reachable, restart the Calls plugin to bring it back.
- **After a connection is established**, later disconnections are retried automatically, so a brief RTCD restart needs no action on the Mattermost side. The plugin makes up to 8 reconnection attempts for a host before dropping it, and a dropped host that's still advertised in DNS is picked up again by the 10-second host check.
</Important>
### Version Compatibility
The Calls plugin enforces a minimum RTCD version and won't use a server running an older one.
For this reason, upgrade RTCD **before** upgrading the Mattermost server to a release shipping a newer version of Calls. When the plugin finds a server below the minimum version:
- On plugin activation, such as after a Mattermost server restart or upgrade, the failed version check prevents the Calls plugin from starting at all. This happens if *any* of the servers resolved by the **RTCD Service URL** fails the check, not only if all of them do.
- On a server discovered through DNS while the plugin is already running, the failure is logged as an error and the server isn't used. Calls continue to be routed to the remaining servers.
This means an RTCD server below the minimum version that's left in the DNS record can prevent Calls from starting the next time the Mattermost server restarts, even if calls are working at the time.
See [Important Upgrade Notes](/administration-guide/upgrade/important-upgrade-notes) for version-specific requirements. To check the version a server is running, query it directly with `curl http://YOUR_RTCD_SERVER:8045/version`.
### How RTCD Shuts Down
When RTCD receives a `SIGTERM` or `SIGINT` signal, it drains instead of exiting immediately: it waits for all active call sessions to end before shutting down. Calls in progress are never force-closed, and there's no drain timeout, so the process waits for as long as the last call lasts.
Two things follow from this behavior:
- The HTTP and WebSocket API listeners stay open while the service drains, so a draining server can still be assigned new calls. Remove the server from the DNS record *before* signalling the process; otherwise the plugin can keep sending new calls to it, and the drain may never complete.
- Any process supervisor that force-kills the service after a timeout cuts off the calls still running on it, and the default timeouts are generally shorter than a call.
`systemctl stop rtcd` sends `SIGTERM` to the service, and with the default `KillMode=control-group`, to every process in the unit's control group. systemd then waits for `TimeoutStopSec` before escalating to `SIGKILL`. When that value isn't set explicitly it inherits `DefaultTimeoutStopSec`, which gives a 90-second timeout on a stock systemd installation, so calls still running when the timeout expires are dropped.
The rolling upgrade below avoids this entirely by draining a server through DNS before stopping it, so the server is already idle by the time the service is stopped and the timeout never comes into play.
### Upgrading a Single Server
With a single RTCD server, an upgrade interrupts the service: no new calls can be started while the process is down, and because the service drains on shutdown, the restart doesn't complete until the existing calls end. There are two options:
- **Wait for the drain to complete.** Send `SIGTERM` and let the service exit after the last call ends. No call is dropped, but the length of the outage depends on how long those calls run, and new calls fail in the meantime. Note that the drain only runs to completion if the process supervisor allows it: with systemd's 90 second default stop timeout, a longer drain is cut short and the remaining calls are dropped.
- **Stop the service at a set time.** Notify participants, then force the process down with `SIGKILL` after a fixed period. Any calls still running are dropped and clients see those calls end.
Scheduling the upgrade for a period of low usage keeps either option short. See [Communicate scheduled maintenance](/administration-guide/upgrade/communicate-scheduled-maintenance) for templates to notify your users.
### Rolling Upgrade with Multiple Servers
When [horizontal scaling](#horizontal-scaling) is configured, servers can be upgraded one at a time without dropping calls. For each server in turn:
1. **Remove the server from DNS**:
Remove its IP address from the DNS record that the **RTCD Service URL** resolves to.
2. **Wait for the plugin to pick up the change**:
The plugin re-resolves the hostname every 10 seconds and flags servers that are no longer advertised. A flagged server is excluded from new calls, while the calls already running on it continue uninterrupted.
3. **Wait for the server to go idle**:
The `rtcd_rtc_sessions_total` metric reports the number of active RTC sessions per call group (see [RTCD Metrics](calls-metrics-monitoring#rtcd-metrics)). The server can be restarted safely once the sum across all groups reaches zero.
4. **Stop the service**:
```bash
sudo systemctl stop rtcd
```
Because the server is already idle at this point, it exits immediately and the stop timeout doesn't come into play.
5. **Install the new version**:
Replace the binary or container image with the new version and start the service again.
6. **Verify the upgrade**:
```bash
curl http://YOUR_RTCD_SERVER:8045/version
```
7. **Return the server to DNS**:
Add its IP address back to the DNS record. The plugin picks the server up on its next resolution cycle and starts assigning new calls to it again.
Once the server is back in rotation, repeat the process for the next one.
<Note>
- Since a call always lives entirely on a single server, restarting one server only ever affects the calls hosted on that server.
- Keep enough capacity in the fleet to absorb new calls while a server is out of rotation. Waiting for a server to reach zero sessions can take a while when calls are long-running.
</Note>
### Upgrading in Kubernetes
The [RTCD Helm chart](calls-kubernetes#rtcd-helm-chart) defaults to a `RollingUpdate` strategy with `maxUnavailable: 1`, and sets `configuration.terminationGracePeriod` to `18000` seconds (5 hours). That value maps to the pod's `terminationGracePeriodSeconds`, so Kubernetes allows a pod 5 hours to drain its calls before killing it.
Before changing the image, decide how the data store is handled. The chart ships no `PersistentVolumeClaim` template, and the store defaults to a path inside the container, so each replaced pod starts with an empty store. Since the store is a local embedded database with one instance per pod, a single volume can't be shared across replicas. There are two workable approaches:
- **Let pods re-register.** Enable `allow_self_registration` on a private, access-controlled network, as described in the warning above, and the plugin re-registers against each new pod automatically. This is the simpler option and needs no storage configuration.
- **Give each pod its own storage.** With `deploymentType: daemonset`, one pod runs per node, so a per-node `hostPath` mounted at the `data_source` path through `configuration.extraVolumes` and `configuration.extraVolumeMounts` gives each pod a store that survives image replacement.
To upgrade, set `image.tag` to the new version in your values file and apply the chart. Kubernetes sends `SIGTERM` to each pod it replaces, which starts the drain described above.
The chart doesn't set `maxSurge`, so a `Deployment` rollout uses the Kubernetes default and new pods can be created before the draining ones have exited. Expect old and new pods to run side by side for as long as the drains take, and size the node pool accordingly. `maxUnavailable: 1` bounds how many pods can be unavailable at once; it doesn't serialize the replacements.
<Warning>
Don't reduce `terminationGracePeriod` to a conventional value such as 30 or 60 seconds. When the grace period expires, Kubernetes sends `SIGKILL` and every call still running on that pod is dropped. The default of 5 hours is deliberately long enough to outlast extended meetings.
</Warning>
## Integration with Mattermost
Once RTCD is properly set up and validated, configure Mattermost to use it:
1. Go to **System Console > Plugins > Calls**
2. Set the **RTCD Service URL** to your RTCD service address (either a single server or DNS load-balanced hostname). Ensure you provide any generated credentials formulated in the URI (e.g., `http://clientID:authKey@rtcd.local`).
3. Save the configuration
4. Test by creating a new call in any Mattermost channel
5. Verify that the call is being routed through RTCD by checking the RTCD logs and metrics
## Other Calls Documentation
- [Calls Deployment Guide](calls-deployment-guide.mdx): Overview of deployment options and architecture
- [Calls Offloader Setup and Configuration](calls-offloader-setup.mdx): Setup guide for call recording and transcription
- [Calls Metrics and Monitoring](calls-metrics-monitoring.mdx): Guide to monitoring Calls performance using metrics and observability
- [Calls Deployment on Kubernetes](calls-kubernetes.mdx): Detailed guide for deploying Calls in Kubernetes environments
- [Calls Logging](calls-logging.mdx): Detailed guidance for collecting Calls logs and client diagnostics
For detailed Mattermost Calls configuration options, see the [Calls Plugin Configuration Settings](/administration-guide/configure/plugins-configuration-settings#calls) documentation.

View File

@@ -0,0 +1,31 @@
---
title: "Size your deployment"
description: Interactive deployment architecture builder. Pick a scale tier, deployment type, and hosting provider — get an architecture diagram and a bill of materials.
---
Pick your scale tier, deployment type, and hosting provider. The builder below renders a target architecture and a bill of materials sized to those choices. Sizing follows the [Mattermost scaling guide](/deployment-guide/scale/scaling-for-enterprise); provider SKUs are illustrative — verify against current pricing and regional / compliance constraints before committing to a procurement decision.
<DeploymentArchitectureBuilder />
## How to use this page
1. **Pick the scale tier** that fits your expected concurrent user count. Tiers correspond to the named bands in the scaling guide (Trial / Small / Medium / Large / Extra Large / Mega / Hyperscale).
2. **Pick a deployment type**:
- **Virtual machines** — Mattermost installed via the [Linux install paths](/deployment-guide/server/deploy-linux), with a separate VM per role (app, database, cache, search). Most common for self-hosted and private-cloud deployments.
- **Kubernetes** — Mattermost deployed via the [Mattermost Operator](/deployment-guide/server/deploy-kubernetes). The diagram and bill of materials swap the load balancer for an ingress controller and the app row for the Operator pattern.
3. **Pick a hosting provider** to see provider-specific SKU recommendations. **On-prem / Other** swaps managed services for self-managed equivalents (PostgreSQL on a VM, Redis on a VM, OpenSearch / Elasticsearch on a VM cluster, MinIO or NFS for object storage).
## What's next
Once you've sized the architecture:
- For **air-gapped** environments, also work through [Air-Gapped Operations](/deployment-guide/air-gapped-operations/quick-start-runbook). The architecture is the same; the install procedure and dependency-staging are different.
- For **HA tuning** (clustering, Redis configuration, multi-AZ database topology), see [High Availability cluster-based deployment](/deployment-guide/server/high-availability-cluster-based-deployment).
- For **version and hardware minimums** on the components you just sized, see [Software and hardware requirements](/deployment-guide/software-hardware-requirements), the last step in Plan.
- To **choose an install path**, see [Deploy the Mattermost server](/deployment-guide/server/deploy-server), which compares Kubernetes, Linux, and containers.
:::note[Where this page sits]
This is the second step in [Plan](/deployment-guide/server/server-deployment-planning), after [Application architecture](/deployment-guide/application-architecture). If you haven't picked the *shape* of the deployment yet, [Deployment Scenarios](/deployment-guide/deployment-scenarios/deployment-scenarios-index) covers which operational pattern fits (air-gapped, mission partner, DDIL, sovereign-Microsoft, out-of-band); this page sizes **the components** of whichever shape you pick.
:::

View File

@@ -0,0 +1,44 @@
---
title: "Deployment Guide"
---
This guide takes you from evaluating Mattermost through to running it in production: planning a deployment, preparing its dependencies, installing the server, securing and scaling it, and rolling out the desktop and mobile apps.
## Start here
Work through the sections below in order. Each one links to the pages inside it.
Two situations call for a different starting point. To evaluate Mattermost and see its capabilities before committing to a deployment plan, begin with [Quick Start Evaluation](/deployment-guide/quick-start-evaluation). If your environment has particular constraints, such as no internet egress, a coalition network, or an intermittently connected edge, read [Deployment Scenarios](/deployment-guide/deployment-scenarios/deployment-scenarios-index) first, because those constraints shape every decision that follows.
## Deployment scenarios
[Deployment Scenarios](/deployment-guide/deployment-scenarios/deployment-scenarios-index) describes the operational patterns Mattermost is deployed into - out-of-band communications, mission partner collaboration, DDIL operations, sovereign collaboration in Microsoft, and air-gapped environments. Read this before the sections below if any of them describe your environment, because the constraints shape every decision that follows.
## Server deployment
The steps below run in order. Each is a section in the sidebar.
- [Plan](/deployment-guide/server/server-deployment-planning) - Understand the [components of a deployment](/deployment-guide/application-architecture), [size it for your user count](/deployment-guide/deployment-architecture), decide whether you need [high availability and clustering](/deployment-guide/server/high-availability-cluster-based-deployment), and check the [software and hardware requirements](/deployment-guide/software-hardware-requirements).
- [Prepare](/deployment-guide/server/preparations) - Stand up the prerequisites before you install: the [database](/deployment-guide/server/prepare-database), [file storage](/deployment-guide/server/prepare-file-storage), [network access](/deployment-guide/server/prepare-network), an [NGINX reverse proxy](/deployment-guide/server/setup-nginx-proxy), and [TLS](/deployment-guide/server/setup-tls). Large deployments also provision [search infrastructure](/deployment-guide/scale/enterprise-search) and [caching with Redis](/deployment-guide/scale/redis) here.
- [Choose a deployment method](/deployment-guide/server/deploy-server) - Compare the methods, then install on [Linux](/deployment-guide/server/deploy-linux), [Kubernetes](/deployment-guide/server/deploy-kubernetes), or with [containers](/deployment-guide/server/deploy-containers).
- [Secure your deployment](/deployment-guide/encryption-options) - Encryption at rest and [in transit](/deployment-guide/transport-encryption).
- [Back up and recover](/deployment-guide/backup-disaster-recovery) - Backup strategy and [active/passive disaster recovery on AWS](/deployment-guide/disaster-recovery-aws).
- [Air-Gapped Operations](/deployment-guide/air-gapped-operations/) - The runbook, bill of materials, registry mirroring, and configuration changes for a deployment with no internet access.
- [General deployment troubleshooting](/deployment-guide/server/troubleshooting) - Log review, environment review, and the diagnostic data to gather for a support ticket. It also indexes the guides for specific layers - Docker, the database, and the desktop and mobile apps.
## Calls deployment
[Calls Deployment](/deployment-guide/calls/calls-deployment-guide) - Deploy and operate Calls infrastructure, including RTCD, the recording offloader, logging, and metrics.
## Deploy the apps
- [Desktop App Deployment](/deployment-guide/desktop/desktop-app-deployment) - Distribution and management for Windows, macOS, and Linux, including MSI and group policy.
- [Mobile App Deployment](/deployment-guide/mobile/mobile-app-deployment) - EMM distribution, Microsoft Intune MAM, custom builds, and running your own push proxy.
<Note>
- If you encounter issues that aren't covered in this documentation:
- Customers with a Mattermost subscription: See the [Mattermost Support Knowledge Base](https://support.mattermost.com/hc/en-us), or [contact Mattermost Support](https://support.mattermost.com/hc/en-us/requests/new) for assistance.
- Community deployments: Reference the [Mattermost community forums](https://forum.mattermost.com/).
- For advanced customization or integrations, refer to the [Open source components](/administration-guide/upgrade/open-source-components) documentation for details about extending Mattermost functionality.
</Note>

View File

@@ -0,0 +1,43 @@
---
title: "Deploy in Air-Gapped Environments"
---
## Overview
An air-gapped environment is one that's physically or logically isolated from the public internet. Nothing inside it can reach an external package repository, container registry, app store, or SaaS API, and nothing outside it can initiate a connection in. Mattermost is deployed and operated entirely from resources that already exist inside the boundary.
Organizations adopt this pattern when regulation or classification makes an internet connection unacceptable rather than merely undesirable — classified and cross-domain networks, defense and intelligence programs, and industrial or operational-technology networks where the collaboration platform must sit on the same isolated segment as the systems it supports.
<Note>
Consider [talking to a Mattermost expert](https://mattermost.com/contact-sales/) if your organization needs support deploying Mattermost and supporting services in an air-gapped environment.
</Note>
## How it differs from a connected deployment
The Mattermost server itself is the same product, deployed with the same [Linux](/deployment-guide/server/deploy-linux), [Kubernetes](/deployment-guide/server/deploy-kubernetes), or [container](/deployment-guide/server/deploy-containers) methods used anywhere else. What changes is everything around it:
- **Nothing is fetched at install time.** Packages, container images, Helm charts, plugin binaries, and desktop app installers must all be gathered on an internet-connected machine, staged into a private package mirror or container registry, and transferred across the air gap on approved media before the install begins.
- **Upgrades are a planned transfer, not a download.** Because each upgrade repeats that staging and transfer cycle, air-gapped deployments commonly track an [Extended Support Release](/product-overview/release-policy#extended-support-releases) rather than the monthly cadence.
- **Client apps are side-loaded.** Air-gapped devices can't reach the public app stores, so desktop and mobile apps are distributed through your own [desktop](/deployment-guide/desktop/desktop-app-deployment) and [mobile](/deployment-guide/mobile/mobile-app-deployment) deployment tooling.
- **Documentation travels with the deployment.** Administrators inside the boundary can't reach docs.mattermost.com, so the documentation is built and served locally.
## Constraints to plan for
Several Mattermost capabilities depend on an outbound internet connection and are unavailable or must be replaced:
- **Mobile push notifications** rely on the hosted push notification service. Either disable push notifications or run your own [push proxy](/deployment-guide/mobile/host-your-own-push-proxy-service) reachable from the isolated network.
- **The Mattermost Marketplace** is unreachable, so plugins are downloaded in advance and uploaded through the System Console.
- **Website link previews and the GIF picker** call third-party services and should be disabled.
- **In-product notices and telemetry** phone home, generate log errors when they can't, and should be turned off.
- **Email** requires an internal SMTP relay inside the boundary, or email invitations and verification must be disabled.
- **AI agents** must run against a [self-hosted, OpenAI-compatible LLM](/administration-guide/configure/agents-admin-guide) rather than a hosted model provider.
## Deploy an air-gapped environment
[Air-Gapped Operations](/deployment-guide/air-gapped-operations/) covers the full procedure: the step-by-step deployment runbook, the bill of materials to gather before you cross the air gap, how to stand up a private package mirror or container registry, and the server settings to change once Mattermost is running.
## Related deployment scenarios
- [Enterprise to Edge DDIL Operations](/deployment-guide/deployment-scenarios/deploy-ddil-operations) — for networks that are intermittently rather than permanently disconnected.
- [Out-of-Band Communications](/deployment-guide/deployment-scenarios/deploy-oob) — for an isolated, pre-provisioned system used during incident response.

View File

@@ -0,0 +1,93 @@
---
title: "Deploy for Enterprise to Edge DDIL Operations"
---
## Overview
Disconnected, Denied, Intermittent, and Limited (DDIL) network conditions present unique challenges for enterprise-to-edge operations. Field operations, remote deployments, and edge environments often become temporarily isolated from the internet, interrupting direct access to Microsoft 365 services such as Teams and Outlook.
Mattermost enables resilient collaboration by remaining fully operational in DDIL environments. Mission users continue to access self-hosted messaging collaboration, workflow automation, and mission planning within their mobile tactical network. No internet connectivity is required for enhanced collaboration functions, including mission tuned AI agents powered by self-hosted LLMs, and audio and screen sharing services.
When connectivity is restored, mission users regain access to M365 enterprise systems in addition to collaboration continuity with enterprise users through the [embedded Mattermost experience](/integrations-guide/mattermost-mission-collaboration-for-m365) inside their Microsoft Teams and Outlook applications. All mission activity during the period of disconnection becomes available across enterprise and tactical environments when connectivity returns.
Traditional cloud-only solutions fail in these scenarios, while fully disconnected systems don't integrate with enterprise tools during normal operations. This deployment architecture [extends sovereign collaboration with Microsoft Teams and Outlook](/deployment-guide/deployment-scenarios/deploy-sovereign-collaboration) to the tactical edge, providing a hybrid solution that enables enterprise integration and fully disconnected tactical collaboration.
![Mattermost diagram displays the deployment components and relationships outlined in detail in this document.](/images/architecture-ms-teams-ddil.png)
<Note>
Consider [talking to a Mattermost expert](https://mattermost.com/contact-sales/) if your organization needs support deploying Mattermost and supporting services for DDIL operations.
</Note>
## Architecture components
This hybrid deployment architecture provides optimal collaboration in both connected and disconnected states, including:
- **Enterprise Network:** Network containing enterprise services and continuous access to Microsoft 365. The network may have a firewall or access gateway protecting egress and ingress, such as network policies, IP allowlists, or WAFs depending on your networking configurations.
- **Enterprise Users:** Users within the enterprise network boundary accessing client applications for M365 services and Mattermost.
- **Tactical Network:** Operates independently during internet disconnections, hosting a self-contained Mattermost deployment to ensure mission users maintain collaboration capabilities.
- **Mission Users:** Tactical or edge users who may be intermittently disconnected from enterprise systems and Microsoft services.
- **Identity Providers:**
- **Microsoft Entra ID:** Enterprise users authenticate to M365 applications and Mattermost using [single sign-on Entra ID](/administration-guide/onboard/sso-entraid) via OpenID Connect (OIDC) or SAML. This provider only works with functioning internet access.
- **Alternative Local Identity Provider:** Deployed within the tactical network to provide authentication services for mission users during disconnected periods when M365 is unreachable. The local IdP serves as the primary authentication source for Mattermost and maintains an independent user directory that operates without internet connectivity.
- **Client Applications:**
- **Microsoft 365 Desktop Apps:** Teams and Outlook with [embedded Mattermost application.](/integrations-guide/mattermost-mission-collaboration-for-m365)
- When internet connected: Enables seamless enterprise-to-edge collaboration within a familiar interface.
- When internet disconnected: Microsoft services are unreachable, but embedded Mattermost application remains fully operational for tactical teams.
- **Mattermost Desktop Apps:** Access Mattermost via [desktop](/deployment-guide/desktop/desktop-app-deployment) or web apps in addition to the embedded views from Teams and Outlook. *(Optional - not shown)*
- **Mattermost Mobile Apps:** Access Mattermost via [iPhone and Android apps](/deployment-guide/mobile/mobile-app-deployment), with support for [ID-only push notifications](/deployment-guide/mobile/host-your-own-push-proxy-service) to ensure compliance with data sovereignty requirements. *(Optional when connectivity permits - not shown)*
- **Mattermost Deployment:** Mattermost deployed for sovereign tactical collaboration on local infrastructure, such as [Azure Local](https://learn.microsoft.com/en-us/azure/azure-local/manage/disconnected-operations-overview), supporting data residency regulations and [disconnected operations](/deployment-guide/deployment-scenarios/air-gapped-deployment). See [reference architecture](/deployment-guide/scale/server-architecture) documentation for Mattermost deployment configurations based on expected scale.
- **Mattermost Server:** Core application server handling tactical collaboration workloads, including:
- [Messaging Collaboration](/end-user-guide/collaborate/collaborate-index): DDIL-ready 1:1, group messaging, and structured channel collaboration with [rich integration capabilities](/integrations-guide/integrations-guide-index) and [enterprise-grade search](/deployment-guide/scale/scaling-for-enterprise#enterprise-search).
- [Workflow Automation](/end-user-guide/workflow-automation/workflow-automation-index): Playbooks provide structure, monitoring and automation for repeatable processes built-in to your local Mattermost deployment.
- [Project Tracking](/end-user-guide/project-management/project-management-index): Boards enables project management capabilities built-in to your local Mattermost deployment.
- [AI Agents](/administration-guide/configure/agents-admin-guide): AI Agents run against a local LLM hosted within your tactical network.
- [Audio & Screenshare](/deployment-guide/calls/calls-deployment-guide): Calls offers native real-time self-hosted audio calls and screen sharing within your tactical network.
- **Proxy Server:** The [proxy server](/deployment-guide/server/setup-nginx-proxy) handles HTTP(S) routing within the cluster, directing traffic between the server and clients accessing Mattermost services. NGINX is recommended for load balancing with support for WebSocket connections, health check endpoints, and sticky sessions. The proxy layer provides SSL termination and distributes client traffic across application servers.
- **PostgreSQL Database:** Stores persistent application data on a [PostgreSQL v13+ database](/deployment-guide/server/prepare-database) hosted locally within your tactical network.
- **Object Storage:** File uploads, images, and attachments are stored outside the application node on an [S3-compatible store](/deployment-guide/server/prepare-file-storage) or network/local storage, hosted locally within your tactical network.
- **Recording Instance:** `calls-offloader` job service, configured using the [Calls Offloader Setup and Configuration](/deployment-guide/calls/calls-offloader-setup) guide, to offload heavy processing tasks from Mattermost Calls to self-hosted infrastructure within your tactical network, such as recordings, transcriptions, and live captioning. *(Optional)*
- **Self-hosted integrations:** [Custom apps, plugins, and webhooks](/integrations-guide/integrations-guide-index) can be deployed within your tactical network. *(Optional - not shown)*
- **Self-hosted LLM:** Locally hosted [OpenAI compatible LLM](/agents/docs/providers) for agentic powered collaboration within your tactical network. *(Optional)*
- **Microsoft Global Network:** [World-wide network](https://learn.microsoft.com/en-us/azure/networking/microsoft-global-network) of Microsoft data centers, delivering public cloud services when internet connectivity permits.
## Operational Best Practices
The following best practices and deployment configurations help ensure that Mattermost remains compliant and operationally resilient in contested environments.
### User Authentication
DDIL environments require authentication infrastructure that remains fully operational without internet connectivity. Relying solely on cloud-based identity providers like Microsoft Entra ID creates a critical single point of failure when tactical networks become disconnected. To ensure mission users maintain authentication capabilities, deploy a locally hosted identity provider within the tactical network.
- **Enterprise Users:** Access Teams and Outlook by authenticating to Microsoft 365 via Entra ID, and their M365 session also provides access to the embedded Mattermost experience when the tactical network is internet connected.
- **Mission users:** Authenticate to Mattermost using a local IdP, such as [Keycloak](/administration-guide/onboard/sso-saml-keycloak) (open-source IdP with OIDC/SAML support), Active Directory with ADFS, or OpenLDAP with an OIDC bridge. When internet connected, the local IdP can optionally federate with Microsoft Entra ID to synchronize user accounts, credentials, and group memberships to enable access to Microsoft applications.
User accounts must be provisioned in the local IdP before disconnection occurs to ensure authentication services remain available throughout DDIL conditions.
### Sovereign AI
Deploy an [OpenAI compatible LLM](/administration-guide/configure/agents-admin-guide) on tactical infrastructure to ensure AI capabilities remain fully sovereign and operational in disconnected scenarios. A self-hosted LLM can power [message and call summarization, semantic search](/end-user-guide/agents#analyze-threads-and-channels), and [mission-tuned AI agents](/administration-guide/configure/agents-admin-guide#agent-configuration) without relying on public cloud AI services. This guarantees compliance with strict data handling mandates and enables AI-enhanced workflows to function locally, even during extended disconnections.
### Self-hosted audio & screensharing
Effective collaboration at the tactical edge requires all voice and screen sharing capabilities remain operational without reliance on the internet or third-party services. Deploy [Mattermost Calls](/deployment-guide/calls/calls-deployment-guide) in a self-hosted configuration, including:
- The `rtcd` service, configured using the [RTCD Setup and Configuration](/deployment-guide/calls/calls-rtcd-setup) guide, provides scalable, low-latency media routing hosted on-premises. Run multiple `rtcd` nodes for redundancy.
- The `calls-offloader` service, configured using the [Calls Offloader Setup and Configuration](/deployment-guide/calls/calls-offloader-setup) guide, offloads heavy processing tasks like recording, transcription and live captioning to a locally hosted compliance-approved job server.
### High availability and fault tolerance
Deploy Mattermost in a [cluster-based architecture](/deployment-guide/server/high-availability-cluster-based-deployment) to ensure continued availability during outages or hardware failures. High availability requires redundant infrastructure across each critical component:
- Application servers: Scale horizontally across multiple nodes with a load balancer distributing client traffic.
- Search service: [Elasticsearch or AWS OpenSearch Service](/deployment-guide/scale/scaling-for-enterprise#enterprise-search) provides optimized search performance with dedicated indexing for large-scale deployments.
- Object storage: Configure S3-compatible backends with erasure coding or replication for durability. All application servers must access shared file storage (NAS or S3) to ensure consistent data availability.
- Calls services: Run multiple `rtcd` and offloader nodes for resilience.
### Compliance and retention
Sovereign environments often require strict enforcement of retention policies, legal hold, and export controls. Configure Mattermost's built-in compliance features to meet organizational mandates.
- Enable [compliance export](/administration-guide/comply/compliance-export) and [monitoring](/administration-guide/comply/compliance-monitoring) to produce auditable exports of message data and user activity logs.
- Configure [message retention](/administration-guide/comply/data-retention-policy) and [legal hold](/administration-guide/comply/legal-hold) policies to align with applicable regulations.
- Integrate with your organization's [eDiscovery](/administration-guide/comply/electronic-discovery) and archiving systems as required.

View File

@@ -0,0 +1,146 @@
---
title: "Deploy for Mission Partner Collaboration"
---
## Overview
Mission partner collaboration extends [sovereign collaboration](/deployment-guide/deployment-scenarios/deploy-sovereign-collaboration) and [edge deployment](/deployment-guide/deployment-scenarios/deploy-ddil-operations) models to enable joint and allied operations across organizations using Mattermost, Microsoft 365 and legacy platforms. The solution architecture outlined in this document delivers a secure, sovereign, and intelligent mission environment that is federated across enterprise and coalition partner networks, enabling interoperability while maintaining compliance and control.
Joint mission collaboration is achieved through federation using [connected workspaces](/administration-guide/onboard/connected-workspaces), [Matrix connectors](https://mattermost.com/marketplace/mattermost-matrix-connector/), [guest accounts](/administration-guide/onboard/guest-accounts), and [auto-translation](https://github.com/mattermost/mattermost-plugin-channel-translations) for fast, accurate comprehension across globally distributed teams. Additionally, integrating external data feeds, workflow automation, and sovereign AI enables allied and partner users to collaborate at mission speed while enforcing zero-trust policies and maintaining data sovereignty.
Mattermost deployments may be hosted on-premises or in sovereign clouds, enabling allies and partners to retain control over sensitive data while extending interoperability to coalition partner enterprise networks.
## Collaboration challenges
Multi-agency collaborations face complex communication challenges:
- **Platform diversity:** Organizations often use different platforms, including Microsoft 365, Mattermost, and Matrix - with some using Teams for enterprise productivity [supplemented with Mattermost](/deployment-guide/deployment-scenarios/deploy-sovereign-collaboration) for sovereign collaboration, data residency, and offline resilience.
- **External access:** External partners need controlled access without full organizational membership.
- **Language barriers:** Organizations may speak different languages.
- **Compliance:** Data residency and compliance requirements vary across organizations.
## Solution Architecture
Traditional solutions require everyone to adopt the same platform or use insecure external tools. Mattermost powers a multi-layer approach addressing these collaboration challenges and diverse organizational needs, including:
- **Mattermost ↔ Mattermost Collaboration:** Organizations with Mattermost deployments establish secure connections and share specific channels using [connected workspaces](/administration-guide/onboard/connected-workspaces) over standard HTTPS/VPN.
- **External users ↔ Mattermost Collaboration:** Users from external organizations receive Mattermost [guest accounts](/administration-guide/onboard/guest-accounts) with least-privilege access. External users in Microsoft environments may access Mattermost using the [embedded application](/integrations-guide/mattermost-mission-collaboration-for-m365) in their Teams and Outlook clients.
- **Matrix / XMPP ↔ Mattermost Collaboration:** Organizations using legacy XMPP systems or Matrix servers connect to Mattermost via the [Matrix bridge plugin](https://github.com/mattermost/mattermost-plugin-matrix-bridge) for bidirectional communication.
- **Automatic Language Translation:** The AI-powered [automatic translation plugin](https://github.com/mattermost/mattermost-plugin-channel-translations) enables seamless communication across language barriers in channels with distributed teams.
![Mattermost diagram displays the deployment components and relationships outlined in detail in this document.](/images/architecture-mpe.png)
<Note>
Consider [talking to a Mattermost expert](https://mattermost.com/contact-sales/) if your organization needs support deploying Mattermost and supporting services for mission partner collaboration.
</Note>
## Architecture components
The deployment architecture includes the following components:
- **Allied or Partner Networks:** Globally distributed and segregated networks for each allied or partner organization.
- Networks may have a firewall or access gateway protecting egress and ingress, such as network policies, IP allowlists, or WAFs depending on networking configurations.
- Networks may [operate in contested environments](/deployment-guide/deployment-scenarios/deploy-ddil-operations) where internet connectivity is intermittent.
- **Users:** Enterprise, allied, and coalition partner users accessing client applications for Mattermost and/or Microsoft 365.
- **Microsoft Entra ID (Identity Provider):** Partnered organizations using Microsoft 365 services may use [single sign-on Entra ID](/administration-guide/onboard/sso-entraid) for unified authentication to M365 and Mattermost applications. *(Optional)*
- **Federation Services:**
- **Connected workspaces:** [Federated collaboration](/administration-guide/onboard/connected-workspaces) across partner networks, with seamless synchronization of messages, threads, and files.
- **Guest Accounts:** [Secure participation](/administration-guide/onboard/guest-accounts) of external mission partners with least-privilege access. *(Optional)*
- **Matrix & XMPP Interoperability:** [Federation with legacy partner systems](https://github.com/mattermost/mattermost-plugin-matrix-bridge) for cross-domain coalition collaboration. *(Optional)*
- **Client Applications:**
- **Mattermost Desktop Apps:** Access Mattermost directly by deploying [desktop](/deployment-guide/desktop/desktop-app-deployment) or web apps in your organization.
- **Mattermost Mobile Apps:** Access Mattermost via [iPhone and Android apps](/deployment-guide/mobile/mobile-app-deployment), with support for [ID-only push notifications](/deployment-guide/mobile/host-your-own-push-proxy-service) to ensure compliance with data sovereignty requirements. *(Optional - not shown)*
- **Microsoft 365 Desktop Apps:** For partnered organizations using Microsoft 365 services, Teams and Outlook can be deployed with the [embedded Mattermost application](/integrations-guide/mattermost-mission-collaboration-for-m365) for cross-domain partner collaboration within a familiar interface. *(Optional)*
- **Mattermost Deployments:** Mattermost deployed for sovereign collaboration on private cloud or local infrastructure, such as [Azure](/deployment-guide/server/deploy-kubernetes) or [Azure Local](https://learn.microsoft.com/en-us/azure/azure-local/manage/disconnected-operations-overview), to maintain compliance with STIG, FedRAMP, and NIST 800-53 standards. See [reference architecture](/deployment-guide/scale/server-architecture) documentation for Mattermost deployment configurations based on expected scale.
- **Mattermost Server:** Core application server handling collaboration workloads, including:
- [Messaging Collaboration](/end-user-guide/collaborate/collaborate-index): Sovereign 1:1, group messaging, and structured channel collaboration.
- [Workflow Automation](/end-user-guide/workflow-automation/workflow-automation-index): Playbooks provide structure, monitoring and automation for repeatable processes built-in to your sovereign Mattermost deployment.
- [Project Tracking](/end-user-guide/project-management/project-management-index): Boards enables project management capabilities built-in to your local Mattermost deployment. Boards enables project management capabilities built-in to your sovereign Mattermost deployment.
- [AI Agents](/administration-guide/configure/agents-admin-guide): AI Agents run against Azure OpenAI endpoints or a self-hosted LLM that is OpenAI-compatible.
- [Audio & Screenshare](/deployment-guide/calls/calls-deployment-guide): Calls offers native real-time self-hosted audio calls and screen sharing within your own network.
- **Proxy Server:** The [proxy server](/deployment-guide/server/setup-nginx-proxy) handles HTTP(S) routing within the cluster, directing traffic between the server and clients accessing Mattermost services, including requests from users in [connected organizations](/administration-guide/onboard/connected-workspaces). NGINX is recommended for load balancing with support for WebSocket connections, health check endpoints, and sticky sessions. The proxy layer provides SSL termination and distributes client traffic across application servers.
- **PostgreSQL Database:** Stores persistent application data on a [PostgreSQL v13+ database](/deployment-guide/server/prepare-database), such as [Azure Database for PostgreSQL](https://azure.microsoft.com/en-us/products/postgresql).
- **Object Storage:** File uploads, images, and attachments are stored outside the application node on an [S3-compatible store](/deployment-guide/server/prepare-file-storage) or an NFS (Network File System) server. [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs) can be used, but needs an S3-compatible proxy for Mattermost to interface with.
- **Recording Instance:** `calls-offloader` job service, configured using the [Calls Offloader Setup and Configuration](/deployment-guide/calls/calls-offloader-setup) guide, to offload heavy processing tasks from Mattermost Calls, such as recordings, transcriptions, and live captioning, to local infrastructure or private cloud. *(Optional)*
- **Integration framework:** [Custom apps, plugins, and webhooks](/integrations-guide/integrations-guide-index) can be deployed for real-time data integrations and alerting. *(Optional - not shown)*
- **Self-hosted LLM:** Locally hosted [OpenAI compatible LLM](/agents/docs/providers) for agentic powered collaboration. *(Optional)*
- **Microsoft Global Network:** [World-wide network](https://learn.microsoft.com/en-us/azure/networking/microsoft-global-network) of Microsoft data centers, delivering public cloud services including M365 and Azure OpenAI. *(Optional)*
## Operational Best Practices
The following best practices and deployment configurations help ensure that Mattermost remains secure, resilient, and interoperable across federated mission partner environments.
### Network Configuration
When external access is enabled through various federation capabilities, it is recommended to deploy Mattermost in a DMZ rather than on the internal network. This approach provides defense-in-depth and preserves security boundaries by isolating each connected server deployment from the enterprise network.
- **DMZ Deployment:** Position Mattermost application servers in the DMZ network segment, allowing both internal users and external partner federation traffic to access the collaboration platform through controlled network boundaries.
- **VPN Termination:** Terminate site-to-site VPN connections at the network perimeter or DMZ layer, enabling encrypted partner connectivity without exposing internal network infrastructure. VPN tunnels establish secure communication channels between partner organizations over the internet.
- **Firewall Segmentation:** Deploy ingress and egress firewall rules to control traffic flow between the DMZ, internal network, and external partner networks. Restrict database and object storage access to only originate from the DMZ segment where Mattermost servers reside.
- **Federation Traffic Isolation:** Partner federation traffic (Connected workspaces synchronize over HTTPS port 443/TCP) remains isolated within the DMZ, protecting internal systems while enabling partner collaboration and enforcing zero-trust principles across organizational boundaries.
### Resilient federation for joint operations
[Connected workspaces](/administration-guide/onboard/connected-workspaces) allow federated collaboration across multiple organizations and networks while maintaining local data control of each Mattermost deployment. Messages, threads, and files are securely synchronized between environments, ensuring mission continuity for multinational operations without requiring partners to join a single centralized deployment.
- Enforce [zero-trust access](/administration-guide/onboard/connected-workspaces#create-a-secure-connection) and ensure that only authorized mission partners can view or contribute to shared collaboration channels.
- Configure [auto-translation](https://github.com/mattermost/mattermost-plugin-channel-translations) in shared channels for seamless multilingual cross-domain collaboration.
- Mattermost instances can operate independently during outages or intermittent connectivity and sync conversations once connectivity returns.
Many mission partners continue to operate on legacy systems such as Matrix and XMPP. To enable joint operations without forcing migration, Mattermost supports [secure interoperability](https://github.com/mattermost/mattermost-plugin-matrix-bridge) with these environments for continuity of coalition communications while allowing modernized workflows to extend across federated networks.
Synchronize Mattermost channels with Matrix or XMPP rooms, allowing messages, threads, and attachments to flow across systems in real-time. Each organization maintains control of its data and infrastructure, while interoperability is enabled through federation bridges rather than centralized services.
### Controlled external access
Mission partner collaboration may require involving external users such as allied forces, contractors, or coalition partners that do not have Mattermost deployments themselves. [Guest accounts](/administration-guide/onboard/guest-accounts) provide a controlled mechanism to enable these users to participate in joint mission operations while maintaining strict compliance and security boundaries.
- Guest accounts are restricted to specific teams and channels. This ensures external users only have access to mission-critical resources necessary for their role.
- Guests can be granted access to shared channels, enabling collaboration with additional trusted organizations through [connected workspaces](/administration-guide/onboard/connected-workspaces).
- Guest users can be provided VPN credentials that allow them to connect specifically to the DMZ network segment where Mattermost resides. This architecture ensures external guests can access the collaboration platform without gaining access to internal corporate resources, files, or systems.
### Zero-trust access controls
Mission partner collaboration environments should adopt zero-trust principles by implementing [attribute-based access control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) to ensure access to mission channels is governed by dynamic attributes such as role, clearance, location, and mission context.
- Restrict channel access based on [user attributes](/administration-guide/manage/admin/user-attributes) rather than static groups.
- Continuously audit ABAC policies to ensure compliance with multinational operational and legal requirements.
### Sovereign AI
AI capabilities enhance mission collaboration with summarization, translation, semantic search, and decision support. Sovereign AI ensures these capabilities remain fully under organizational control, without reliance on public cloud services or external data processing. Deploying AI in a self-hosted or compliance-approved environment enables secure, mission-ready augmentation.
- Deploy [OpenAI compatible language models](/administration-guide/configure/agents-admin-guide) on local or private cloud infrastructure to maintain data sovereignty and ensure offline availability.
- Configure [custom agents](/administration-guide/configure/agents-admin-guide#agent-configuration) for summarization, workflow automation, and decision support while enforcing organizational compliance policies.
- Enable multilingual collaboration in shared channels using sovereign AI services to provide [real-time translations](https://github.com/mattermost/mattermost-plugin-channel-translations) across partner organizations.
- Embed AI into operational playbooks for automated task execution, situational summaries, and proactive recommendations.
- Allow authorized users from partner organizations to securely access locally hosted LLMs through shared channels in [connected workspaces](/administration-guide/onboard/connected-workspaces).
### High availability and fault tolerance
Deploy Mattermost in a [cluster-based architecture](/deployment-guide/server/high-availability-cluster-based-deployment) to ensure continued availability during outages or hardware failures. High availability requires redundant infrastructure across each critical component:
- Application servers: Scale horizontally across multiple nodes with a load balancer distributing client traffic.
- Search service: [Elasticsearch or AWS OpenSearch Service](/deployment-guide/scale/scaling-for-enterprise#enterprise-search) provides optimized search performance with dedicated indexing for large-scale deployments.
- Object storage: Configure S3-compatible backends with erasure coding or replication for durability. All application servers must access shared file storage (NAS or S3) to ensure consistent data availability.
- Calls services: Run multiple `rtcd` and offloader nodes for resilience.
### Sovereign audio & screensharing
Deploy [Mattermost Calls](/deployment-guide/calls/calls-deployment-guide) in a self-hosted configuration to ensure voice and screen sharing capabilities remain operational without reliance on the internet, and that media traffic does not traverse non-compliant third-party services.
- The `rtcd` service, configured using the [RTCD Setup and Configuration](/deployment-guide/calls/calls-rtcd-setup) guide, provides scalable, low-latency media routing hosted on-premises. Run multiple `rtcd` nodes for redundancy.
- The `calls-offloader` service, configured using the [Calls Offloader Setup and Configuration](/deployment-guide/calls/calls-offloader-setup) guide, offloads heavy processing tasks like recording, transcription and live captioning to a compliance-approved job server.
### Compliance and retention
Sovereign environments often require strict enforcement of retention policies, legal hold, and export controls. Configure Mattermost's built-in compliance features to meet organizational mandates.
- Enable [compliance export](/administration-guide/comply/compliance-export) and [monitoring](/administration-guide/comply/compliance-monitoring) to produce auditable exports of message data and user activity logs.
- Configure [message retention](/administration-guide/comply/data-retention-policy) and [legal hold](/administration-guide/comply/legal-hold) policies to align with applicable regulations.
- Integrate with your organization's [eDiscovery](/administration-guide/comply/electronic-discovery) and archiving systems as required.
### Mobile notifications
To prevent sensitive message content from being transmitted to external notification services such as Apple Push Notification Service (APNS) and Firebase Cloud Messaging (FCM), configure Mattermost to use [ID-only push notifications](/deployment-guide/mobile/host-your-own-push-proxy-service). In this mode, only a message identifier is sent to public push notification services, and the client retrieves the content securely from the Mattermost server over an encrypted channel.

View File

@@ -0,0 +1,112 @@
---
title: "Deploy for Out-of-Band (OOB) Communications"
---
import useBaseUrl from '@docusaurus/useBaseUrl';
When a critical incident disrupts an organization’s primary infrastructure—due to a cyberattack, cloud outage, or internal failure—a secure, independent communication channel becomes essential. Mattermost can serve as that channel by operating in an Out-of-Band (OOB) environment: isolated, pre-provisioned, and ready to support incident response and business continuity teams.
This document outlines architectural guidance for deploying Mattermost in an OOB scenario across [generic](#generic-oob-architecture), [AWS](#aws-based-oob-deployment), and [Azure](#azure-based-oob-deployment) environments.
## Generic OOB architecture
This platform-agnostic design establishes a fallback communication system, decoupled from primary networks and identity providers.
<img src={useBaseUrl('/images/oob-generic-architecture.png')} class="align-center" alt="Generic OOB Architecture" />
### Architecture components
- **Users (Cybersecurity, IR Teams)**: Pre-authorized personnel trained to access and use the OOB platform during emergencies. Credentials and access methods should be provisioned in advance.
- **Secure Access Layer**: A firewall or access gateway protecting entry into the OOB environment. May include network policies, IP allowlists, or WAFs.
- **Secondary IdP / Emergency Auth**: A dedicated identity provider not dependent on the organization’s primary SSO or IdP (e.g., a minimal Azure AD tenant, Okta org, or locally stored credentials with MFA).
- **VPN / Bastion Host**: A hardened jumpbox or independent VPN granting access to internal OOB components and Kubernetes control plane.
- **Failover DNS Manager**: Services like Cloudflare Load Balancer, Azure Traffic Manager, or Route 53 to monitor primary system health and reroute DNS to the OOB ingress.
- **Ingress Controller**: e.g., ingress-nginx to handle HTTP(S) routing within the cluster, directing traffic to Mattermost Web, API, and WebSocket endpoints.
- **Mattermost Operator & App**: Automates lifecycle of Mattermost instances in Kubernetes; ensures updates, scaling, and configuration consistency.
- **PostgreSQL Database**: Persistent storage for channels, messages, users, and configurations; can be self-hosted or managed externally with hardened access.
- **Backups**:
- **Velero**: Backs up Kubernetes resources to external object store (S3, Blob).
- **pg_dump / Cloud-native backup**: Regular logical exports or managed backups.
- **Object Storage**: Durable, versioned storage (e.g., S3, Azure Blob) for snapshots and dumps.
## AWS-based OOB deployment
Deploying Mattermost in AWS leverages managed services and strong isolation capabilities.
<img src={useBaseUrl('/images/oob-aws-architecture.png')} class="align-center" alt="AWS OOB Deployment diagram" />
### AWS components
- **Amazon EKS**: Managed Kubernetes for Mattermost Operator and application, with HA and auto-scaling.
- **Route 53**: DNS service for health-checked failover to the OOB environment.
- **Amazon Aurora PostgreSQL**: High-performance managed PostgreSQL with automated failovers.
- **Amazon S3**: Object storage for Velero snapshots, configurations, and database backups (with versioning and cross-region replication).
- **IAM Roles**: Scoped roles for EKS nodes and Velero using IRSA, enforcing least-privilege.
<Tip>
- Use separate AWS accounts or VPCs for full isolation.
- Configure Route 53 health checks against public or synthetic endpoints.
- Encrypt secrets and enforce least-privilege IAM policies.
</Tip>
## Azure-Based OOB deployment
For Azure customers, AKS and related services provide a robust OOB platform for Mattermost.
<img src={useBaseUrl('/images/oob-azure-architecture.png')} class="align-center" alt="Azure OOB Deployment diagram" />
### Azure components
- **Azure Kubernetes Service (AKS)**: Runs Mattermost workloads with native autoscaling and Azure AD integration.
- **Azure DNS + Traffic Manager**: Global traffic routing and DNS failover based on endpoint health.
- **Azure Database for PostgreSQL**: Managed DB service with automated backups and patching.
- **Azure Blob Storage**: Destination for Velero snapshots and DB dumps; supports lifecycle policies and secure access.
- **Azure AD (Secondary Tenant)**: Acts as the IdP for OOB; deployed in a separate directory with scoped permissions and MFA.
<Tip>
- Deploy in a dedicated subscription for security and billing separation.
- Use Azure Monitor for health checks and Traffic Manager probes.
- Harden AKS node pools and isolate workloads with namespaces and network policies.
</Tip>
## Operational guidelines
<table>
<colgroup>
<col style={{width: '20%'}} />
<col style={{width: '80%'}} />
</colgroup>
<thead>
<tr>
<th><strong>Domain</strong></th>
<th><strong>Recommendation</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>Access Control</td>
<td>Isolate authentication from primary infrastructure. Use MFA, secure vaults, and emergency tokens. Preload user accounts in the secondary IdP.</td>
</tr>
<tr>
<td>DNS Failover</td>
<td>Employ TTL-aware health checks via Route 53 or Traffic Manager. Monitor critical HTTP(S) or TCP endpoints.</td>
</tr>
<tr>
<td>Backup Strategy</td>
<td>Schedule frequent Velero and database backups. Store in versioned, encrypted object storage.</td>
</tr>
<tr>
<td>Disaster Recovery Drills</td>
<td>Conduct quarterly failover exercises: DNS switching, Mattermost access, and data restores.</td>
</tr>
<tr>
<td>Security</td>
<td>Treat OOB as Tier 0. Use hardened OS images, audit logging, strict RBAC, and centralized monitoring. Rotate secrets regularly.</td>
</tr>
</tbody>
</table>
Mattermost can be an effective OOB communication platform when deployed with isolation, automation, and operational readiness. Whether on AWS, Azure, or a generic environment, prioritize independence, simplicity, and resilience. Pair these designs with standard IR playbooks and routine failover testing to build a confident, secure response capability.

View File

@@ -0,0 +1,84 @@
---
title: "Deploy for Sovereign Collaboration in Microsoft"
---
## Overview
Agencies and critical infrastructure organizations often face strict data sovereignty requirements that restrict the use of public cloud services for sensitive collaboration.
Deploying Mattermost for sovereign collaboration within Microsoft Teams and Outlook enables secure, compliant, and resilient communication while maintaining workflow continuity inside familiar Microsoft interfaces. Users access both Teams channels and Mattermost channels [from within the Microsoft ecosystem](/integrations-guide/mattermost-mission-collaboration-for-m365), providing a single-pane-of-glass experience and eliminating application switching.
Mattermost can be hosted on-premises or in sovereign clouds, such as Azure GovCloud or Azure Local, ensuring that messages, files, recordings, and transcriptions remain in compliance-approved systems with encryption and strict policy enforcement.
Unified authentication with Microsoft Entra-ID extends your Microsoft enterprise IT investments while delivering the compliance, control, and resilience required for mission-critical operations or out-of-band scenarios.
This document outlines architectural guidance for enabling sovereign collaboration within your Microsoft ecosystem.
![Mattermost diagram displays the deployment components and relationships outlined in detail in this document.](/images/architecture-ms-teams-collab.png)
<Note>
Consider [talking to a Mattermost expert](https://mattermost.com/contact-sales/) if your organization needs support deploying Mattermost and supporting services for soverign collaboration within your Microsoft ecosystem.
</Note>
## Architecture components
The deployment architecture includes the following components:
- **Users:** Enterprise users within the network boundary accessing client applications for M365 services and Mattermost.
- **Microsoft Entra ID (Identity Provider):** Users authenticate to M365 applications and Mattermost using [single sign-on Entra ID](/administration-guide/onboard/sso-entraid) via OpenID Connect (OIDC) or SAML.
- **Client Applications:**
- **Microsoft 365 Desktop Apps:** Teams and Outlook with [embedded Mattermost application](/integrations-guide/mattermost-mission-collaboration-for-m365) for seamless collaboration within a familiar interface while enforcing regulatory compliance.
- **Mattermost Desktop Apps:** Access Mattermost via [desktop](/deployment-guide/desktop/desktop-app-deployment) or web apps in addition to the embedded views from Teams and Outlook. *(Optional - not shown)*
- **Mattermost Mobile Apps:** Access Mattermost via [iPhone and Android apps](/deployment-guide/mobile/mobile-app-deployment), with support for [ID-only push notifications](/deployment-guide/mobile/host-your-own-push-proxy-service) to ensure compliance with data sovereignty requirements. *(Optional - not shown)*
- **Mattermost Deployment:** Mattermost deployed for sovereign collaboration on enterprise-controlled infrastructure or private cloud, such as [Azure](/deployment-guide/server/deploy-kubernetes) or [Azure Local](https://learn.microsoft.com/en-us/azure/azure-local/manage/disconnected-operations-overview), to maintain compliance with STIG, FedRAMP, and NIST 800-53 standards. See [reference architecture](/deployment-guide/scale/server-architecture) documentation for Mattermost deployment configurations based on expected scale.
- **Mattermost Server:** Core application server handling collaboration workloads, including:
- [Messaging Collaboration](/end-user-guide/collaborate/collaborate-index): DDIL-ready 1:1, group messaging, and structured channel collaboration with [rich integration capabilities](/integrations-guide/integrations-guide-index) and [enterprise-grade search](/deployment-guide/scale/scaling-for-enterprise#enterprise-search).
- [Workflow Automation](/end-user-guide/workflow-automation/workflow-automation-index): Playbooks provide structure, monitoring and automation for repeatable processes built-in to your sovereign Mattermost deployment.
- [Project Tracking](/end-user-guide/project-management/project-management-index): Boards enables project management capabilities built-in to your sovereign Mattermost deployment.
- [AI Agents](/administration-guide/configure/agents-admin-guide): AI Agents run against Azure OpenAI endpoints or a self-hosted LLM that is OpenAI-compatible.
- [Audio & Screenshare](/deployment-guide/calls/calls-deployment-guide): Calls offers native real-time self-hosted audio calls and screen sharing within your own network.
- **Proxy Server:** The [proxy server](/deployment-guide/server/setup-nginx-proxy) handles HTTP(S) routing within the cluster, directing traffic between the server and clients accessing Mattermost services. NGINX is recommended for load balancing with support for WebSocket connections, health check endpoints, and sticky sessions. The proxy layer provides SSL termination and distributes client traffic across application servers.
- **PostgreSQL Database:** Stores persistent application data on a [PostgreSQL v13+ database](/deployment-guide/server/prepare-database), such as [Azure Database for PostgreSQL](https://azure.microsoft.com/en-us/products/postgresql).
- **Object Storage:** File uploads, images, and attachments are stored outside the application node on an [S3-compatible store](/deployment-guide/server/prepare-file-storage) or an NFS (Network File System) server. [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs) can be used, but needs an S3-compatible proxy for Mattermost to interface with.
- **Recording Instance:** `calls-offloader` job service, configured using the [Calls Offloader Setup and Configuration](/deployment-guide/calls/calls-offloader-setup) guide, to offload heavy processing tasks from Mattermost Calls, such as recordings, transcriptions, and live captioning, to enterprise-controlled infrastructure or private cloud. *(Optional)*
- **Self-hosted integrations:** [Custom apps, plugins, and webhooks](/integrations-guide/integrations-guide-index) can be deployed within the enterprise boundary. *(Optional - not shown)*
**Secure Access Layer:** A firewall or access gateway protecting entry into the enterprise network. This may include network policies, IP allowlists, or WAFs depending on your networking configurations. *(Optional)*
**Microsoft Global Network:** [World-wide network](https://learn.microsoft.com/en-us/azure/networking/microsoft-global-network) of Microsoft data centers, delivering public cloud services including M365 and Azure OpenAI.
**Azure OpenAI Service:** [LLM service](/agents/docs/providers) used for summarization, ai-enhanced search, and agent-assisted workflows, hosted within the Microsoft Global Network. *(Optional)*
## Operational Best Practices
The following best practices and deployment configurations help ensure that Mattermost remains compliant, resilient, and fully sovereign when deployed alongside Microsoft 365.
### High availability and fault tolerance
Deploy Mattermost in a [cluster-based architecture](/deployment-guide/server/high-availability-cluster-based-deployment) to ensure continued availability during outages or hardware failures. High availability requires redundant infrastructure across each critical component:
- Application servers: Scale horizontally across multiple nodes with a load balancer distributing client traffic.
- Database layer: Use PostgreSQL replication or managed HA services with automatic failover.
- Search service: [Elasticsearch or AWS OpenSearch Service](/deployment-guide/scale/scaling-for-enterprise#enterprise-search) provides optimized search performance with dedicated indexing for large-scale deployments.
- Object storage: Configure S3-compatible backends with erasure coding or replication for durability. All application servers must access shared file storage (NAS or S3) to ensure consistent data availability.
- Calls services: Run multiple `rtcd` and `calls-offloader` nodes for resilience.
### Sovereign audio & screensharing
Data sovereignty compliance may require that all voice and screen sharing traffic remain within enterprise-controlled infrastructure and does not traverse third-party services. Deploy [Mattermost Calls](/deployment-guide/calls/calls-deployment-guide) in a self-hosted configuration to ensure that Microsoft Teams users and Mattermost users collaborate without media ever leaving the sovereign network.
- The `rtcd` service, configured using the [RTCD Setup and Configuration](/deployment-guide/calls/calls-rtcd-setup) guide, provides scalable, low-latency media routing hosted on-premises. Run multiple `rtcd` nodes for redundancy.
- The `calls-offloader` service, configured using the [Calls Offloader Setup and Configuration](/deployment-guide/calls/calls-offloader-setup) guide, offloads heavy processing tasks like recording, transcription and live captioning to a compliance-approved job server.
### Compliance and retention
Sovereign environments often require strict enforcement of retention policies, legal hold, and export controls. Configure Mattermost's built-in compliance features to meet agency or sectoral mandates.
- Enable [compliance export](/administration-guide/comply/compliance-export) and [monitoring](/administration-guide/comply/compliance-monitoring) to produce auditable exports of message data and user activity logs.
- Configure [message retention](/administration-guide/comply/data-retention-policy) and [legal hold](/administration-guide/comply/legal-hold) policies to align with applicable regulations.
- Integrate with your organization's [eDiscovery](/administration-guide/comply/electronic-discovery) and archiving systems as required.
### Mobile notifications
To prevent sensitive message content from being transmitted to external notification services such as Apple Push Notification Service (APNS) and Firebase Cloud Messaging (FCM), configure Mattermost to use [ID-only push notifications](/deployment-guide/mobile/host-your-own-push-proxy-service). In this configuration, only a message identifier is sent to public push notification services and the client retrieves the content securely from the Mattermost server over an encrypted channel.

View File

@@ -0,0 +1,12 @@
---
title: "Deployment Scenarios"
---
This section outlines reference architectures and guidance tailored for specialized Mattermost deployment scenarios, enabling organizations to build secure, compliant, and resilient collaboration environments across diverse operational contexts.
Whether you’re implementing out-of-band communications, mission partner collaboration, sovereign collaboration within Microsoft ecosystems, or mission-critical operations at the edge, these architectures offer comprehensive guidance, design patterns, and best practices to ensure robust and reliable deployments.
- [Out-of-Band Communications](/deployment-guide/deployment-scenarios/deploy-oob) - Deploy Mattermost as an isolated, pre-provisioned communication system for incident response and business continuity.
- [Mission Partner Collaboration](/deployment-guide/deployment-scenarios/deploy-mission-partner) - Multi-organizational collaboration architecture with secure information sharing between allied networks and coalition partners.
- [Enterprise to Edge DDIL Operations](/deployment-guide/deployment-scenarios/deploy-ddil-operations) - Deployment patterns for Denied, Degraded, Intermittent, and Limited (DDIL) communication environments with offline capabilities.
- [Sovereign Collaboration in Microsoft](/deployment-guide/deployment-scenarios/deploy-sovereign-collaboration) - Integration architecture for sovereign cloud environments with Microsoft Teams, Outlook and other M365 services.
- [Air-gapped Deployment](/deployment-guide/deployment-scenarios/air-gapped-deployment) - Guidance and best practices when deploying Mattermost in air-gapped environments.

View File

@@ -0,0 +1,68 @@
---
title: "Desktop App Deployment"
---
<PlanAvailability slug="all-commercial" />
The Mattermost desktop app is available for Windows, macOS, and Linux operating systems, and offers [additional functionality](/end-user-guide/preferences/customize-desktop-app-experience) beyond the web-based experience.
Learn more about desktop app [software requirements](/deployment-guide/software-hardware-requirements#desktop-apps), [releases and server compatibility](/product-overview/mattermost-desktop-releases) as well as [what's changed across releases](/product-overview/desktop-app-changelog).
<Note>
Hitting problems with an installation or rollout? See [Desktop app troubleshooting](/deployment-guide/desktop/desktop-troubleshooting) at the end of this section, or [Deployment troubleshooting](/deployment-guide/server/troubleshooting) if the problem might not be specific to the desktop app.
</Note>
## Download
Download and install the Mattermost desktop app from the [App Store (macOS)](https://www.apple.com/app-store/), [Microsoft Store (Windows)](https://apps.microsoft.com/home?hl=en-US&gl=US), or by [using a package manager (Linux)](/deployment-guide/desktop/linux-desktop-install). We strongly recommend installing the desktop app on a local drive. Network shares aren't supported.
In Matermost, users are notified under **Downloads** when new desktop app releases become available. If managing the distribution of the Desktop app on behalf of users, you can recommend that your users disable desktop update notifications by going to **… \> File \> Settings** on Windows or **Mattermost \> Settings** on Mac and clearing the **Automatically check for updates** option.
See additional deployment options below to manage distribution of the desktop app to your users.
### Windows distribution channels
From desktop v6.1, organizations deploying on Windows have 2 primary distribution options:
- **Windows Store** (recommended): Provides automatic updates through the Microsoft Store infrastructure. This is the recommended option for most organizations seeking streamlined update management.
- **MSI packages**: Traditional deployment method with full control over installation timing. See the [MSI installer and group policy guide](/deployment-guide/desktop/desktop-msi-installer-and-group-policy-install) documentation for details.
The desktop v6.1 app includes in-app update notifications. All distribution channels (Windows Store, MSI, Mac App Store, Flathub, APT/RPM) release simultaneously to prevent notification and availability mismatches across deployment methods.
## Deployment options
Learn about installation, configuration, and management options for deploying the desktop app in your environment.
- [Distribute a custom desktop app](/deployment-guide/desktop/distribute-a-custom-desktop-app)
- [Silent Windows desktop distribution](/deployment-guide/desktop/silent-windows-desktop-distribution)
- [MSI installer and group policy guide](/deployment-guide/desktop/desktop-msi-installer-and-group-policy-install)
- [Custom dictionaries for Windows and Linux](/deployment-guide/desktop/desktop-custom-dictionaries)
- [Managed resources for the desktop app](/deployment-guide/desktop/desktop-app-managed-resources)
## Privacy and data handling
### Error reporting
From Mattermost Desktop v6.1, the desktop app includes automatic error reporting to help identify and fix crashes and stability issues.
**What information is sent**
Error reports include:
- Crash information and stack traces
- App version and platform details (OS type, architecture)
- Error messages and context
**What is NOT sent**
- Message content or user communications
- User credentials, passwords, or authentication tokens
- Personally identifiable information (PII)
- Server URLs or team names
**Privacy and user control**
Error reporting is **enabled by default**. Users can disable it at any time by going to **Settings \> Advanced \> Send error reports to help improve the app**. Restart the app to apply the change.
Organizations with data handling policies should inform users about this feature and provide guidance on whether to disable it. For organizations building the Desktop app from source, error reporting can be disabled at build time by omitting the `MM_DESKTOP_BUILD_SENTRYDSN` environment variable.

View File

@@ -0,0 +1,37 @@
---
title: "Desktop managed resources"
---
<PlanAvailability slug="all-commercial" />
The Mattermost desktop app supports managed resources. A managed resource can be any service available on the same hostname using the same protocol as the Mattermost server.
<Note>
Using this feature requires a <code>custom build of the Mattermost desktop app \</deployment-guide/desktop/distribute-a-custom-desktop-app\></code>.
</Note>
Add the path of a managed resource to your configuration file. When selected, it opens as a pop-up window in the Mattermost desktop app.
In addition to customizing the Mattermost Desktop App, the [Managed Resource Paths](/administration-guide/configure/environment-configuration-settings#managed-resource-paths) setting on the Mattermost server must be configured.
In the below example we add the managed resource `/video`.
``` text
[...]
managedResources: ['trusted', 'video'],
[...]
```
Here are two example server URLs each with valid and invalid managed resource URLs:
- Mattermost server: `https://mattermost.my.org`
- A valid video service: `https://mattermost.my.org/video`
- A valid conference service: `https://mattermost.my.org/conference`
- An invalid video service using a different protocol: `http://mattermost.my.org/video`
- An invalid conference service having a different origin: `https://conference.my.org`
- Mattermost server: `https://my.org/mattermost`
- A valid video service: `https://my.org/video`
- A valid conference service: `https://my.org/conference`
- An invalid video service using a different protocol: `http://my.org/video`
- An invalid conference service having a different origin: `https://conference.my.org`

View File

@@ -0,0 +1,29 @@
---
title: "Desktop App custom dictionaries"
---
import useBaseUrl from '@docusaurus/useBaseUrl';
<PlanAvailability slug="all-commercial" />
From Mattermost desktop app v4.7.1, custom dictionary definitions can be served through a URL on Windows and Linux. If custom dictionaries aren't specified, default dictionary definitions are obtained automatically from Chromium's CDNs (content delivery networks). On macOS, the Mattermost desktop app uses dictionary definitions provided by Apple that can't be customized.
## Prepare custom dictionaries
On Windows and Linux, the Mattermost desktop app uses [Hunspell Dictionary definitions](https://hunspell.github.io/) by default. You can download a copy of these dictionary definitions and modify them to fit specific needs.
To access a copy of these dictionary definitions:
1. Download a copy of `hunspell_dictionaries.zip` from the [latest electron release](https://github.com/electron/electron/releases/latest).
2. Extract the dictionary definitions from the ZIP file.
3. Convert the filenames to lowercase. (Chromium expects `en-us` rather than `en-US`). Once renamed, these definition files match the usage of using Chromium's CDN ones, and you can modify the definitions as needed.
4. Serve the extracted and converted files from a web server, and note the URL to the root folder of the dictionaries. Specify this URL as the **alternate dictionary URL** in the desktop app.
## Configure the Desktop App
1. In the Mattermost Desktop App, go to Settings by selecting <img src={useBaseUrl('/img/ui/dots-vertical_F01D9.svg')} alt="Use the More icon in the top left corner to access Mattermost desktop apps customization settings." className="theme-icon" /> **\> File \> Settings**.
2. Under **App Options**, ensure that the **Check spelling** option is enabled.
3. Select **Use an alternative dictionary URL** to specify the URL to the root folder of your custom dictionaries, then select **Save**.
## Remove custom dictionaries
Select **Revert to default** to stop using the specified dictionary definitions, and revert to default dictionary definitions.

View File

@@ -0,0 +1,243 @@
---
title: "Desktop MSI installer and group policy guide"
---
<PlanAvailability slug="all-commercial" />
This page provides guidance on installing the desktop app MSI and use Group Policies in Windows for Mattermost Enterprise or Professional. The MSI installer package can be downloaded [here](https://github.com/mattermost/desktop/releases/latest).
<Important>
**Per-machine installation from v6.1.0**: From Mattermost Desktop v6.1.0, the Windows MSI installer defaults to per-machine (system-wide) installation to meet enterprise compliance requirements. This changes deployment strategies and upgrade paths. See the [Deployment considerations for v6.1.0+](#deployment-considerations-for-v610) section below for details.
</Important>
## Windows distribution options
From desktop v6.1, organizations deploying on Windows have 2 primary distribution options:
- **Windows Store**: Primary option for automatic updates. Recommended for most users. The Windows Store version handles updates automatically through the Microsoft Store infrastructure.
- **MSI installer**: Direct download option for traditional deployment methods. This guide covers MSI deployment.
The desktop v6.1 app includes in-app update notifications that check the Mattermost website for new versions. All distribution channels (Windows Store, MSI, Mac App Store, Flathub, APT/RPM) release simultaneously to ensure users receive consistent update notifications regardless of their installation method.
## Upgrading to v6.1.0 with MSI installer
Users upgrading from earlier Desktop app versions using the MSI installer may need to recreate taskbar shortcuts once after the upgrade. The v6.1.0 installer uses a more reliable method for shortcut icons that prevents shortcuts from breaking during future upgrades. This fixes a long-standing issue where shortcuts could break during MSI upgrades. This is a one-time action for the upgrade to v6.1.0. Future upgrades to v6.1.2 and later won't require shortcut recreation. Windows Store deployments aren't affected by this change.
We recommend telling your users in advance that they may need to re-pin the taskbar shortcut after upgrading to desktop app v6.1. Desktop shortcuts are typically unaffected while taskbar shortcuts are most commonly impacted.
If a user reports a broken shortcut after upgrading to v6.1.0, the user should:
1. Right-click the broken shortcut on the taskbar and select **Unpin from taskbar**.
2. Launch Mattermost Desktop from the Start Menu.
3. Right-click the Mattermost icon in the taskbar.
4. Select **Pin to taskbar**.
## Download group policy and MSI installer files
1. Using a newly created Windows VM or dedicated Windows computer, make sure to use a Windows version that supports `Edit group policy` out of the box (i.e. Windows 10 Pro or Enterprise).
![When downloading group policy and MIS installer files, ensure to use a Windows version that supports Edit group policy.](/images/desktop/msi_gpo/msi_gpo_installation_test_00001.png)
2. Navigate to the [Mattermost Desktop](https://github.com/mattermost/desktop) repository on [GitHub.com](https://github.com/).
![Go to the mattermost/desktop repository on GitHub.](/images/desktop/msi_gpo/msi_gpo_installation_test_00002.png)
3. Navigate to the release page for [version v6.3.0](https://github.com/mattermost/desktop/releases/tag/v6.3.0) and download the appropriate installer for your version of Windows (32-bit vs. 64-bit).
4. Download the [source.zip](https://github.com/mattermost/desktop/archive/v6.3.0.zip) file as well to extract group policy files.
![In the mattermost/desktop repository on GitHub, go to the release page for the latest desktop release, then download the installer for your version of Windows. Download the source.zip file as well to extract group policy files.](/images/desktop/msi_gpo/msi_gpo_installation_test_00003.png)
## Install group policy files locally
The following group policies are available supporting a state option of Not Configured, Enabled, or Disabled:
> <table style={{width: '99%'}}>
> <colgroup>
> <col style={{width: '19%'}} />
> <col style={{width: '42%'}} />
> <col style={{width: '16%'}} />
> <col style={{width: '20%'}} />
> </colgroup>
> <thead>
> <tr>
> <th>Group policy</th>
> <th>Description</th>
> <th>Mattermost release</th>
> <th>Setting</th>
> </tr>
> </thead>
> <tbody>
> <tr>
> <td>Enable Server Management</td>
> <td>If disabled, management of servers in the app settings are disabled.</td>
> <td>v4.3 or later</td>
> <td><code>EnableServerManagement</code></td>
> </tr>
> <tr>
> <td>Default Server List</td>
> <td>Define one or more default, permanent servers.</td>
> <td>v4.3 or later</td>
> <td><code>DefaultServerList</code></td>
> </tr>
> <tr>
> <td>Update Notifications</td>
> <td>If disabled, in-app update notifications are not shown.</td>
> <td>v5.1 or later</td>
> <td><code>EnableAutoUpdater</code></td>
> </tr>
> </tbody>
> </table>
1. Browse to the folder the above files were downloaded to and unzip the `desktop-6.3.0.zip` file in place.
![Go to the install download directory on your machine and unzip the ZIP file.](/images/desktop/msi_gpo/msi_gpo_installation_test_00004.png)
2. Navigate to the unzipped `desktop-6.3.0\resources\windows\gpo` folder and copy the contents.
![Go to the \resources\windows\gpo directory and copy its contents.](/images/desktop/msi_gpo/msi_gpo_installation_test_00005.png)
3. Navigate to the `C:\Windows\PolicyDefinitions` folder and paste the files copied in the last step.
![Go to the Windows\PolicyDefinitions directory and paste the files you copied in the previous step.](/images/desktop/msi_gpo/msi_gpo_installation_test_00006.png)
4. Verify the `mattermost.admx` file is in the `C:\Windows\PolicyDefinitions` folder.
![Verify the mattermost.admx file is present in the Windows\PolicyDefinitions directory.](/images/desktop/msi_gpo/msi_gpo_installation_test_00007.png)
5. Verify the `mattermost.adml` file is in the `C:\Windows\PolicyDefinitions\en-US` folder.
![Verify the mattermost.adml file is present in the Windows\PolicyDefinitions\en-US directory.](/images/desktop/msi_gpo/msi_gpo_installation_test_00008.png)
<Note>
- `\\FQDNDomain\sysvol\FQDNDomain\Policies\PolicyDefinitions` can be used instead of `C:\Windows\PolicyDefinitions` if available.
- `\\FQDNDomain\sysvol\FQDNDomain\Policies\PolicyDefinitions\en-US` can be used instead of `C:\Windows\PolicyDefinitions\en-US` if available.
</Note>
**Disable update notifications**
Update notifications can be disabled by configuring the supported group policy. Changes to group policies require you to restart Mattermost for those changes to take effect.
## Configure Mattermost using group policy settings
1. Run the `Edit group policy` application by selecting **Start**, typing `gpedit` into the search field, then selecting the resulting **Edit group policy** search option.
![When configuring Mattermost using group policy settings, run the Edit group policy application by going to Start, typing gpedit into the search field, then selecting the resulting Edit group policy search option.](/images/desktop/msi_gpo/msi_gpo_installation_test_00009.png)
2. In the **Edit group policy** window, navigate to `Local Computer Policy\Computer Configuration\Administrative Templates\Mattermost`. In this example, double-click on `DefaultServerList` to set one or more default servers that will appear on app launch.
![In the Edit group policy window, go to Local Computer Policy \> Computer Configuration \> Administrative Templates \> Mattermost. To set one or more default servers to appear on app launch, for example, double-click on DefaultServerList to begin.](/images/desktop/msi_gpo/msi_gpo_installation_test_00010.png)
3. In the resulting window for **DefaultServerList**, select **Enabled** to turn the feature on, then select the **Show…** button in the **Options:** section of the window to add default servers.
![In the DefaultServerList window, enable the feature, then select Show..., located under Options, to add the default servers.](/images/desktop/msi_gpo/msi_gpo_installation_test_00011.png)
4. In the resulting window, add desired Mattermost servers using a memorable name (i.e., Community) and the web URL of the Mattermost server (i.e., [https://community.mattermost.com](https://community.mattermost.com)).
5. Select **OK** twice, then close the **Edit group policy** app.
![Add the default servers by name and by URL, then select OK twice to close the Edit group policy application.](/images/desktop/msi_gpo/msi_gpo_installation_test_00012.png)
## Deployment considerations for v6.1.0+
From Mattermost Desktop v6.1.0, the Windows MSI installer defaults to per-machine (system-wide) installation to meet enterprise compliance requirements. The application installs to `C:\Program Files\Mattermost` with registry keys in `HKLM` (HKEY_LOCAL_MACHINE), and requires administrator privileges for deployment.
Users upgrading from v5.9 to v6.0.4 with per-user installations must manually uninstall the old version before installing v6.1.0 to avoid duplicate installs. See [Desktop troubleshooting](./desktop-troubleshooting#upgrade-to-v610-fails-or-installs-duplicate-version-windows-msi) for detailed upgrade instructions.
## Multi-view and Group Policies
From desktop v6.0, users can run multiple Mattermost workspaces at the same time in the desktop app. Use existing methods to pre-provision multiple workspaces for users, as follows:
- On Windows, seed the approved list using the `DefaultServerList` Group Policy.
- For scripted installs, seed `config.json` on first run to include multiple entries in the `teams` array. See the [Silent Windows desktop distribution](/deployment-guide/desktop/silent-windows-desktop-distribution) documentation for details.
- To prevent users from adding or removing workspaces, use the existing `EnableServerManagement` Group Policy.
- Disable `EnableAutoUpdater` to turn off update notifications.
### Verify group policy settings have been applied
1. Open up the Registry Editor by selecting **Start**, typing `Registry Editor` in the search field, then selecting the **Registry Editor** option in the search results.
![When verifying group policy settings, open the Registery Editor by going to Start, typing Registry Editor into the search field, then selecting the resulting Registry Editor search option.](/images/desktop/msi_gpo/msi_gpo_installation_test_00013.png)
2. In the **Registry Editor** window, navigate to `Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Mattermost\DefaultServerList` and verify the servers you added using the **Edit group policy** app are listed.
3. Once verified, close the **Registry Editor**.
![Go to Computer \> HKEY_LOCAL_MACHINE \> SOFTWARE \> Policies \> Mattermost \> DefaultServerList to veryfiy the servers you added, then close the Registry Editor.](/images/desktop/msi_gpo/msi_gpo_installation_test_00014.png)
## Install the Mattermost Desktop App using the MSI installer
<Important>
- If the desktop app is running when you install via the MSI, Mattermost prompts you to close the app manually. After acknkowledging the prompt, select **Retry** to continue the MSI installation.
- Avoid selecting **Ignore**. If you do, force close the desktop app using Task Manager, ensure the `Mattermost.exe` process is stopped, and then restart the MSI installation.
</Important>
1. Within the folder the MSI installer was downloaded to, double-click on the MSI installer to begin the Mattermost Desktop installation process.
![Go to the folder where you downloaded the Mattermost Desktop App, and double-click on the MSI file to begin the installation process.](/images/desktop/msi_gpo/msi_gpo_installation_test_00015.png)
2. Installation of the MSI requires admin permission, so accept the resulting request to allow the installer to make changes to your device.
![You'll be prompted to allow the Mattermost Desktop App to make changes to your system. You must select Yes to continue with the installation process.](/images/desktop/msi_gpo/msi_gpo_installation_test_00016.png)
3. Select **Finish** when the installation is complete.
![When the installation is complete, select Finish.](/images/desktop/msi_gpo/msi_gpo_installation_test_00017.png)
### Verify group policy settings in the installed desktop app
1. Launch the newly installed Mattermost app from the **Start** menu.
2. Verify the app loads the first server you defined in the **Edit group policy** app.
![Verify group policy settings in the Mattermost Desktop App by opening the app from the Start menu, and verifying that the app loads the first server you defined in the Edit group policy.](/images/desktop/msi_gpo/msi_gpo_installation_test_00018.png)
## Advanced MSI options
<Important>
You must be a system admin to run these commands, or you must run them from an admin command prompt or PowerShell.
</Important>
### Silent installation
Perform a silent installation of the MSI by running the following command:
<Important>
Ensure the desktop app is closed before proceeding with a silent installation. Because it's a silent installation, Mattermost won't prompt you to close the desktop app.
</Important>
**Command Prompt:** `msiexec /i mattermost-desktop-v6.3.0-x64.msi /qn`
**PowerShell:** `Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList '/i mattermost-desktop-v6.3.0-x64.msi /qn'`
<Note>
\- Replace `<version>` with the actual version number (e.g., `v6.3.0`). - From v6.1.0, the MSI installs per-machine by default, requiring administrator privileges.
</Note>
From version v5.9.0 of the Mattermost desktop app, the following silent MSI installation options are also available.
### Specify an install directory
Use the `APPLICATIONFOLDER` parameter to specify an installation directory for the MSI installation:
- **Command Prompt:** `msiexec /i mattermost-desktop-v6.3.0-x64.msi APPLICATIONFOLDER="<install directory>"`
- **PowerShell:** `Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList '/i mattermost-desktop-v6.3.0-x64.msi APPLICATIONFOLDER="<install directory>"'`
Change this command as new versions of the Mattermost Desktop App are released.
## macOS managed configuration (MDM)
From Mattermost Desktop v6.2.0, admins can manage supported Desktop App configuration on macOS using managed preferences delivered through an MDM solution, in addition to the Windows group policy support described above. macOS managed preferences support the same configuration items as the Windows group policies listed in the [Install group policy files locally](#install-group-policy-files-locally) section, including predefined server lists, server management controls, and update notification controls.
To apply managed configuration on macOS, deploy a configuration profile that sets the supported keys to client Macs through your MDM solution. The Mattermost Desktop App reads managed preference values on launch; restart the app after changing managed configuration for new values to take effect.

View File

@@ -0,0 +1,229 @@
---
title: "Desktop app troubleshooting"
---
## Broken shortcuts after upgrading to v6.1.0 (Windows MSI only)
After upgrading to Mattermost Desktop v6.1.0 using the Windows MSI installer from an older release, the desktop or taskbar shortcut shows the wrong icon or fails to launch. This is due to a one-time icon handling change in the Windows MSI installer to improve shortcut reliability for future upgrades.
This issue doesn't block app usage and only affects Windows MSI installer upgrades from pre-v6.1.0 versions. Users can launch Mattermost from the Start Menu or a working desktop shortcut.Future upgrades to v6.1.1 and later will not require shortcut recreation.
To resolve this issue, recreate the shortcut:
1. Right-click the broken shortcut on the taskbar and select **Unpin from taskbar**.
2. Launch Mattermost Desktop from the Start Menu or a working desktop shortcut.
3. Right-click the Mattermost icon in the taskbar while the application is running.
4. Select **Pin to taskbar**.
The new shortcut will work correctly for all future upgrades.
Organizations standardizing on Windows installations can choose between Windows Store (recommended for automatic updates) or MSI packages (traditional deployment). The MSI method includes this one-time shortcut adjustment; the Windows Store method doesn't.
## Where is configuration stored locally?
The location of the Mattermost desktop app configuration file depends on the platform where you're running Mattermost (and, in the case of macOS, how you've chosen to install the app):
- Windows: `Users\<username>\AppData\Roaming\Mattermost`
- macOS installer: `/Users/<username>/Library/Application Support/Mattermost`
- macOS App Store: `/Users/<username>/Library/Containers/Mattermost.Desktop/Data/Library/Application Support/Mattermost` (via Finder: `~/Library/Application Support/Mattermost` as the extension is hidden)
- Linux: `~/.config/Mattermost`
<Note>
- Local configuration data is not automatically removed when uninstalling the desktop app. If you wish to remove all data, you must manually remove the files from the applicable location noted above.
- Prior to uninstalling, you can choose to log out of any active sessions. You can terminate active sessions from another Mattermost session in **Profile \> Security \> View and Logout of Active Sessions**, then select **Log Out**. Desktop app sessions are labeled as **Native Desktop App**.
</Note>
## Update notifications not appearing
If you're not seeing in-app update notifications when new versions are available:
1. **Check your internet connection**: Ensure outbound HTTPS communication to `mattermost.com` is allowed.
2. **Manually check for updates**: Go to **Help \> Check for Updates** or **Settings \> General \> Check for Updates Now** to trigger an immediate check.
3. **Verify update notifications are enabled**:
- On Windows: Go to **… \> File \> Settings** and ensure **Automatically check for updates** is enabled.
- On macOS: Go to **Mattermost \> Settings** and ensure **Automatically check for updates** is enabled.
4. **Check Group Policy settings** (Enterprise deployments): Your system administrator may have disabled update notifications via the `EnableAutoUpdater` Group Policy. Contact your IT department for clarification.
5. **Version previously skipped**: If you selected **Skip This Version** for the current release, manually check for updates to see it again.
## Update required screen
From Mattermost server v11.6.0, system admins can set a minimum Desktop App version in **System Console \> Site Configuration \> Customization \> Minimum desktop app version**. If your Desktop App version is below the configured minimum, you will see an update required screen and cannot access Mattermost until you update.
The screen includes a **Download** button that links to the apps download page configured by your admin. Select **Download** to go to that page, then follow the [manual update steps](/deployment-guide/desktop/desktop-troubleshooting#how-to-manually-update-mattermost-desktop) for your platform.
If you believe your app is already up to date, contact your system admin to confirm the configured minimum version.
## How to manually update Mattermost Desktop
From v6.1.0, Mattermost Desktop updates are manual. Follow these steps for your platform:
**macOS (App Store)**:
1. Open the App Store application.
2. Go to **Updates** section.
3. Find Mattermost Desktop and select **Update**.
**macOS (DMG installation)**:
1. Download the latest DMG from [https://mattermost.com/download](https://mattermost.com/download) or the [GitHub releases page](https://github.com/mattermost/desktop/releases/latest).
2. Open the downloaded DMG file.
3. Drag the Mattermost application to your Applications folder, replacing the existing version.
4. Restart Mattermost Desktop.
**Windows (Microsoft Store)**:
1. Open the Microsoft Store application.
2. Go to **Library \> Get updates**.
3. Find Mattermost and select **Update**.
**Windows (MSI installation)**:
1. Download the latest MSI installer from the [GitHub releases page](https://github.com/mattermost/desktop/releases/latest).
2. Run the MSI installer.
3. Follow the installation prompts (it will upgrade your existing installation).
**Linux**:
1. Visit the [GitHub releases page](https://github.com/mattermost/desktop/releases/latest).
2. Download the appropriate package for your distribution (AppImage, .deb, .rpm, Flatpak, etc.).
3. Install using your package manager or standard installation method.
<Tip>
For AppImage users: Simply download the new AppImage file and replace the old one. Make sure to make it executable: `chmod +x mattermost-desktop-*.AppImage`
</Tip>
## How do I access logs?
From Mattermost desktop v5.3, you can access logs via **Help \> Show logs**, which opens the file manager window showing the location of the log file.
## How do I download app diagnostics?
From Mattermost desktop v5.3, you can download a diagnostics text file via **Help \> Run diagnostics**, which can be attached to a Support ticket.
## Deep links open in the wrong workspace in multi-view
If you experience deep links opening in the wrong workspace, ensure all relevant workspaces are pre-provisioned via the Group Policy `DefaultServerList`. See the [multi-view and group policies](/deployment-guide/desktop/desktop-msi-installer-and-group-policy-install#multi-view-and-group-policies) documentation for details.
- Verify that workspace URLs match exactly (including protocol and subdomain) so links route to the intended workspace.
- Edit the workspace list to correct or remove stale entries, then retry the link.
## High CPU or memory when multiple workspaces open
Verify the device is powerful enough to run several workspaces concurrently. Close unused tabs and pop-out windows to reduce load.
Check the [desktop app advanced settings](/end-user-guide/preferences/customize-desktop-app-experience). Toggle **Use GPU hardware acceleration** off on systems with unstable drivers.
## Desktop App displays white screen while launching and doesn't load the page
1. Delete the local `Mattermost desktop app` configuration file. See the [Where is configuration stored locally?](#where-is-configuration-stored-locally) section above for file location details.
2. Reinstall the application.
## Upgrade to v6.1.0 fails or installs duplicate version (Windows MSI)
After installing v6.1.0 MSI, the old version still appears, both versions are present, or the upgrade doesn't seem to work. This is because you had a per-user installation from v5.9 to v6.0.4. From v6.1.0, the MSI installer defaults to per-machine (system-wide) installation. MSI installers cannot automatically upgrade across different installation contexts (per-user to per-machine).
To check your installation type before upgrading, open File Explorer.
- If Mattermost is in `C:\Program Files\Mattermost` or `C:\Program Files (x86)\Mattermost`: Per-machine install (upgrade will work normally)
- If Mattermost is in `C:\Users\<YourName>\AppData\Local\...`: Per-user install (requires manual uninstall before v6.1.0)
To resolve this issue, you must manually uninstall the old version before installing v6.1.0:
1. Uninstall both versions:
- Go to **Settings \> Apps** or **Control Panel \> Programs and Features**.
- Uninstall all Mattermost Desktop entries.
2. Download the v6.1.0 MSI installer again from the [releases page](https://github.com/mattermost/desktop/releases).
3. Install v6.1.0 with administrator privileges (it will install to `C:\Program Files\Mattermost`).
4. Future upgrades will work normally.
## "Installation has failed" dialog
The app data might be corrupted. Remove all the files in `%LOCALAPPDATA%\mattermost`, then try reinstalling the app.
## "The application "Mattermost" can't be opened" dialog
On macOS Catalina, this dialog can be triggered if the Mac Archive Utility is the default method for decompressing files. In this case using a third-party tool such as [Keka](https://www.keka.io) or [Unarchiver](https://macpaw.com/the-unarchiver) may resolve the problem.
## Desktop App window is black and doesn't load the page
1. Ensure you have installed the latest desktop app version available.
2. Clear your cache and reload the app from **View \> Clear Cache and Reload** or press <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>R</kbd> on Windows or Linux, or <kbd>⌘</kbd> <kbd>⇧</kbd> <kbd>R</kbd> on Mac.
3. Quit the app and restart it to see if the issue clears.
4. Disable GPU hardware acceleration.
> - On Windows or Linux, select **File \> Settings** and clear the **Use GPU hardware acceleration** option.
> - On macOS, select **Mattermost \> Settings** and clear the **Use GPU hardware acceleration** option.
5. If you are using a special video driver, such as Optimus, try disabling it to see if the problem is resolved.
## Desktop App window is white and doesn't load the page
1. Ensure you have installed the latest desktop app version available.
2. Delete the `%userprofile%\AppData\Roaming\Mattermost` directory on your local machine.
3. Reinstall the desktop app.
## Desktop App is not visible, but the Mattermost icon is in the Task Bar
This issue can occur on Windows in a multiple-monitor setup. When you disconnect the monitor that Mattermost is displayed on, Mattermost continues to display at screen coordinates that no longer exist.
To resolve this issue, you can reset the desktop app screen location by deleting the screen location file. When the file is not present, the desktop app displays on the primary monitor by default.
To reset the desktop app screen location:
1. If the desktop app is running, right-click the Mattermost icon in the task bar, then select **Close Window**.
2. Open Windows File Explorer, and go to the `%APPDATA%\Mattermost` folder.
3. Delete the file `bounds-info.json`.
## Desktop App constantly refreshes the page
This issue can occur when `localStorage` has an unexpected state. To resolve the issue:
- Windows: Open Windows File Explorer, go to the `%APPDATA%\Mattermost` folder, then delete the `Local Storage` folder.
- Mac: Open Finder, go to the `~/Library/Application Support/Mattermost` folder, then delete the `Local Storage` folder.
- Linux: Open the File Manager, go to the `~/.config/Mattermost` folder, then delete the `Local Storage` folder. Linux file managers may hide folders starting with a period by default. You can delete them from the terminal using `rm -rf ~/.config/Mattermost`.
## Desktop App constantly asks to log in to Mattermost server
This issue can occur after a crash or unexpected shutdown of the desktop app that causes the app data to be corrupted. To resolve the issue:
- Windows: Open Windows File Explorer, go to the `%APPDATA%\Mattermost` folder, then delete the `IndexedDB` folder and the `Cookies` and `Cookies-journal` files.
- Mac: Open Finder, go to the `~/Library/Application Support/Mattermost` folder, then delete the `IndexedDB` folder and the `Cookies` and `Cookies-journal` files.
- Linux: Open the file manager, go to the `~/.config/Mattermost` folder, then delete the `IndexedDB` folder and the `Cookies` and `Cookies-journal` files. Linux file managers may hide folders starting with a period by default. You can delete them from the terminal using `rm -rf ~/.config/Mattermost`.
## "Internal error: BrowserWindow 'unresponsive' event has been emitted"
Selecting **Show Details** on the dialog provides logs. Ways to resolve the issue:
1. Clear the cache via **View \> Clear Cache and Reload** or press <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>R</kbd> on Windows or Linux, or <kbd>⌘</kbd> <kbd>⇧</kbd> <kbd>R</kbd> on Mac.
2. Go to App Settings via **File \> Settings** (or by pressing <kbd>Ctrl</kbd> <kbd>,</kbd> on Windows or Linux, or <kbd>⌘</kbd> <kbd>,</kbd> on Mac) and unselect hardware acceleration.
## Desktop app not responsive within Citrix Virtual Apps or Desktop Environment
Append `Mattermost.exe;` to the Registry Key `HKLM\SYSTEM\CurrentControlSet\Services\CtxUvi\UviProcessExcludes` and reboot the system.
For further assistance, review the [Troubleshooting forum](https://forum.mattermost.com/c/trouble-shoot/16) for previously reported errors, or [join the Mattermost user community for troubleshooting help](https://mattermost.com/community/).
## Can I uninstall the desktop app I installed using snap on Linux?
Yes. Run the following command from a terminal window: `sudo snap remove mattermost-desktop`.
### Report Desktop App issues
When reporting issues found in the Mattermost desktop app, it's helpful to include the contents of the Developer Tools Console along with [the information on this page](https://support.mattermost.com/hc/en-us/articles/360060662492-Opening-a-Support-Ticket-for-Self-Managed-Deployments).
To access the Developer Tools Console:
1. In the menu bar, go to **View \> Developer Tools \> Developer Tools for Current Tab**.
2. Select the **Console** tab.
3. Right-click the log entry, then select **Save As**.
4. Save the file, then send it along with a description of your issue.
5. Close the console to disable the Developer Tools.
You can open an additional set of developer tools for each server you have added to the desktop app. The tools can be opened by pasting this command in the Developer Tools Console you opened with the steps described above:
> ``` javascript
> document.getElementsByTagName("webview")[0].openDevTools();
> ```

View File

@@ -0,0 +1,80 @@
---
title: "Distribute a custom desktop app"
---
<PlanAvailability slug="all-commercial" />
You can customize and distribute your own Mattermost desktop application by configuring [src/common/config/buildConfig.ts](https://github.com/mattermost/desktop/blob/master/src/common/config/buildConfig.ts).
1. Configure the desktop app's `buildConfig.ts` file. You can configure the following parameters to customize the user experience, including [defaultTeams](#defaultteams), [helpLink](#helplink), and [enableServerManagement](#enableservermanagement).
2. Follow the [Mattermost Desktop Development Guide](https://developers.mattermost.com/contribute/more-info/desktop/developer-setup/) to build the application.
3. Distribute the application to your users.
## `defaultTeams`
List of server URLs and their display names added to the desktop app by default, which the user cannot modify. Users can still add servers [through the Server Management page](#enableservermanagement) unless `enableServerManagement` is set to `false`. Expects an array of key-value pairs.
Example:
``` text
defaultTeams: [
{
name: 'example',
url: 'https://example.com'
},
{
name: 'mattermost',
url: 'https://www.mattermost.com'
}
]
```
## `helpLink`
The URL of the help documentation in **Help \> Learn More** menu bar item. If none is specified, the menu option is hidden. Expects a string.
Example:
``` text
helpLink: 'https://docs.mattermost.com/messaging/managing-desktop-app-servers.html'
helpLink: ''
```
## `enableServerManagement`
Controls whether users can add, edit, or remove servers on the app settings page. If set to false, at least one server must be specified for `defaultTeams` or else users cannot interact with any servers. Expects a boolean, true or false.
Example:
``` text
enableServerManagement: true
```
## Managed resources
[Custom builds](/deployment-guide/desktop/distribute-a-custom-desktop-app) of the Mattermost desktop app support managed resources which are services available on the same hostname and protocol as the Mattermost server.
To configure managed resources, add their path to the `managedResources` field in your configuration file. Selecting a managed resource opens it as a pop-up window in the desktop app.
Additionally, you must configure the :ref:Managed Resource Paths \<administration-guide/configure/environment-configuration-settings:managed resource paths\>\` server configuration setting. For example, adding the `/video` path:
``` text
[...]
managedResources: ['trusted', 'video'],
[...]
```
Below are examples of server URLs with valid and invalid managed resource URLs:
Server: `https://mattermost.my.org`
- Valid: `https://mattermost.my.org/video`
- Valid: `https://mattermost.my.org/conference`
- Invalid: `http://mattermost.my.org/video` (different protocol)
- Invalid: `https://conference.my.org` (different origin)
Server: `https://my.org/mattermost`
- Valid: `https://my.org/video`
- Valid: `https://my.org/conference`
- Invalid: `http://my.org/video` (different protocol)
- Invalid: `https://conference.my.org` (different origin)

View File

@@ -0,0 +1,153 @@
---
title: "Install desktop app on Linux"
---
import useBaseUrl from '@docusaurus/useBaseUrl';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<PlanAvailability slug="all-commercial" />
This page describes how to install the Mattermost desktop app on Linux.
<Tabs>
<TabItem value="ubuntu-debian" label="Ubuntu/Debian">
Both a `.deb` package (Beta), and an official APT repository is available for Debian 9 and for Ubuntu releases 20.04 LTS or later. Automatic app updates are supported and enabled. When a new version of the desktop app is released, your app updates automatically.
<Important>
The GPG public key has changed. If you had previously set up the repository on your system, you'll need to [download the new key](https://deb.packages.mattermost.com/pubkey.gpg). You can set the `UPDATE_GPG_KEY=yes` environment variable when running the setup script to configure it to overwrite the previous key on your system with the new one. The first step of installation then becomes: `curl -fsS -o- https://deb.packages.mattermost.com/setup-repo.sh | sudo UPDATE_GPG_KEY=yes bash`. Depending on your setup, additional steps may also be required, particularly for installations that don't rely on the repository setup script.
</Important>
1. At the command line, set up the Mattermost repository on your system:
> ``` sh
> curl -fsS -o- https://deb.packages.mattermost.com/setup-repo.sh | sudo bash
> ```
2. Install the Mattermost desktop app:
> ``` sh
> sudo apt install mattermost-desktop
> ```
3. Update the Mattermost desktop app:
> ``` sh
> sudo apt upgrade mattermost-desktop
> ```
## Snapcraft Package
A snap is available for systems that have Snapcraft installed. Snapcraft is installed by default on Ubuntu 16.04 and later, but for most other Linux distributions you can install it manually. To install Snapcraft, see [Install snapd](https://snapcraft.io/docs/installing-snapd) on the Snapcraft website for details.
1. At the command line, execute the following command:
> ``` sh
> sudo snap install mattermost-desktop
> ```
2. Run Mattermost as a desktop app.
<Tip>
You can review the current version of your desktop app by selecting the **More** <img src={useBaseUrl('/img/ui/dots-vertical_F01D9.svg')} alt="Use the More icon in the top left corner to access Mattermost desktop apps customization settings." className="theme-icon" /> icon located in the top left corner of the desktop app, then selecting **Help \> Version...**.
</Tip>
</TabItem>
<TabItem value="centos-rhel" label="CentOS/RHEL">
Beta `.rpm` packages are available for CentOS and RHEL 7 and 8. Automatic app updates aren't supported. You must update your app manually.
## Install the Mattermost desktop app
1. Download the latest version of the Mattermost desktop app for 64-bit systems: [mattermost-desktop-6.3.0-linux-x86_64.rpm](https://releases.mattermost.com/desktop/6.3.0/mattermost-desktop-6.3.0-linux-x86_64.rpm)
2. At the command line, execute the following command:
> ``` sh
> sudo rpm -i mattermost-desktop-6.3.0-linux-x86_64.rpm
> ```
3. Run Mattermost as a desktop app.
To manually update the desktop app, run the following command:
> ``` sh
> sudo rpm -u mattermost-desktop-6.3.0-linux-x86_64.rpm
> ```
<Tip>
You can review the current version of your desktop app by selecting the **More** <img src={useBaseUrl('/img/ui/dots-vertical_F01D9.svg')} alt="Use the More icon in the top left corner to access Mattermost desktop apps customization settings." className="theme-icon" /> icon located in the top left corner of the desktop app, then selecting **Help \> Version...**.
</Tip>
</TabItem>
<TabItem value="flatpak" label="Flatpak">
From Mattermost Desktop v6.1, Flatpak packages are available for Linux systems. Flatpak is a universal Linux package format that provides a sandboxed environment and includes runtime dependencies. The Flatpak version is currently in **beta**.
<Note>
Flatpak requires the Flatpak runtime to be installed on your system. The Mattermost Desktop Flatpak package uses Freedesktop Platform/SDK 25.08 and Electron BaseApp 25.08. Wayland display server support is enabled by default.
</Note>
## Available architectures
Flatpak packages are available for:
- **x86_64** (Intel/AMD 64-bit processors)
- **aarch64** (ARM 64-bit processors)
## Install Flatpak
1. Ensure Flatpak is installed on your system. If not, see the [Flatpak setup guide](https://flatpak.org/setup/) for your distribution.
2. Download the latest Mattermost Desktop Flatpak package for your architecture from the [Desktop App's Github releases page](https://github.com/mattermost/desktop/releases):
- For x86_64: `mattermost-desktop-&#123;VERSION&#125;-linux-x86_64.flatpak`
- For aarch64: `mattermost-desktop-&#123;VERSION&#125;-linux-aarch64.flatpak`
3. Install the Flatpak package:
> ``` sh
> flatpak install mattermost-desktop-&#123;VERSION&#125;-linux-&#123;ARCH&#125;.flatpak
>
> Replace ``&#123;VERSION&#125;`` with the version number (e.g., ``6.3.0``) and ``&#123;ARCH&#125;`` with your architecture (``x86_64`` or ``aarch64``).
> ```
4. Run Mattermost as a desktop app:
> ``` sh
> flatpak run com.mattermost.Desktop
> ```
## Considerations
- The Flatpak version runs in a sandboxed environment, which may affect certain integrations or file access patterns.
- Automatic app updates are handled through the Flatpak update mechanism.
- The application requires access to Flathub or a compatible Flatpak repository for runtime dependencies.
<Tip>
You can review the current version of your desktop app by selecting the **More** <img src={useBaseUrl('/img/ui/dots-vertical_F01D9.svg')} alt="Use the More icon in the top left corner to access Mattermost desktop apps customization settings." className="theme-icon" /> icon located in the top left corner of the desktop app, then selecting **Help \> Version...**.
</Tip>
</TabItem>
<TabItem value="generic-linux" label="Generic Linux">
The Desktop app is available in two formats which are usable on most Linux distributions: a compressed tarball, and an AppImage binary. Both can be downloaded from the [Desktop App's Github releases page](https://github.com/mattermost/desktop/releases). Automatic app updates are supported and enabled on AppImage binary builds. When a new version of the desktop app is released, your app updates automatically.
For instructions on how to use the AppImage binary, please refer to the [AppImage Quickstart documentation page](https://docs.appimage.org/introduction/quickstart.html).
## Install the Desktop App's compressed tarball
1. Download the latest version of the Mattermost desktop app for 64-bit systems: [mattermost-desktop-6.3.0-linux-x64.tar.gz](https://releases.mattermost.com/desktop/6.3.0/mattermost-desktop-6.3.0-linux-x64.tar.gz)
2. Extract the archive to a convenient location, then give `chrome-sandbox` in the extracted directory the required ownership and permissions: `sudo chown root:root chrome-sandbox && sudo chmod 4755 chrome-sandbox`
3. Execute `mattermost-desktop` located inside the extracted directory.
4. To create a Desktop launcher, open the file `README.md`, and follow the instructions in the **Desktop launcher** section.
</TabItem>
</Tabs>

View File

@@ -0,0 +1,116 @@
---
title: "Silent Windows desktop distribution"
---
<PlanAvailability slug="all-commercial" />
You can distribute the official Windows desktop app silently to end users using the MSI installer, pre-configured with server URLs and settings. For comprehensive MSI installation options including Group Policy configuration, see the [MSI installer and Group Policy guide](/deployment-guide/desktop/desktop-msi-installer-and-group-policy-install).
## Silent MSI installation
1. Download the latest Windows MSI installer from the [Mattermost Desktop releases page on GitHub](https://github.com/mattermost/desktop/releases/latest).
2. Move the MSI file to a shared location such as a file server with read-only permissions.
3. Use your software deployment tool (SCCM, Intune, PDQ Deploy, etc.) to deploy the MSI with silent installation parameters:
**Silent install:**
``` text
msiexec /i \\SERVER\shared_folder\mattermost-desktop-v6.1.0-x64.msi /qn
```
## Pre-configuration with config.json
To pre-configure servers and settings, create a `config.json` file in the user's Mattermost data directory before first launch:
**Location**: `%APPDATA%\Mattermost\config.json`
**Example config.json**:
``` json
{
"version": 2,
"teams": [
{
"name": "core",
"url": "https://community.mattermost.com",
"order": 0
},
{
"name": "hq",
"url": "https://hq.example.com",
"order": 1
}
],
"showTrayIcon": true,
"trayIconTheme": "light",
"minimizeToTray": true,
"notifications": {
"flashWindow": 2,
"bounceIcon": true,
"bounceIconType": "informational"
},
"showUnreadBadge": true,
"useSpellChecker": true,
"enableHardwareAcceleration": true,
"autostart": false,
"spellCheckerLocale": "en-US",
"darkMode": false
}
```
**Batch script for silent install with pre-configuration:**
``` batch
rem Install Mattermost desktop app silently
msiexec /i \\SERVER\shared_folder\mattermost-desktop-v6.1.0-x64.msi /qn
rem Wait for installation to complete
timeout /t 10
rem Create config directory if it doesn't exist
if not exist "%APPDATA%\Mattermost" mkdir %APPDATA%\Mattermost
rem Copy pre-configured config.json
copy \\SERVER\shared_folder\config.json %APPDATA%\Mattermost\config.json
```
## Windows App: Silently removing the app
The MSI installer can be silently uninstalled using:
``` text
msiexec /x {PRODUCT-CODE-GUID} /qn
```
To find the product code for your installed version:
``` powershell
Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -like "*Mattermost*"} | Select-Object Name, IdentifyingNumber
```
Alternatively, uninstall by searching for the MSI file:
``` text
msiexec /x mattermost-desktop-v6.1.0-x64.msi /qn
```
## Migration from EXE to MSI
Organizations currently using the Windows EXE installer must migrate to the MSI installer or Microsoft Store version:
1. **Uninstall existing EXE version** (if desired, optional):
``` text
%userprofile%\AppData\local\Programs\mattermost-desktop\Uninstall Mattermost.exe /currentuser /S
```
2. **Install MSI version** using silent installation commands above.
3. **User data preservation**: User settings and credentials are stored in `%APPDATA%\Mattermost` and will be preserved across the migration.
<Note>
The EXE installer will not receive v6.1.0 or later updates. Plan your migration accordingly.
</Note>

View File

@@ -0,0 +1,375 @@
---
title: "Active/passive DR deployment on AWS"
---
<PlanAvailability slug="all-commercial" />
Before you begin, ensure the following are in place:
- AWS account access with IAM permissions to manage RDS, S3, and OpenSearch resources in both regions
- A chosen primary and secondary AWS region pair for failover
- An existing, healthy Mattermost primary deployment
- DNS control over the domain used to reach Mattermost, so you can redirect traffic during failover
- Required RDS Aurora PostgreSQL global cluster permissions and a verified, restorable database backup
- OpenSearch 2.x with fine-grained access control available in both regions
- Network connectivity between the primary and secondary regions confirmed
Enterprise customers who use Mattermost for mission-critical operations must ensure continuous availability and operational resilience. A robust disaster recovery strategy is essential to mitigate risks associated with data center failures, ensuring that users can access Mattermost seamlessly, even in the event of unexpected outages.
This page details the steps needed to set up Mattermost in an active/passive disaster recovery configuration on AWS, and how to fail over from one data center to another.
<Tip>
To learn how to safely upgrade your deployment in Kubernetes for High Availability and Active/Active support, see the [Upgrading Mattermost in Kubernetes and High Availability Environments](/administration-guide/upgrade/upgrade-mattermost-kubernetes-ha) documentation.
</Tip>
## Set up in one data center
As a first step, set up Mattermost in a single data center. The following diagram illustrates a basic single data center architecture:
![An architecture diagram showing a single proxy that's forwarding traffic to 2 nodes, a database with single writer + n readers, and an S3 bucket and ES/OS using AWS OpenSearch service.](/images/dr1.png)
The diagram above has a single proxy, forwarding traffic to 2 nodes. There's also a database with single writer + n readers and an S3 bucket and ES/OS using AWS OpenSearch service.
At this stage, we are ignoring other details like LDAP/SAML, SMTP etc.
<Tip>
The following architecture would be implemented when an entire region goes down. It does not cover the case when a single server/service goes down. For example:
- If a single app node goes down, follow best practices to provision a new node.
- If a database replica node goes down, create a new replica from AWS console. Or set a policy to do so automatically.
</Tip>
## Replicate database
The next tasks include creating a global AWS Cluster.
1. Select the RDS instance in the AWS Console, and expand the **Actions** menu to select **Add AWS Region**.
2. Choose the secondary region and enter the other details.
<Warning>
Select the **Enable write forwarding** option on the secondary cluster to help forward write operations from secondary to primary. See the [AmazonRDS write forwarding](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-global-database-write-forwarding-apg.html#aurora-global-database-write-forwarding-enabling-apg) documentation for details.
Also verify the PostgreSQL version and ensure it allows `write forwarding`. Not all PostgreSQL versions allow it. See the [Amazon RDS write forwarding region and version availability](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-global-database-write-forwarding-apg.html#aurora-global-database-write-forwarding-regions-versions-apg) documentation for details.
</Warning>
You should now have a global cluster with the primary cluster in `us-west-1`, and the secondary cluster in `us-east-1`:
![A screenshot of the AWS console with a global RDS cluster where the primary cluster is us-west-1 and the secondary cluster is us-east-1.](/images/dr2.png)
## Replicate S3 bucket
1. Create a new S3 bucket in the secondary region.
2. Back in the original bucket, go to the **Properties** tab, and enable **Bucket versioning**.
3. Go to the **Management** tab, scroll down to **Replication Rules**, and create a new replication rule.
4. In the rule, select the source bucket, and then choose **Apply to all objects in the bucket** to replicate everything in the bucket.
5. Choose the destination bucket.
6. For the IAM role, select **Create new role**.
<Warning>
Select the **Replica modification sync** option for the bucket to help keep the replica and source buckets in sync with each other.
</Warning>
7. Select **Save**.
8. Select **Yes** when prompted to start a job to replicate any existing objects to the secondary bucket or not.
9. Perform these same steps on the secondary bucket.
Now you have bi-directional replication working between these S3 replica and source buckets.
## Replicate ES/OS storage
1. To replicate ES/OS storage, set up CCR (cross-cluster replication) for AWS OpenSearch with the following requirements:
> - Elasticsearch 7.10 or OpenSearch 2.x
> - Fine-grained access control enabled
> - Node-to-node encryption enabled
<Tip>
If you are already running OpenSearch 2.x, all you need to do is enable fine-grained access control — node-to-node encryption is enabled automatically once fine-grained access control is turned on.
</Tip>
2. You also need to add the `CrossClusterGet` permission on the IAM policy for the OS cluster set under the **Security Configuration** tab for your OS domain. We recommend the following as per AWS, but feel free to fine-tune as necessary:
> ``` json
> &#123;
> "Version": "2012-10-17",
> "Statement": [
> &#123;
> "Effect": "Allow",
> "Principal": &#123;
> "AWS": "*"
> &#125;,
> "Action": "es:ESHttp*",
> "Resource": "arn:aws:es:&lt;region&gt;:<acc_num>:domain/<domain_name>/*"
> &#125;,
> &#123;
> "Effect": "Allow",
> "Principal": &#123;
> "AWS": "*"
> &#125;,
> "Action": "es:ESCrossClusterGet",
> "Resource": "arn:aws:es:&lt;region&gt;:<acc_num>:domain/<domain_name>"
> &#125;
> ]
> &#125;
> ```
To recap:
- Use OpenSearch 2.x.
- Enable fine-grained access control.
- Create the master user, and note the server credentials.
- Set the IAM policy as above.
<Warning>
After creating the master user, IP based access to the OS might not work from Mattermost application nodes. You may need to update the `ElasticsearchSettings` section in `config.json` to update the server [username](/administration-guide/configure/environment-configuration-settings#server-username) and [password](/administration-guide/configure/environment-configuration-settings#server-password).
</Warning>
3. Create a new OS cluster in the secondary region. Follow the same steps again for this cluster.
> <div class="warning">
>
> <div class="title">
>
> Warning
>
> </div>
>
> At this stage, ensure that you have all indices populated with data in the primary region. Run a bulk index to do that if you haven't already.
>
> </div>
4. Begin replication from the primary to secondary region.
> 1. First, create a connection from secondary to primary. Note that replication in OS works in a "pull" model, so the secondary site pulls data from the primary.
> 2. In the Amazon OpenSearch Service console, select the secondary domain, go to the **Connections** tab, and choose **Request**.
> 3. For **Connection alias**, enter a name for your connection.
> 4. Choose **connect to a domain in another AWS account or region**, and enter the **ARN** of the primary domain.
> 5. Select **Request** to send a permission request to the primary domain.
> 6. Open the primary domain to see and accept the incoming request under the **Connections** tab.
5. Now set up the replication rules for indices.
> 1. SSH into an app node in the secondary region to set up an auto-follow rule for the `posts*` indices because of the daily naming scheme and monthly aggregation.
> 2. For the other indices, replicate each of them. You can also set up a rule with `*` to replicate everything, but that would also include the hidden and system indices which you don't want.
> 3. Set up the auto-follow for `posts*` indices:
>
> > ``` sh
> > curl -XPOST -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/_autofollow?pretty' -d '
> > &#123;
> > "leader_alias" : "<LEADER_ALIAS>",
> > "name": "autofollow-rule",
> > "pattern": "posts*",
> > "use_roles":&#123;
> > "leader_cluster_role": "all_access",
> > "follower_cluster_role": "all_access"
> > &#125;
> > &#125;'
> > ```
>
> 4. Check the status of the auto-follow rule:
>
> > ``` sh
> > curl -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/autofollow_stats?pretty'
> > &#123;
> > "num_success_start_replication" : 2,
> > "num_failed_start_replication" : 0,
> > "num_failed_leader_calls" : 0,
> > "failed_indices" : [ ],
> > "autofollow_stats" : [
> > &#123;
> > "name" : "autofollow-rule",
> > "pattern" : "posts*",
> > "num_success_start_replication" : 2,
> > "num_failed_start_replication" : 0,
> > "num_failed_leader_calls" : 0,
> > "failed_indices" : [ ],
> > "last_execution_time" : 1737699113927
> > &#125;
> > ]
> > &#125;
> > ```
>
> 5. Next, set up replication for the other indices:
>
> > ``` sh
> > curl -XPUT -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/channels/_start?pretty' -d '
> > &#123;
> > "leader_alias": "<LEADER_ALIAS>",
> > "leader_index": "channels",
> > "use_roles":&#123;
> > "leader_cluster_role": "all_access",
> > "follower_cluster_role": "all_access"
> > &#125;
> > &#125;'
> >
> > curl -XPUT -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/users/_start?pretty' -d '
> > &#123;
> > "leader_alias": "<LEADER_ALIAS>",
> > "leader_index": "users",
> > "use_roles":&#123;
> > "leader_cluster_role": "all_access",
> > "follower_cluster_role": "all_access"
> > &#125;
> > &#125;'
> >
> > curl -XPUT -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/files/_start?pretty' -d '
> > &#123;
> > "leader_alias": "<LEADER_ALIAS>",
> > "leader_index": "files",
> > "use_roles":&#123;
> > "leader_cluster_role": "all_access",
> > "follower_cluster_role": "all_access"
> > &#125;
> > &#125;'
> > ```
>
> 6. Check the status of the replication rules:
>
> > ``` sh
> > curl -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/channels/_status?pretty'
> > curl -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/files/_status?pretty'
> > curl -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/users/_status?pretty'
> > curl -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/posts_<DATE>/_status?pretty'
> > Sample output:
> > &#123;
> > "status" : "SYNCING",
> > "reason" : "User initiated",
> > "leader_alias" : "<LEADER_ALIAS>",
> > "leader_index" : "<INDEX>",
> > "follower_index" : "<INDEX>",
> > "syncing_details" : &#123;
> > "leader_checkpoint" : 16,
> > "follower_checkpoint" : 16,
> > "seq_no" : 17
> > &#125;
> > &#125;
> > ```
>
> 7. Check for indices. You should be able to see all the indices from the primary domain in the secondary domain:
>
> > ``` sh
> > curl -s -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_cat/indices?pretty'
> > ```
## Replicate job servers
If the job scheduler is left running in the secondary region, it will pick up jobs and start running them. Follow these steps to manage it correctly. See the [RunScheduler configuration setting](/administration-guide/configure/experimental-configuration-settings#run-scheduler) documentation for details.
1. **Precondition:** Set `JobSettings.RunScheduler` to `false` on all nodes in the secondary region before enabling that region.
2. **On failover:** Set `JobSettings.RunScheduler` to `true` on all nodes in the new primary region.
3. **Immediately after:** Set `JobSettings.RunScheduler` to `false` on all nodes in the new secondary region.
4. **Verify:** Confirm that jobs execute only in the active region. Submit a test job (for example, trigger an index rebuild) and check the job logs to ensure it runs on the new primary, not the secondary.
## Test the secondary region
With the above steps complete, you have a fully functioning secondary region. You can replicate the same setup of nodes and a proxy server like the primary region. The app nodes in the secondary region won't be able to come up the first time because Mattermost will try to run some DDL statements which are not allowed with write-forwarding. So it will be stuck in a loop trying to connect. Once you fail over the region, it will start working. The primary region will still be readable, and any periodic writes will be forwarded to the secondary (now primary).
<Warning>
Ensure you have separate `ClusterNames` for the different clusters in two regions to use the same database across 2 clusters.
</Warning>
## Failover RDS to secondary
To perform the failover, go to the RDS global cluster, and under **Actions**, select **Switchover or Failover global database**, and then select **switchover** to switch over without any data loss (which will take more time to complete). Alternatively, you can choose **failover** for a quicker failover at the expense of data-loss. If the entire region is unavailable anyways, then **failover** is no worse than **switchover**.
After this is done, the app nodes which were stuck trying to connect should move forward and everything should be functional. You can read/write, upload images and everything should be replicated. Everything except OpenSearch data.
## Failover ES/OS to secondary
ES/OS does not allow multi-writer for a single index. You can only write to 1 index at one time. Therefore, you need to perform some manual steps to reverse the replication direction, and start replicating from secondary to primary.
For simplicity, let's say `site1` is primary, and `site2` is secondary. Therefore, OS in `site1` is the leader domain, and in `site2` is the follower. The follower pulls from the leader. To switch the direction where `site2` becomes leader, and `site1` becomes follower.
1. Remove the rule from `site1` \> `site2` in AWS Console. This will auto-pause the replication, but the indices in `site2` will still be read-only. Remove the replication rules for that.
2. Remove auto-follow rule:
> ``` sh
> curl -XDELETE -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/_autofollow?pretty' -d '
> &#123;
> "leader_alias" : "<LEADER_ALIAS>",
> "name": "autofollow-rule"
> &#125;'
> ```
3. Check the status of the auto-follow rule as mentioned before.
4. Remove replication rules:
> ``` sh
> curl -XPOST -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/channels/_stop?pretty' -d '&#123;&#125;'
> curl -XPOST -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/files/_stop?pretty' -d '&#123;&#125;'
> curl -XPOST -H 'Content-Type: application/json' -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_plugins/_replication/users/_stop?pretty' -d '&#123;&#125;'
> ```
5. Check the status of replication rules as mentioned before.
6. Now indices will become writable
7. Add rule from `site2` \> `site1` in AWS console.
8. In `site1`, make all the indices as followers. You must delete all indices first:
> ``` sh
> curl -XDELETE -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/posts*?pretty'
> curl -XDELETE -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/channels?pretty'
> curl -XDELETE -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/files?pretty'
> curl -XDELETE -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/users?pretty'
> ```
9. Refresh indices:
> ``` sh
> curl -XPOST -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_refresh?pretty'
> ```
10. Confirm that everything is deleted:
> ``` sh
> curl -s -u '<USERNAME>:<PASSWORD>' 'https://<HOSTNAME>/_cat/indices?pretty'
> ```
11. Add the auto-follow rule add replication rules. Follow the same steps as before.
12. List the indices again to confirm that replication has started and indices are available.
<Note>
There's nothing you need to do to ensure the S3 bucket is auto-replicating both ways.
</Note>
## Testing end to end
Once the failover has happened, and the ES/OS replication direction has been swapped, the new site can be used normally.
This becomes the final architecture:
![A diagram showing the final architecture with Mattermost set up in 2 data centers.](/images/dr3.png)
You can use DNS to easily switch between PRIMARY to SECONDARY during a failover.
<Tip>
Websockets will still point to the old data center even if you have switched DNS. You need to roll over each app node gradually to move those connections to the new data center. If all your nodes are down, no action is necessary and the clients will automatically re-connect to the new data center.
</Tip>
The S3 bucket is replicated bi-directionally while the database and ES/OS is replicated uni-directionally.
## Restore to primary data center
When the disaster event is resolved and you are ready to restore normal operations, perform the same failover steps in reverse to return traffic to the original primary data center:
1. Perform an RDS switchover back to the original primary region using the **Switchover or Failover global database** option in the RDS console.
2. Reverse the ES/OS replication direction by following the same steps in the [Failover ES/OS to secondary](#failover-esos-to-secondary) section, swapping the roles of `site1` and `site2`.
3. Update DNS to redirect traffic back to the original primary data center.
4. Re-enable `JobSettings.RunScheduler` on the original primary nodes and disable it on the secondary nodes.
5. Roll over app nodes gradually to move websocket connections back to the primary data center.

View File

@@ -0,0 +1,50 @@
---
title: "Encryption options"
---
<PlanAvailability slug="all-commercial" />
Mattermost provides encryption-in-transit and encryption-at-rest capabilities. This page guides you through setting up appropriate encryption security.
Encryption is not required for GDPR, although it can be used as an additional safeguard against data breach.
## Encryption-in-transit
Mattermost supports TLS encryption including AES-256 with 2048-bit RSA on all data transmissions between Mattermost client applications and the Mattermost server. You may either set up TLS on the Mattermost Server or install a proxy such as NGINX and set up TLS on the proxy. Refer to our [configuration guide for more details](/deployment-guide/server/setup-tls).
Connections to Active Directory/LDAP can [optionally be secured with TLS or stunnel](/administration-guide/configure/authentication-configuration-settings#adldap-port).
Connections to calls are secured with a combination of:
> - TLS: The existing WebSocket channel is used to secure the signaling path.
> - DTLS v1.2 (mandatory): Used for initial key exchange. Supports `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256` and `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA` algorithms.
> - SRTP (mandatory): Used to encrypt all media packets (i.e. those containing voice or screen share). Supports `AEAD_AES_128_GCM` and `AES128_CM_HMAC_SHA1_80` algorithms.
## Gossip encryption
In a High Availability mode, Mattermost supports encryption of cluster data in-transit when using the gossip protocol, which is based on principles outlined in the [SWIM protocol developed by researchers at Cornell University](https://www.cs.cornell.edu/projects/Quicksilver/public_pdfs/SWIM.pdf). The gossip protocol is a communication mechanism in distributed systems where nodes randomly exchange information to ensure data consistency across the network. It is decentralized, scalable, and fault-tolerant, making it ideal for systems with numerous nodes. Information is spread in a manner similar to social gossip, with nodes periodically "gossiping" updates to random peers until the network converges to a consistent state. Widely used in distributed databases, blockchain networks, and peer-to-peer systems, the protocol is simple to implement and resilient to node failures. However, it can suffer from redundancy and propagation delays in large networks.
From Mattermost v10.11, [gossip encryption](/administration-guide/configure/environment-configuration-settings#enable-gossip-encryption) is enabled by default for new deployments while existing deployments maintain their current configuration.
The encryption uses AES-256 by default, and it is not configurable. However, it is possible to manually set the value in the `Systems` table for the `ClusterEncryptionKey` row. A key is a byte array converted to base64. It can be set to a length of 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256 respectively.
## Encryption-at-rest
Encryption-at-rest is available for messages via hardware and software disk encryption solutions applied to the Mattermost database, which resides on its own server within your infrastructure. To enable end user search and compliance reporting of message histories, Mattermost does not offer encryption within the database.
Both the database and file storage can be secured using software or hardware disk encryption solutions. Full-disk encryption methods such as LUKS (Linux), BitLocker (Windows), or database-specific solutions like Transparent Data Encryption (TDE) can be employed. Integration with external encrypted storage systems is supported.
Additionally, encryption-at-rest is available for files stored via hardware and software disk encryption solutions applied to the server used for local/network storage or S3-compatible storage.
### Database
See the [PostgreSQL](https://www.postgresql.org/docs/10/encryption-options.html) database documentation for details on encryption options at the disk level.
### File storage
For local storage, NFS, or S3-compatible storage, encryption-at-rest is available for files stored via hardware and software disk encryption solutions applied to the server.
For Amazon’s proprietary S3 system, encryption-at-rest is available via [server-side encryption with Amazon S3-managed keys](/administration-guide/configure/environment-configuration-settings#enable-server-side-encryption-for-amazon-s3) in Mattermost enterprise-badge.
## SAML encryption support
SAML assertion encryption is configured alongside the rest of your identity provider settings rather than at the infrastructure layer. See [supported SAML encryption methods](/administration-guide/configure/authentication-configuration-settings#supported-saml-encryption-methods) in the authentication configuration settings.

View File

@@ -0,0 +1,874 @@
---
title: "Configure Microsoft Intune Mobile Application Management (MAM)"
sidebar_label: "Configure Microsoft Intune MAM"
---
<PlanAvailability slug="entry-adv" />
You can configure the Mattermost Mobile App on iOS to enforce Microsoft Intune App Protection Policies (MAM) so organizational data remains protected on Bring Your Own Device (BYOD) and mixed-use devices without requiring device enrollment (MDM).
This guide documents the required configuration to enable Intune MAM successfully on iOS.
## Read This First
Intune MAM enforcement in Mattermost is identity-based and applies only to the sign-in method selected as the enforced **Auth Provider** in **System Console \> Environment \> Mobile Security**.
- The enforced authentication provider must resolve users using Azure AD `objectId` (`IdAttribute = objectId`).
- MSAL access tokens must include the `oid` claim, and it must match the same Azure AD `objectId` (confirm identity alignment: `objectId ↔ oid`).
<Important>
If Intune MAM enrollment fails due to a technical error, the affected Mattermost server is removed from the mobile app and cached data for that server is wiped from the device.
</Important>
## Unsupported Scenarios
This guide doesn't apply when:
- You require Intune MAM on Android devices.
- You want Intune MAM enforcement for a sign-in method not backed by Microsoft Entra ID.
- The enforced authentication provider cannot resolve users to Azure AD `objectId`.
- You require a rollout model where users can bypass or defer Intune MAM for the enforced sign-in method.
Other authentication methods, such as guest access, may still be enabled separately, but they aren't evaluated by Intune MAM.
## Prerequisites
Confirm the following before continuing:
- Microsoft Entra ID is used for authentication.
- You can commit to Azure AD `objectId` as the authoritative identity.
- Mattermost Enterprise Advanced licensing is available for the server.
- Target users are licensed for Microsoft Intune.
- You can register applications and grant tenant-wide admin consent in Microsoft Entra.
- If enforcing Intune MAM on SAML, users already exist in Mattermost (mobile sign-in does not create users for SAML).
<Note>
In this guide, OpenID Connect (OIDC) refers to the Microsoft Entra sign-in method used by the Mattermost Mobile App via MSAL.
</Note>
## Configuration Overview
Successful Intune MAM enforcement requires coordinated configuration across:
- **Microsoft Entra ID** – app registration, scope, API permissions, admin consent
- **Microsoft Intune** – iOS App Protection Policies
- **Mattermost Server** – MAM enablement and provider selection
- **Mattermost Mobile App (iOS)** – enrollment and enforcement
Complete the steps below in order.
## Setup Summary
1. Confirm identity requirements and alignment (`objectId ↔ oid`).
2. Configure Microsoft Entra (server-referenced application).
3. Configure Intune App Protection Policies.
4. Enable Intune MAM in Mattermost and select the enforced provider.
5. Deploy the official Mattermost iOS app.
6. Validate enrollment and enforcement.
## Values You’ll Need Later
Capture these during setup:
<table style={{width: '99%'}}>
<colgroup>
<col style={{width: '23%'}} />
<col style={{width: '30%'}} />
<col style={{width: '46%'}} />
</colgroup>
<thead>
<tr>
<th>Value</th>
<th>Where to get it</th>
<th>Where you use it</th>
</tr>
</thead>
<tbody>
<tr>
<td>Directory (tenant) ID</td>
<td>Entra app registration overview</td>
<td>Mattermost System Console</td>
</tr>
<tr>
<td>Application (client) ID</td>
<td>Entra app registration overview</td>
<td>Mattermost System Console</td>
</tr>
<tr>
<td>Application ID URI</td>
<td>Entra app &gt; Expose an API</td>
<td>Used to form the <code>api://&lt;APPLICATION-ID&gt;/login.mattermost</code> scope reference in Authorized client applications</td>
</tr>
<tr>
<td><code>login.mattermost</code> scope</td>
<td>Entra app &gt; Expose an API</td>
<td>Authorized client applications</td>
</tr>
<tr>
<td>Mobile client application ID</td>
<td>Provided by Mattermost</td>
<td>Entra app &gt; Authorized client applications</td>
</tr>
<tr>
<td>iOS bundle IDs (prod/beta)</td>
<td>This guide</td>
<td>Intune App Protection Policies</td>
</tr>
</tbody>
</table>
## Step 1: Identity Configuration for Intune MAM
<div id="step-1-identity-configuration-for-intune-mam">
This step defines the required identity model for the authentication provider selected for Intune MAM enforcement.
</div>
### Required Identity Model
Microsoft Intune MAM for Mattermost requires Azure AD `objectId` as the authoritative user identifier. The following is non-negotiable.
- `IdAttribute` must equal `objectId` for the enforced provider.
- MSAL access tokens must include the `oid` claim.
- Confirm identity alignment (`objectId ↔ oid`) before enabling Intune MAM.
### Confirm Identity Alignment (objectId ↔ oid)
<div id="identity-alignment-objectid-oid">
For the same user, the following values must match:
</div>
- Azure AD `objectId`
- MSAL access token `oid` claim
- SAML `objectidentifier` (if applicable)
- LDAP `msDS-aadObjectId` (if applicable)
Any mismatch prevents enrollment.
### Identity Enforcement by Authentication Method
**OIDC (Mobile sign-in via MSAL)**
- Mattermost uses the MSAL access token for identity and enrollment.
- Confirm identity alignment (`objectId ↔ oid`).
**SAML (Entra-backed)**
- `SamlSettings.IdAttribute` must map to `objectidentifier`.
- Email, UPN, and `immutableID` aren't supported.
- Users must already exist in Mattermost before mobile sign-in.
**LDAP (Entra ID Domain Services)**
- Use `msDS-aadObjectId`.
- Do not use `objectGUID`.
### Runtime Enforcement Behavior
When Intune MAM is enabled for a provider:
- Enforcement occurs during active sessions, not only at login.
- If Intune MAM becomes newly required due to policy, licensing, or configuration changes, enrollment may be triggered immediately.
- Users can’t bypass enforcement for the enforced provider.
### Pre-flight Checklist
- Licensed Intune test user available
- Ability to grant tenant-wide admin consent
- Enforced provider identified (OIDC or SAML)
- `IdAttribute = objectId` configured
- Identity alignment verified (`objectId ↔ oid`)
- Official Mattermost iOS app deployed
- Target bundle IDs known: `com.mattermost.rn` (Production), `com.mattermost.rnbeta` (Beta)
## Step 2: Microsoft Entra Configuration for Intune MAM
<div id="step-2-microsoft-entra-configuration-for-intune-mam">
You register a single-tenant Microsoft Entra application that is referenced by Mattermost Server. This application validates MSAL access tokens and supports Intune MAM enrollment.
</div>
You don't register the Mattermost Mobile app itself. Redirect URI configuration isn't required.
### Entra Application Registration
1. Go to **Identity \> Applications \> App registrations**
2. Select **New registration**
3. Configure:
- **Name**: Mattermost Mobile (Intune MAM)
- **Supported account types**: Single tenant
4. Register the app
5. Copy:
- **Application (client) ID**
- **Directory (tenant) ID**
### Expose the API and Create the Scope
1. Go to **Expose an API**
2. Confirm **Application ID URI** is set (for example, `api://<APPLICATION-ID>`)
3. Add a scope named `login.mattermost`
4. Save your changes.
### Authorize the Official Mobile Client
Authorize the official Mattermost Mobile client application ID (provided by Mattermost) to request the `login.mattermost` scope.
1. In the Entra app registration, go to **Expose an API**.
2. Under **Authorized client applications**, select **Add a client application**.
3. Add the official Mattermost Mobile client application ID (provided by Mattermost) as:
> - Beta: `64e9952b-20eb-46dc-92ad-99089ed24903`
> - Production: `9ac649f1-4f77-44d6-9792-b2f54ab3c9a7`
4. Authorize the `api://<APPLICATION-ID>/login.mattermost` scope.
5. Save your changes.
### API Permissions and Admin Consent
<div id="api-permissions-admin-consent">
1. Go to **API permissions**.
2. Select **Add a permission**.
3. Add the following **Microsoft Graph** delegated permissions:
- Microsoft Graph → `email` (Delegated)
- Microsoft Graph → `profile` (Delegated)
4. Select **Grant admin consent** for your tenant.
</div>
These are the permissions the customer admin must grant for the Entra application referenced by Mattermost Server.
If these permissions are missing or lack tenant-wide admin consent, enrollment can fail with an Entra permissions/admin-consent error (for example, `AADSTS650057`) or a user-visible **Consent Denied** message during first sign-in.
### Configure MSAL tokens and required claims
Before enabling Intune MAM, ensure the Entra app registration issues access tokens with the claims Mattermost expects during mobile sign-in.
1. In the Entra app registration, go to **Token configuration**.
2. Select **Add optional claim**.
3. Under **Token type**, select **Access**.
4. Add the following optional claims:
- `email`
- `family_name`
- `given_name`
- `preferred_username`
- `upn`
5. Save your changes.
<Note>
Mattermost Intune MAM enforcement uses the MSAL access token. If required claims are missing, sign-in and/or enrollment may fail.
</Note>
### Enable MSAL v2 access tokens
1. Open the app **Manifest**.
2. Set the token version to `2`:
- If your manifest shows `api.requestedAccessTokenVersion`, set it to `2`.
- Otherwise set `accessTokenAcceptedVersion` to `2`.
3. Save your changes.
## Step 3: Configure Intune App Protection Policies
1. Go to **Intune admin center \> Apps \> App protection policies**.
2. Create a policy:
- **Platform**: iOS/iPadOS
- **Targeted app**: Managed apps
3. Add the Mattermost app by bundle ID:
- `com.mattermost.rn` (Production)
- `com.mattermost.rnbeta` (Beta)
4. Configure protection settings.
5. Assign to Entra ID user groups.
6. Save your changes.
Separate policies are required for Production and Beta apps.
## Step 4: Configure Mattermost Server for Intune MAM
<div id="step-4-configure-mattermost-server-for-intune-mam">
1. Go to **System Console \> Environment \> Mobile Security**
2. Set **Enable Microsoft Intune MAM** to **True**
3. Select **Auth Provider**:
- OpenID Connect (Entra-backed)
- SAML 2.0 (Entra-backed)
4. Enter:
- **Tenant ID**
- **Application (Client) ID**
5. Save your changes.
</div>
The enforced provider must resolve identity using `IdAttribute = objectId`.
## Step 5: Deploy the Mattermost iOS App
Download and install the official Mattermost iOS app using:
- Apple App Store (Production)
- TestFlight (Beta)
Wrapped, re-signed, or privately distributed apps aren't supported.
## Step 6: Validate Enrollment
Validate with a licensed test user on iOS.
Confirm:
- Enrollment completes successfully
- Enforcement applies at sign-in and mid-session
- Identity alignment is correct (`objectId ↔ oid`)
## Expected Behavior During Mobile Sign-In
1. User signs in via MSAL.
2. Mattermost validates the access token.
3. Intune MAM enrollment is triggered.
4. App Protection Policies are applied.
If enrollment is required but cannot complete, access is blocked until enrollment succeeds.
## Troubleshooting
<div id="troubleshooting">
Most failures are caused by:
</div>
- Identity mismatch (`objectId ↔ oid`)
- `IdAttribute` not set to `objectId`
- Missing Entra API permissions or admin consent
- App Protection Policy not targeting the user or app
- Unsupported client or platform
### Quick Diagnostics
1. Confirm identity alignment (`objectId ↔ oid`).
2. Confirm `IdAttribute = objectId`.
3. Confirm Entra permissions and admin consent.
4. Confirm Auth Provider selection.
5. Confirm Intune policy targeting.
If the user declines enrollment, retry is allowed.
### Intune MAM Errors
The errors below may occur during mobile sign-in or when Intune MAM enforcement is triggered mid-session. Some errors are shown in the Mattermost Mobile App, while others are silent and must be diagnosed using Mattermost server logs.
<Note>
In the table below, **Fallback: Web SSO** means the mobile app uses the **non-Intune** version of the configured sign-in method (SAML or OpenID Connect) as if Intune MAM were not enabled.
</Note>
<style>
/* Compact, scannable 3-column table with full inline metadata and strong grid lines */
.mm-intune-errors &#123;
width: 100%;
border-collapse: collapse;
table-layout: fixed; /* prevents horizontal scrolling */
margin: 0.75rem 0 1rem 0;
font-size: 0.95rem;
line-height: 1.35;
border: 1px solid #b3b3b3;
&#125;
.mm-intune-errors th,
.mm-intune-errors td &#123;
padding: 0.6rem 0.7rem;
vertical-align: top;
border: 1px solid #b3b3b3;
overflow-wrap: anywhere;
word-break: break-word;
white-space: normal;
background: transparent;
color: inherit;
&#125;
/* Light mode header: explicit contrast */
.mm-intune-errors th &#123;
font-weight: 600;
text-align: left;
background-color: #f2f2f2;
color: #111111;
&#125;
/* Strong row separation */
.mm-intune-errors tbody tr + tr td &#123;
border-top-width: 2px;
&#125;
.mm-intune-errors code &#123;
font-size: 0.9em;
white-space: normal;
padding: 0.1em 0.25em;
border-radius: 4px;
background: rgba(0, 0, 0, 0.08);
&#125;
.mm-intune-errors .meta &#123;
opacity: 0.92;
font-size: 0.92em;
margin-top: 0.35rem;
&#125;
.mm-intune-errors .meta div &#123;
margin: 0.08rem 0;
&#125;
.mm-intune-errors .label &#123;
font-weight: 600;
&#125;
/* Dark mode override */
@media (prefers-color-scheme: dark) &#123;
.mm-intune-errors,
.mm-intune-errors th,
.mm-intune-errors td &#123;
border-color: #666;
&#125;
.mm-intune-errors th &#123;
background-color: #2a2a2a;
color: #ffffff;
&#125;
.mm-intune-errors code &#123;
background: rgba(255, 255, 255, 0.14);
&#125;
.mm-intune-errors .meta &#123;
opacity: 0.9;
&#125;
&#125;
</style>
<table class="mm-intune-errors" aria-label="Microsoft Intune MAM errors and admin remediation steps">
<thead>
<tr>
<th style={{width: '30%'}}>Error</th>
<th style={{width: '22%'}}>Meaning</th>
<th style={{width: '48%'}}>Admin cause &amp; next step</th>
</tr>
</thead>
<tbody>
{/* Enrollment Failed */}
<tr>
<td>
<strong>Enrollment Failed</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>(varies)</code></div>
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
<div><span class="label">Scenario:</span> Enrollment failed (technical)</div>
<div><span class="label">User message:</span> "Enrollment Failed"</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
Intune MAM enrollment failed due to a technical error.
</td>
<td>
<span class="label">Cause:</span> Enrollment could not be completed due to a technical failure (MSAL error, Intune enrollment API failure, identity mismatch, or missing Entra permissions).<br/>
<span class="label">Behavior:</span> The server is removed immediately and there is no retry option; cached data for that server is wiped.<br/>
<span class="label">Next step:</span> Fix the underlying issue, then have the user re-add the server in the mobile app.<br/>
<span class="label">Admin checks:</span> Verify <code>IdAttribute = objectId</code>; confirm identity alignment (<code>objectId ↔ oid</code>); confirm tenant-wide admin consent; confirm App Protection Policy targets the user and the correct iOS bundle ID.
</td>
</tr>
{/* Enrollment Declined */}
<tr>
<td>
<strong>Enrollment Declined</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>(varies)</code></div>
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
<div><span class="label">Scenario:</span> User declined enrollment</div>
<div><span class="label">User message:</span> "Enrollment Declined"</div>
<div><span class="label">Retry:</span> Yes</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The user declined Intune MAM enrollment.
</td>
<td>
<span class="label">Cause:</span> The user canceled the enrollment prompt.<br/>
<span class="label">Behavior:</span> A <strong>Retry</strong> option is shown; no server data is removed unless a later technical enrollment failure occurs.<br/>
<span class="label">Next step:</span> Instruct the user to retry enrollment when ready.
</td>
</tr>
{/* Consent Denied (admin consent missing) */}
<tr>
<td>
<strong>Consent Denied</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>(varies)</code></div>
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
<div><span class="label">Scenario:</span> Admin consent missing (first login)</div>
<div><span class="label">User message:</span> "You denied consent for Intune management. The affected accounts have been unenrolled and signed out."</div>
<div><span class="label">Retry:</span> Yes (after admin consent)</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
Enrollment cannot complete because required Entra app permissions don’t have tenant-wide admin consent.
</td>
<td>
<span class="label">Cause:</span> Tenant-wide admin consent has not been granted for the required delegated permissions on the Entra app registration configured in Mattermost Server.<br/>
<span class="label">Behavior:</span> The message may appear as if the user denied consent, but the underlying issue is missing admin consent.<br/>
<span class="label">Next step:</span> In Microsoft Entra, grant tenant-wide admin consent for Microsoft Graph delegated permissions <code>email</code> and <code>profile</code> on the same Entra app registration configured in Mattermost, then have the user retry mobile sign-in.
</td>
</tr>
{/* Enterprise not compiled */}
<tr>
<td>
<strong>(silent)</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>api.user.login_by_intune.not_available.app_error</code></div>
<div><span class="label">HTTP:</span> 501</div>
<div><span class="label">Scenario:</span> Enterprise not compiled</div>
<div><span class="label">User message:</span> (silent)</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> Standard SSO (non-Intune)</div>
</div>
</td>
<td>
Intune MAM login is not available on this server.
</td>
<td>
<span class="label">Cause:</span> The server does not support Intune MAM (feature not available in this build or not enabled for the deployment).<br/>
<span class="label">Next step:</span> Confirm the server build includes Intune MAM support and the deployment is licensed for Enterprise Advanced.<br/>
<span class="label">User guidance:</span> Have the user sign in via web/desktop using the standard (non-Intune) SSO flow for their provider (SAML or OpenID Connect) while the server is updated or configuration is corrected.
</td>
</tr>
{/* Intune not configured */}
<tr>
<td>
<strong>(silent)</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>api.user.login_by_intune.not_configured.app_error</code></div>
<div><span class="label">HTTP:</span> 400</div>
<div><span class="label">Scenario:</span> Intune not configured</div>
<div><span class="label">User message:</span> (silent)</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> Standard SSO (non-Intune)</div>
</div>
</td>
<td>
Intune MAM is enabled for the org but not configured on the server.
</td>
<td>
<span class="label">Cause:</span> Intune MAM isn't fully configured in <strong>System Console &gt; Environment &gt; Mobile Security</strong>.<br/>
<span class="label">Next step:</span> Enable Microsoft Intune MAM and ensure <strong>Tenant ID</strong>, <strong>Application (Client) ID</strong>, and <strong>Auth Provider</strong> are set correctly.<br/>
<span class="label">Admin checks:</span> Confirm the selected auth provider is Entra-backed and required permissions/admin consent have been granted for the Entra app registration.<br/>
<span class="label">User guidance:</span> Have the user sign in via web/desktop using the standard (non-Intune) SSO flow for their provider (SAML or OpenID Connect) while the server is updated or configuration is corrected.
</td>
</tr>
{/* Bot login forbidden */}
<tr>
<td>
<strong>Bot accounts cannot sign in using this method.</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>api.user.login_by_intune.bot_login_forbidden.app_error</code></div>
<div><span class="label">HTTP:</span> 403</div>
<div><span class="label">Scenario:</span> Bot tried to login</div>
<div><span class="label">User message:</span> "Bot accounts cannot sign in using this method."</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The account cannot use Intune MAM sign-in.
</td>
<td>
<span class="label">Cause:</span> Bot accounts are not allowed to authenticate via Intune MAM.<br/>
<span class="label">Next step:</span> Use a human user account for Intune MAM enrollment and access.
</td>
</tr>
{/* Account locked/deactivated */}
<tr>
<td>
<strong>Your account has been deactivated. Please contact your administrator.</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>api.user.login_by_intune.account_locked.app_error</code></div>
<div><span class="label">HTTP:</span> 409</div>
<div><span class="label">Scenario:</span> User deleted/disabled</div>
<div><span class="label">User message:</span> "Your account has been deactivated. Please contact your administrator."</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The account is not permitted to sign in.
</td>
<td>
<span class="label">Cause:</span> The user is deleted, disabled, or locked in Mattermost.<br/>
<span class="label">Next step:</span> Re-enable or restore the user account in Mattermost, then retry sign-in and enrollment.
</td>
</tr>
{/* IsConfigured() false */}
<tr>
<td>
<strong>(silent)</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>ent.intune.login.not_configured.app_error</code></div>
<div><span class="label">HTTP:</span> 403</div>
<div><span class="label">Scenario:</span> IsConfigured() = false</div>
<div><span class="label">User message:</span> (silent)</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> Standard SSO (non-Intune)</div>
</div>
</td>
<td>
Intune MAM is not configured for the current sign-in path.
</td>
<td>
<span class="label">Cause:</span> Intune MAM isn't configured for the requested authentication path (configuration incomplete or mismatched provider selection).<br/>
<span class="label">Next step:</span> Confirm Intune MAM is enabled and configured, and the selected <strong>Auth Provider</strong> matches how users authenticate (OIDC vs SAML).<br/>
<span class="label">User guidance:</span> Have the user sign in via web/desktop using the standard (non-Intune) SSO flow for their provider (SAML or OpenID Connect) while the server is updated or configuration is corrected.
</td>
</tr>
{/* IdAttribute mapping failed */}
<tr>
<td>
<strong>We couldn't complete your sign in. Please try again.</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>ent.intune.login.extract_auth_data.app_error</code></div>
<div><span class="label">HTTP:</span> 400</div>
<div><span class="label">Scenario:</span> IdAttribute mapping failed</div>
<div><span class="label">User message:</span> "We couldn't complete your sign in. Please try again."</div>
<div><span class="label">Retry:</span> Yes (1x)</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
Identity mapping failed during sign-in.
</td>
<td>
<span class="label">Cause:</span> The server couldn’t extract or map the identity attribute required for Intune MAM (commonly <code>IdAttribute</code> is misconfigured or the token isn't MSAL v2).<br/>
<span class="label">Next step:</span> Ensure <code>IdAttribute = objectId</code>, then confirm identity alignment (<code>objectId ↔ oid</code>). Verify the Entra app issues v2 tokens (<code>accessTokenAcceptedVersion = 2</code>).
</td>
</tr>
{/* SAML user not found */}
<tr>
<td>
<strong>Your account isn't fully set up yet. Please sign in to Mattermost via the web or desktop app first.</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>ent.intune.login.account_not_found.app_error</code></div>
<div><span class="label">HTTP:</span> 428</div>
<div><span class="label">Scenario:</span> SAML user account not found</div>
<div><span class="label">User message:</span> "Your account isn't fully set up yet. Please sign in to Mattermost via the web or desktop app first."</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The user does not exist in Mattermost for SAML-based sign-in.
</td>
<td>
<span class="label">Cause:</span> When SAML is the selected provider for Intune MAM enforcement, mobile sign-in cannot create a new user.<br/>
<span class="label">Next step:</span> Have the user sign in once via the web or desktop app to provision the account, then retry mobile sign-in.<br/>
<span class="label">Admin checks:</span> Ensure provisioning is in place (web/desktop first sign-in, LDAP sync, or another provisioning method).
</td>
</tr>
{/* Token validation failed */}
<tr>
<td>
<strong>We couldn't verify your sign in. Please try again.</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>ent.intune.validate_token.invalid_token.app_error</code></div>
<div><span class="label">HTTP:</span> 400</div>
<div><span class="label">Scenario:</span> Token validation failed</div>
<div><span class="label">User message:</span> "We couldn't verify your sign in. Please try again."</div>
<div><span class="label">Retry:</span> Yes (1x)</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The access token could not be validated.
</td>
<td>
<span class="label">Cause:</span> Token validation failed (token malformed, wrong issuer/audience, missing permissions, or Entra configuration mismatch).<br/>
<span class="label">Next step:</span> Verify the configured <strong>Tenant ID</strong> and <strong>Application (Client) ID</strong> match the Entra app registration referenced by Mattermost Server. Confirm tenant-wide admin consent has been granted for Microsoft Graph delegated permissions <code>email</code> and <code>profile</code> on that same app registration. Then confirm identity alignment (<code>objectId ↔ oid</code>) for the affected user.<br/>
<span class="label">Admin checks:</span> Confirm v2 tokens (<code>accessTokenAcceptedVersion = 2</code>) and that Microsoft Graph delegated permissions <code>email</code> and <code>profile</code> have tenant-wide admin consent.
</td>
</tr>
{/* Token expired */}
<tr>
<td>
<strong>Your sign in session has expired. Please try signing in again.</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>ent.intune.validate_token.token_expired.app_error</code></div>
<div><span class="label">HTTP:</span> 400</div>
<div><span class="label">Scenario:</span> Token expired</div>
<div><span class="label">User message:</span> "Your sign in session has expired. Please try signing in again."</div>
<div><span class="label">Retry:</span> Yes (1x)</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The authentication session expired before enrollment completed.
</td>
<td>
<span class="label">Cause:</span> The access token or interactive session expired during sign-in/enrollment.<br/>
<span class="label">Next step:</span> Have the user sign in again and complete enrollment promptly.<br/>
<span class="label">Admin checks:</span> If repeated, confirm the device can reach Entra/Intune endpoints during enrollment and prompts aren't being blocked.
</td>
</tr>
{/* Missing claims */}
<tr>
<td>
<strong>We couldn't complete your sign in. Please contact your IT administrator.</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>ent.intune.validate_token.missing_claims.app_error</code></div>
<div><span class="label">HTTP:</span> 400</div>
<div><span class="label">Scenario:</span> Required claims missing</div>
<div><span class="label">User message:</span> "We couldn't complete your sign in. Please contact your IT administrator."</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The access token is missing required claims for sign-in and enrollment.
</td>
<td>
<span class="label">Cause:</span> Required claims are missing from the MSAL access token (most commonly <code>oid</code>, or optional claims required by Mattermost).<br/>
<span class="label">Next step:</span> Confirm MSAL v2 access tokens are issued (<code>accessTokenAcceptedVersion = 2</code>) and the token includes <code>oid</code>. In the Entra app registration, go to <strong>Token configuration</strong> and ensure optional claims are added for the <strong>Access</strong> token: <code>email</code>, <code>family_name</code>, <code>given_name</code>, <code>preferred_username</code>, and <code>upn</code>. Confirm the enforced provider uses <code>IdAttribute = objectId</code>, then verify identity alignment (<code>objectId ↔ oid</code>).
</td>
</tr>
{/* Invalid tenant */}
<tr>
<td>
<strong>There was a configuration issue. Please contact your IT administrator.</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>ent.intune.validate_token.invalid_tenant_id.app_error</code></div>
<div><span class="label">HTTP:</span> 400</div>
<div><span class="label">Scenario:</span> Token tenant ≠ configured tenant</div>
<div><span class="label">User message:</span> "There was a configuration issue. Please contact your IT administrator."</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The token tenant does not match the configured tenant.
</td>
<td>
<span class="label">Cause:</span> The token was issued by a different tenant than the one configured in Mattermost.<br/>
<span class="label">Next step:</span> Verify the <strong>Tenant ID</strong> configured in <strong>System Console &gt; Environment &gt; Mobile Security</strong> matches the Entra tenant issuing MSAL tokens for the user.
</td>
</tr>
{/* AADSTS650057 */}
<tr>
<td>
<strong>AADSTS650057</strong><br/>
<span class="meta">(invalid_resource)</span>
<div class="meta">
<div><span class="label">Error ID:</span> <code>(AADSTS650057)</code></div>
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
<div><span class="label">Scenario:</span> invalid_resource</div>
<div><span class="label">User message:</span> (MSAL/Entra error)</div>
<div><span class="label">Retry:</span> No (until fixed)</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The Entra app configuration is missing required permissions and/or admin consent.
</td>
<td>
<span class="label">Cause:</span> Required Intune MAM API permissions are missing or do not have tenant-wide admin consent.<br/>
<span class="label">Next step:</span> In the Microsoft Entra admin center, go to <strong>Enterprise applications</strong> (not App registrations), search for <strong>Mattermost Mobile</strong> / <strong>Mattermost Mobile Beta</strong>, then open <strong>Permissions</strong> and add/grant admin consent for the Intune MAM permissions (for example, <code>https://msmamservice.api.application/.default</code> and <strong>Microsoft Mobile Application Management</strong> → <code>user_impersonation</code> (Delegated)). Then have the user retry sign-in.
</td>
</tr>
{/* NotLicensed */}
<tr>
<td>
<strong>NotLicensed</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>(NotLicensed)</code></div>
<div><span class="label">HTTP:</span> <code>(varies)</code></div>
<div><span class="label">Scenario:</span> License missing or inactive</div>
<div><span class="label">User message:</span> (varies)</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
The server is not licensed for Intune MAM enforcement.
</td>
<td>
<span class="label">Cause:</span> Enterprise Advanced licensing is missing or not applied to the server.<br/>
<span class="label">Next step:</span> Apply an Enterprise Advanced license to the server and confirm the license is active, then retry.
</td>
</tr>
{/* HTTP 403 Forbidden */}
<tr>
<td>
<strong>HTTP 403 Forbidden</strong>
<div class="meta">
<div><span class="label">Error ID:</span> <code>(HTTP 403)</code></div>
<div><span class="label">HTTP:</span> 403</div>
<div><span class="label">Scenario:</span> Server-side access blocked</div>
<div><span class="label">User message:</span> (varies)</div>
<div><span class="label">Retry:</span> No</div>
<div><span class="label">Fallback:</span> None</div>
</div>
</td>
<td>
Server-side access is blocked by a gating condition.
</td>
<td>
<span class="label">Cause:</span> A server gating condition is preventing enrollment (not an Intune service failure).<br/>
<span class="label">Next step:</span> Verify Enterprise Advanced licensing, Intune MAM is enabled, <strong>Auth Provider</strong> selection matches how users authenticate, configured <strong>Tenant ID</strong> and <strong>Application (Client) ID</strong> are correct, and tenant-wide admin consent is granted. Then confirm identity alignment (<code>objectId ↔ oid</code>) and Intune App Protection Policy targeting for the correct iOS bundle ID.
</td>
</tr>
</tbody>
</table>
### Consent During First Login
If a user’s first mobile sign-in fails with **Consent Denied** or:
`You denied consent for Intune management. The affected accounts have been unenrolled and signed out.`
Treat this as missing tenant-wide admin consent for the Entra app registration referenced by Mattermost Server. See the **Consent Denied** entry in the [Intune MAM Errors](#intune-mam-errors) table above for remediation steps.
To resolve this:
1. In the Microsoft Entra admin center, go to **Enterprise applications**.
2. Search for **Mattermost Mobile** or **Mattermost Mobile Beta**.
3. Go to **Permissions** and add/grant **tenant-wide admin consent** for the Intune MAM permissions (for example, `https://msmamservice.api.application/.default` and Microsoft Mobile Application Management → `user_impersonation` (Delegated)).
4. Have the user retry mobile sign-in.
## Rollout and Recovery Guidance
- Pilot with a small group first
- Validate identity alignment before broad rollout
- Expect enforcement to occur mid-session if requirements change

View File

@@ -0,0 +1,49 @@
---
title: "Mobile VPN options"
---
<PlanAvailability slug="all-commercial" />
To connect to your private network Mattermost instance, you need to set up a way to connect to your private network Mattermost instance, using an external proxy with encrypted transport through HTTPS and WSS network connections.
Depending on your security policies, we recommend deploying Mattermost behind a VPN and using a [per-app VPN](#per-app-vpn) with your EMM provider, or a mobile VPN client.
Also consider deploying a mobile VPN client with multi-factor authentication (MFA) to your preferred login method, such as GitLab SSO with MFA, or run Mattermost Enterprise Edition with [multi-factor authentication (MFA)](/administration-guide/onboard/multi-factor-authentication) enabled.
## Mobile VPN options
A Virtual Private Network (VPN) allows a device outside a firewall to access content inside the firewall as if it were on the same network.
<Note>
Some mobile VPN options depend on the requirements of your organization and the demands and/or the needs of your users.
</Note>
We recommend one of two options: [per-app VPN](#per-app-vpn) or a [device VPN](#device-vpn) to secure your deployment. Both options are compatible with most EMM providers.
We also recommend you review the following [commonly-asked questions](/deployment-guide/mobile/mobile-faq) about data security on mobile devices:
- How data is handled on a device after an account is deleted?
- What post metadata is sent in mobile push notifications?
- What are my options for securing the Mobile apps?
- What are my options for securing push notifications?
### Per-app VPN
A common approach is to use a per-app VPN. This provides a connection to the VPN when needed (on-demand). If using a per-app VPN with Mattermost, you can configure the following options:
- **useVPN:** Mattermost waits until the connection to the VPN server is established before making any requests (otherwise they will fail). This is only supported on iOS as Android OS cannot support waiting. It still works but the first connection attempt may fail.
- **timeoutVPN (iOS only):** How long to wait for the connection to the VPN server before trying.
### Device VPN
With this option, all internet traffic routes through the VPN specified in the profile. This could cause issues for personal applications.
## Connect via corporate proxy server
Review the following commonly-asked questions about connecting through a corporate proxy server:
- [How do I receive mobile push notifications if my IT policy requires the use of a corporate proxy server?](/deployment-guide/mobile/mobile-faq#how-do-i-receive-mobile-push-notifications-if-my-it-policy-requires-the-use-of-a-corporate-proxy-server)
- [Deploy Mattermost with connection restricted post-proxy relay in DMZ or a trusted cloud environment](/deployment-guide/mobile/mobile-faq#deploy-mattermost-with-connection-restricted-post-proxy-relay-in-dmz-or-a-trusted-cloud-environment)
- [Whitelist Mattermost push notification proxy to bypass your corporate proxy server](/deployment-guide/mobile/mobile-faq#whitelist-mattermost-push-notification-proxy-to-bypass-your-corporate-proxy-server)
- [Run App Store versions of the Mattermost Mobile apps](/deployment-guide/mobile/mobile-faq#run-app-store-versions-of-the-mattermost-mobile-apps)

View File

@@ -0,0 +1,185 @@
---
title: "Deploy using an EMM provider"
---
import useBaseUrl from '@docusaurus/useBaseUrl';
<PlanAvailability slug="entry-ent" />
You can enhance mobile security by deploying the Mattermost mobile app with [Enterprise Mobility Management (EMM)](https://en.wikipedia.org/wiki/Enterprise_mobility_management) and Mattermost AppConfig compatibility to secure mobile endpoints with management application configuration.
You can use an EMM to:
- Enforce users to download the Mattermost pre-built or custom apps managed by your organization.
- Set default server url address.
- Restrict users from changing servers.
- Enforce security policies.
An EMM provider pushes Mattermost Mobile apps to EMM-enrolled devices. This approach is recommended for organizations that typically use EMM solutions to deploy Mobile apps to meet security and compliance policies.
## Manage app configuration using AppConfig
AppConfig is our recommended approach for app configuration and management. It was introduced by the [AppConfig Community](https://www.appconfig.org/), a group of leading EMM providers and app developers who have come together to make it easier for developers and customers to drive mobility in business.
AppConfig provides an easy way to configure enterprise mobile apps with any EMM providers listed on the [AppConfig website](https://www.appconfig.org/). Using AppConfig, you can manage default settings and security controls on public app stores and custom-built mobile clients. For example, you can pre-configure your Mattermost server URL and username.
### Mattermost AppConfig values
The following table shows all the configuration options that can be sent from the EMM provider of your choice to the Mattermost mobile apps. You can also [download an XML template](/files/samples/mattermost-specfile.xml) of the configuration file for use with your EMM provider.
<style>
table.mattermost-plans &#123;
border-collapse: collapse;
width: 100%;
font-size: 0.95em;
&#125;
table.mattermost-plans th, table.mattermost-plans td &#123;
border: 1px solid #888;
padding: 6px 8px;
vertical-align: top;
&#125;
/* Dark mode border color */
body:not([data-custom-theme="light"]) table.mattermost-plans th,
body:not([data-custom-theme="light"]) table.mattermost-plans td &#123;
border-color: #666;
&#125;
table.mattermost-plans th &#123;
background: #f2f2f2;
font-weight: bold;
text-align: left;
&#125;
/* Dark mode support for table headers */
body:not([data-custom-theme="light"]) table.mattermost-plans th &#123;
background: #444;
color: #fff;
&#125;
</style>
<table class="mattermost-plans">
<thead>
<tr>
<th>Key</th>
<th>Description</th>
<th>Default/Valid Values</th>
<th>iOS Support</th>
<th>Android for Work Support</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>inAppPinCode</code></strong><br /><em>String</em></td>
<td>Require users to authenticate as the device owner before using the app. Prompts for fingerprint or passcode when the app first opens and when the app has been in the background for more than five minutes.</td>
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
<tr>
<td><strong><code>blurApplicationScreen</code></strong><br /><em>String</em></td>
<td>Blur the app when it's set to background to protect any confidential on-screen information. On Android, it also prevents taking screenshots of the app.</td>
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
<tr>
<td><strong><code>jailbreakDetection</code></strong><br /><em>String</em></td>
<td>Disable app launch on jailbroken or rooted devices.</td>
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
<tr>
<td><strong><code>copyAndPasteProtection</code></strong><br /><em>String</em></td>
<td>Disable the ability to copy from or paste into any text inputs in the app.</td>
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /> (since v1.24.0)</td>
</tr>
<tr>
<td><strong><code>serverUrl</code></strong><br /><em>String</em></td>
<td>Set a default Mattermost server URL. Supports a single server only while v2.0 of the mobile app supports multiple server connections.</td>
<td>Valid: URL</td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
<tr>
<td><strong><code>serverName</code></strong><br /><em>String</em></td>
<td>Automatically populates the server display name for the URL specified in serverURL.</td>
<td>Valid: alphanumeric or empty</td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
<tr>
<td><strong><code>allowOtherServers</code></strong><br /><em>String</em></td>
<td>Allow the user to change the above server URL. If set to <code>true</code>, users can connect to multiple servers that aren't specified in the server URL setting. If set to <code>false</code>, users can only connect to a single defined server.</td>
<td>Default: <code>true</code><br />Valid: <code>true | false</code></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
<tr>
<td><strong><code>username</code></strong><br /><em>String</em></td>
<td>Set the username or email address to use to authenticate against the Mattermost Server.</td>
<td></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
<tr>
<td><strong><code>useVPN</code></strong><br /><em>String</em></td>
<td>Enable connection to the Mattermost Server to use a per-app VPN or VPN on-demand.</td>
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td></td>
</tr>
<tr>
<td><strong><code>timeoutVPN</code></strong><br /><em>String</em></td>
<td>Set how long the request waits (in milliseconds) for an initial VPN connection to establish before timeout.</td>
<td>Default: 30000</td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td></td>
</tr>
<tr>
<td><strong><code>vendor</code></strong><br /><em>String</em></td>
<td>Name of the EMM vendor or company deploying the app. Used in help text when prompting for passcodes so users are aware why the app is being protected.</td>
<td>Default: Mattermost</td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
<tr>
<td><strong><code>inAppSessionAuth</code></strong><br /><em>String</em></td>
<td>Use the app's internal browser for SSO instead of an external browser. From Mattermost v10.2 and mobile v2.2.1, deprecated in favor of the <a href="../../administration-guide/configure/site-configuration-settings.html#mobile-external-browser">mobile external browser</a> server configuration setting.</td>
<td>Default: <code>false</code><br />Valid: <code>true | false</code></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
<td><img src={useBaseUrl('/img/ui/checkmark.svg')} alt="Supported" width="16" height="16" /></td>
</tr>
</tbody>
</table>
### Other AppConfig settings
As part of AppConfig, EMM administrators can set the following additional configuration options for the Mattermost mobile apps:
1. **App Tunnel:** Leverage the "Per-app VPN" capabilities in most commercial VPN solutions.
2. **Prevent App Backup:** Prevent users from backing up app data.
3. **Enforce App Encryption:** Set security policies such as requiring encryption.
4. **Remotely Wipe App:** Use the EMM tool to distribute the app to devices as a managed application so it can be remotely wiped. If the app was previously installed, mark it so the EMM converts the app to a managed app.
Other configurations may be available depending on your EMM provider.
<Important>
\- Mattermost only supports the AppConfig standard for securing Mattermost mobile apps via an EMM provider due to incompatibilities with app wrapping and React Native applications. Different EMM vendors refer to “wrapping” in different ways, but it ultimately comes down to unpacking the mobile client bundle, injecting additional SDKs, and re-packaging/re-signing. React Native is the technology used to develop the Mattermost mobile apps. - Mattermost doesn’t support app wrapping, and Mattermost mobile apps won't function properly when using app wrapping (e.g., Websockets for real-time messaging will break). Use app wrapping/containerization technology at your own risk. - A Mattermost Enterprise subscription plan (or a legacy Enterprise Edition license) is required to request assistance or troubleshooting help from [Mattermost Customer Support](https://mattermost.com/support/) when building and deploying custom mobile apps. Customers on other Mattermost subscription plans can develop and deploy custom mobile apps, but can't request technical support assistance through Mattermost Customer Support. - With the release of Mattermost mobile app v2.0, mobile app v1.55 becomes the official [extended support mobile release](/product-overview/mattermost-mobile-releases), and will be supported for an extended timeframe.
</Important>
## Enroll devices
When building your own custom versions or deploying the pre-built Mattermost Mobile apps, consider your organization’s mobile policy:
- Can users bring their own device (BYOD) If so, what devices will be used?
- Are devices company-owned and company-issued?
- Are both options supported?
- What operating systems do you want to start testing?
Once you know what possible device configurations you’ll be supporting, consider creating a sample configuration, then running validation tests against each configuration item.
## Generate and assign device profiles
Generate and assign a device profile for device-wide configurations through the EMM provider.

View File

@@ -0,0 +1,56 @@
---
title: "Distribute a custom mobile app"
---
<PlanAvailability slug="all-commercial" />
To control the look and feel of the Mattermost mobile app requires building your own mobile apps, [hosting your own push proxy service](/deployment-guide/mobile/host-your-own-push-proxy-service), and managing your own app distribution.
<Note>
- Mattermost Enterprise customers are eligible for support guidance on distributing their own custom mobile apps.
- With the release of Mattermost mobile app v2.0, mobile app v1.55 becomes the official [extended support mobile release](/product-overview/mattermost-mobile-releases), and v1.55 will continue to be supported for an extended timeframe.
</Note>
## Key considerations
The Mattermost Mobile App is an open source project. Customizing Mattermost mobile apps requires a fork of the source code. Your team will be responsible for maintaining that fork, as well as keeping that fork updated with any changes made by Mattermost.
Building your own mobile apps will present some challenges, including:
- Installing the necessary developer tools (such as Nodejs, XCode Developer Tools, Android SDKs, as well as others).
- Obtaining and providing certificates for your custom Mattermost mobile apps\*.
- Signing your custom Mattermost mobile apps\*.
- Distributing your Mobile app to your users.
This means that you manage the maintenance of your custom Mattermost mobile apps, such as rebuilding and incorporating feature and/or security updates. If this isn't done regularly, your applications won't match the functionality of our publicly-available applications, and could be incompatible with future versions of Mattermost Server.
This process can be complicated and can greatly increase deployment time, not only initially, but whenever the mobile apps need to be updated. We recommend having your development team [review the Mattermost Mobile Apps developer documentation](https://developers.mattermost.com/contribute/mobile/) to ensure they understand the scale and requirements of taking this path. This documentation provides guidance on building, compiling, signing, and white-labeling Mattermost Mobile apps.
### URL schema limitations
If you are building your own version of Mattermost's mobile client, you need to be aware of the following limitations:
- To allow users to simultaneously run the App Store versions of Mattermost, in addition to the custom company version, you will need to adapt the URL schemes used for the app in the build, as well as configure those schemes on the server using [App Custom URL Schemes](/administration-guide/configure/site-configuration-settings#app-custom-url-schemes)
- Be aware that the `bundleid` for the application should not include `rnbeta`.
- The same change would be required in a custom build of the Mattermost desktop app.
- The mobile and desktop custom clients would no longer be able to log into other Mattermost servers (unless they had the same custom app schema configuration change applied).
## Deployment options
When you decide to build your own Mattermost mobile apps, you have multiple ways to deploy them to your organization.
Our recommend approach is to submit your app to an Enterprise App Store. Once your custom app is added to your own enterprise App Store, your users can download it from the store directly or from an EMM catalog.
Alternatively, use [an Enterprise Mobile Management (EMM) provider](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider) to push the mobile app to the user’s device, and use the AppConfig standard to enforce a selection of app-specific controls. Or, you can use [another distribution method](#using-another-distribution-method), such as a file sharing platform.
You can also submit your app to [public app stores](#using-public-app-stores). This is the same process Mattermost uses to make Mattermost mobile apps available for everyone. However, before your app can be listed on the public app stores, you need to submit it to the public app stores for review and approval.
- As part of the submission process, you need to identify an update strategy that accounts for the release of new versions of Mattermost mobile apps that includes reviewing compatibility requirements, validating mobile app versions connecting to the server, and updating Mattermost server.
- We highly recommend you update your custom Mattermost mobile apps to incorporate any security or service releases.
- Prior to distribution, check any compatibility requirements for the mobile apps and the Mattermost server.
- Not all provided updates are compatible with all previous versions of Mattermost server. Updating only Mattermost mobile apps or updating the mobile apps before Mattermost Server can result in incompatibility issues.
## Custom whitelabeling
Ensure you select a unique app name that helps users distinguish your version from others, such as "\<Your Company Name\> Collaboration". See our [Brand and Visual Design Guidelines](https://handbook.mattermost.com/operations/operations/company-processes/publishing/publishing-guidelines/brand-and-visual-design-guidelines#name-usage-guidelines.html) in our company Handbook for details.

View File

@@ -0,0 +1,40 @@
---
title: "Host your own push proxy service"
---
<PlanAvailability slug="all-commercial" />
Customers building their own custom mobile apps must host their own push proxy service using one of the following methods:
- Compile your own MPNS from the [open source repository](https://github.com/mattermost/mattermost-push-proxy).
- Use the [pre-compiled version of MPNS available on GitHub](https://github.com/mattermost/mattermost-push-proxy/releases).
See our [developer documentation](https://developers.mattermost.com/contribute/mobile/push-notifications/service/) on working with the Mattermost Push Notification Service.
## Enable MPNS
1. Go to **System Console \> Environment \> Push Notification Server**.
2. Under **Enable Push Notifications**, select **Manually enter Push Notification Service location**.
3. Enter the location of your MPNS in the **Push Notification Server** field, then select **Save**.
**Deployment recommendations:**
- Deploy the MPNS on your own infrastructure - whether on-premises behind your firewall or in your public cloud.
- Ensure the Mattermost server has network access to the MPNS instance. Mattermost clients don't need any inbound connectivity.
- The MPNS does not connect with Mattermost mobile apps directly; the MPNS parses and forwards push notifications from the Mattermost server to the Apple Push Notification Service (APNS) or the Firebase Cloud Messaging (FCM).
- The MPNS must be able to communicate with the Apple Push Notification Service over HTTP/2. If an outbound proxy appliance is deployed between the MPNS and APNS, ensure it supports HTTP/2.
- Configure TLS encryption between your MPNS and your Mattermost server.
- Sign the mobile applications during your build process, and obtain and configure valid push certificates for both Android and iOS. Without these certificates, the apps will be unable to send or receive notifications via your MPNS instance.
- Subscribe to [Mattermost Security Bulletins](https://mattermost.com/security-updates/#sign-up) to receive and promptly apply MPNS-related security updates.
## Configure ID-only push notification contents (Enterprise)
By default, push notification message content passes through Apple Push Notification Service (APNS) or Google Firebase Cloud Messaging (FCM) before it reaches a device. This potentially presents a problem for organizations with ultra-strict security and compliance requirements.
With the ID-only option, message contents can be fetched directly from the server once a push notification is delivered to a device. APNS and FCM can’t read push notifications since only a unique message ID is sent in each notification payload. While message content will take slightly longer to send, this feature helps organizations meet advanced compliance requirements.
To set mobile push notification contents to ID-only:
1. Go to **System Console \> Site Configuration \> Notifications**.
2. Under **Push Notification Contents**, select **Full message content fetched from the server on receipt**, then select **Save**.
- As part of the process of building the applications, you'll need to sign the applications. You must also obtain the appropriate certificate for both Android and iOS. If this isn't done, the applications won't be able to interact with your instance of the MPNS. Once this is complete, you can proceed with the deployment of your MPNS instance.
- We strongly recommend that you subscribe to [Mattermost Security Bulletins](https://mattermost.com/security-updates/#sign-up). When you're notified of security updates for the MPNS, apply them promptly.

View File

@@ -0,0 +1,32 @@
---
title: "Mobile App Deployment"
---
<PlanAvailability slug="all-commercial" />
The Mattermost mobile app is available for iPhone and Android devices, and provides a native experience on the go, ensuring you can stay connected and productive from anywhere.
Learn more about [mobile app software requirements](/deployment-guide/software-hardware-requirements#mobile-apps), [available releases and server compatibility](/product-overview/mattermost-mobile-releases), [what's changed across releases](/product-overview/mobile-app-changelog), and [commonly asked questions](/deployment-guide/mobile/mobile-faq).
<Note>
Hitting problems with an installation or rollout? See [Mobile deployment troubleshooting](/deployment-guide/mobile/mobile-troubleshooting) at the end of this section, or [Deployment troubleshooting](/deployment-guide/server/troubleshooting) if the problem might not be specific to the mobile apps.
</Note>
## Download
Download and install the Mattermost mobile app from the [Apple App Store (iOS)](https://www.apple.com/app-store/) or [Google Play Store (Android)](https://play.google.com/store/games?hl=en). When new mobile app releases become available, your mobile app is automatically updated.
If you prefer to manage distribution of the mobile app to your users, we recommend using an [EMM provider](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider) to maintain full control over the distribution process, as well as enforce or restrict specific security policies. See the deployment options below for details.
## Deployment options
Learn what’s required to build and deploy Mattermost mobile apps.
- [Configure Microsoft Intune MAM for Mattermost](/deployment-guide/mobile/configure-microsoft-intune-mam)
- [Distribute custom mobile apps](/deployment-guide/mobile/distribute-custom-mobile-apps)
- [Host your own push proxy service](/deployment-guide/mobile/host-your-own-push-proxy-service)
- [Mobile VPN options](/deployment-guide/mobile/consider-mobile-vpn-options)
- [Mobile security features](/deployment-guide/mobile/mobile-security-features)
- [Secure mobile file storage](/deployment-guide/mobile/secure-mobile-file-storage)
- [Mobile apps FAQ](/deployment-guide/mobile/mobile-faq)

View File

@@ -0,0 +1,368 @@
---
title: "Mobile apps FAQ"
---
## Can I connect to multiple Mattermost servers using the mobile apps?
Yes, using Mattermost mobile app v2.0. Mobile v1.x only supports connecting to one server at a time.
## What data is stored?
The data that can be found on the device depends solely on whether or not the user is logged in to the Mattermost server, and is independent of the state of the device's connection or the state of the app. While logged in, anything that the user is normally allowed to see is eligible for storage on the device, which includes the following content:
- Messages
- Files and images that are attached to messages
- Profile pictures, usernames, and email addresses of people in the currently open channel
In addition, metadata that the app uses for keeping track of its operations is also cached. The metadata includes user IDs, channel IDs, team IDs, and message IDs.
Currently, cache cannot be reset remotely on connected mobile devices.
### What about push notifications?
Push notification storage is managed by the operating system on the device. Mattermost can be configured to send limited amounts of information that does not include the message text or channel name, and it can also be configured to not send push notifications at all.
## Where is the data stored and how is that data protected?
The data is stored in the app's local storage. It's protected by the security measures that a device normally provides to the apps that are installed on it.
## How long is the data stored?
Data is stored until the user logs out, or until it is purged during normal cache management. Deactivating a user account forces a logout and subsequent purging of data from the device.
## How is data handled after a user account is deactivated?
App data is wiped from the device when a user logs out of the app. If the user is logged in when the account is deactivated, then within one minute of deactivation the system logs the user out. Thereafter all app data is wiped from the device.
If file attachments are enabled on the server, users can download files that are attached to messages and store them on their local file system. After they are downloaded, the files are outside the control of the app and can remain on the device indefinitely.
## Are messages pre-loaded?
No. Messages are sent to the device on demand. They are not pre-loaded in anticipation of users scrolling up or switching channels.
## Do I need to compile the mobile apps to host my own push notification server?
Yes. To host your own push notification server, you'll need to compile the mobile apps. See [documentation](/deployment-guide/mobile/distribute-custom-mobile-apps) to learn how to compile your own mobile apps.
## How do push notifications work?
Your Mattermost server sends push notifications to a hosted push proxy server, which relays them via mobile push notification services provided by Apple and Google.
To ensure push notifications are coming from a trusted source, Apple and Google only allow push notifications sent from a service using a key or signature corresponding to a secret compiled into the mobile app itself.
The full process is outlined below:
1. An action triggering a push notification is detected in the Mattermost server running in your private network.
2. Your Mattermost server sends a push notification message to a Mattermost Push Notification Service (MPNS), either self-hosted in your private network, or publicly hosted by Mattermost, Inc.
3. MPNS sends a push notification message to either Apple Push Notification Service (APNS) or to Google’s Firebase Cloud Messaging (FCM) service over a TLS connection.
> - If sent to Apple, the message has a signature corresponding to a secret compiled in the iOS app.
> - If sent to Google, the message uses a key corresponding to a secret compiled in the Android app.
Regardless of whether you're using iOS or Android, the MPNS needs to have access to the appropriate secret compiled into the mobile app.
This means if you use the Mattermost apps from the [Apple App Store](https://www.apple.com/app-store/) or [Google Play Store](https://play.google.com/store/games?hl=en), you need to use the hosted push notification service from Mattermost, Inc. If you compile the apps yourself, you must also compile and use your own MPNS with the corresponding secret.
4. Either APNS or FCM receives the push notification message from MPNS over TLS, and then relays the message to the user's iOS or Android device to be displayed.
<Note>
The use of push notifications with iOS and Android applications will require a moment where the contents of push notifications are visible and unencrypted by a server controlled by either Apple or Google. This is standard for any iOS or Android app. For this reason, there is an option available in Mattermost Enterprise to omit the contents of Mattermost messages from push notifications, or to configure message contents to be fetched from the server when notifications reach the device. See our [Configuration Settings](/administration-guide/configure/site-configuration-settings#push-notification-contents) documentation for details.
</Note>
## Is TLS v1.3 supported?
Yes. Mattermost mobile app v2.0 supports both TLS v1.2 and TLS v1.3 for websocket connections.
## What post metadata is sent in mobile push notifications?
The following post metadata is sent in all push notifications:
- `Team ID`
- `Channel ID`
- `Post ID`
- `User ID` (post author)
- `Username` (post author or webhook override username)
- `Root ID` (only if the post is in a thread)
- `Type` (create or clear push notification)
- `Category` (iOS only, determines if the notifications can be replied to)
- `Badge number` (what the notification badge on the app icon should be set to when the notification is received)
Additional metadata may be sent depending on the System Console setting for [Push Notification Contents](/administration-guide/configure/site-configuration-settings#push-notification-contents):
- **Generic description with sender and channel names**: `Channel name` metadata will be included.
- **Full message content sent in the notification payload**: `Post content` and `Channel name` metadata will be included.
- **Full message content fetched from the server on receipt** (available in Mattermost Enterprise): `Post content` and `Channel name` are not included in the notification payload, instead the `Post ID` is used to fetch `Post content` and `Channel name` from the server after the push notification is received on the device.
## How can I use ID-Only Push Notifications to protect notification content from being exposed to third-party services?
When it comes to mobile data privacy, many organizations prioritize secure handling of messaging data, particularly when it may contain mission-critical or proprietary information. These organizations may have concerns about using mobile notifications because data must pass through third-party entities like Apple Push Notification Service (APNS) or Google Firebase Cloud Messaging (FCM) before it reaches a device.
This poses a potential risk for organizations that operate under strict compliance requirements and cannot expose message data to external entities. To solve this, we offer an option for greater protection for Mattermost push notification message data by only sending a unique message ID in the notification payload rather than the full message data (available in Mattermost Enterprise). Once the device receives the ID, it then fetches the message content directly from the server and displays the notification per usual.
External entities, such as APNS and FCM, handle only the ID and are unable to read any part of the message itself. If your organization has strict privacy or compliance needs, the [ID-Only Push Notification](/administration-guide/configure/site-configuration-settings#push-notification-contents) setting offers a high level of privacy while still allowing your team members to benefit from mobile push notifications.
The following payload shows an example of the json that is transmitted to the push notification service when using the ID-Only setting:
> ``` json
> &#123;
> "ack_id": "nnfbqk5bnffe5karxuzs8o5rec",
> "platform": "apple_rn",
> "server_id": "aoej8izzfffr9e67d6uz3g387h",
> "device_id": "32f198dbdd7427be7e6f03ba721ffdceba58c3f0bfa9c4655a6e7cc8271ba539",
> "post_id": "77d9cs9aq3b1fpoepbdbmqfs4c",
> "category": "CAN_REPLY",
> "message": "You've received a new message.",
> "badge": 3,
> "channel_id": "et3ghiycm7g7bb41ihg85pqgah",
> "type": "message",
> "sender_id": "g774dzud4tgaxgphso4wm8xrxe",
> "version": "v2",
> "is_id_loaded": true
> &#125;
> ```
where the following definitions are applied:
- `ack_id`: An ephemeral identifier generated per notification that determines whether the notification sent was received by the device (using same method that generates identifiers to the rest of the models in the server). This information is available in the `notifications.log` file on the Mattermost server. The `ack_id` is only used for receipt delivery from the mobile app to the Mattermost server to confirm whether the notification sent was received.
- `server_id`: A server identifier created on the server, called `DiagnosticId`. In the future, this value will be used in the mobile app (for multi-server support) to identify which server the notification belongs to.
- `device_id`: The token that APNs and FCM return when you allow the device to receive notifications. So when the user logs into Mattermost, Mattermost sends this `device_id` to attach it to the session. If the session is terminated, the `device_id` is no longer present in the server database because the session record is removed. When the user logs back in, the `device_id` is registered again with the same value because the identifier is specific to the device. This value won't be the same across apps or devices owned by the same person, but will be the same for each session the user creates from the same app on the same device.
- `version`: Tells the mobile app how data is structured so it can parse it properly. Current value is `v2`.
- `is_id_loaded`: (Mattermost Enterprise only) When true, the mobile app look for the contents of the notification on the server because those details are not part of the payload.
## What are my options for securing the mobile apps?
The following options for secure mobile app deployments are available:
1. Securing network connection to mobile apps
> - Use HTTPS and WSS network connections to encrypt transport.
> - Use of a mobile VPN client on mobile devices to establish secure connection to Mattermost server within private network.
2. Use multifactor authentication options
> - If a VPN client with multifactor authentication is not in use, it's highly recommended that MFA is required on authenticating into Mattermost, either within Mattermost itself or via your SSO provider.
## What are my options for securing push notifications?
The following options are available for securing your push notification service:
1. Protecting notification contents
> - You can [choose what type of information to include in push notifications](/administration-guide/configure/site-configuration-settings#push-notification-contents), such as excluding the message contents if your compliance policies require it. Default server settings have message contents turned off.
2. Disabling push notifications
> - Push notifications can also be disabled entirely depending on security requirements. Default server settings have push notifications disabled.
3. Encrypting connections for apps you compile yourself:
> - When using a privately-hosted Mattermost Push Notification Service (MPNS), use encrypted TLS connections between:
> - MNPS and Apple Push Notification Service (APNS)
> - MPNS and Google’s Firebase Cloud Messaging (FCM)
> - MPNS and your Mattermost server
4. Securing apps installed through the Apple App Store and Google Play:
> - When using Mattermost mobile apps from the App Store and Google Play, purchase an annual subscription to Mattermost Enterprise or Professional to use Mattermost's [Hosted Push Notification Service (HPNS)](/administration-guide/configure/environment-configuration-settings#enable-push-notifications).
<Note>
For configuration details, see guides for [deploying the Mattermost mobile app](/deployment-guide/mobile/mobile-app-deployment) and [deploying your own version of the apps](/deployment-guide/mobile/distribute-custom-mobile-apps).
</Note>
## Why do I sometimes see a delay in receiving a push notification?
[Apple Push Notification Service (APNS)](https://developer.apple.com/documentation/usernotifications) and [Google Fire Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) determine when your device receives a push notification from Mattermost. Thus, a delay is usually as a result of those services.
The technical flow for the device to receive a push notification is as follows:
1. User posts a message in Mattermost.
2. Mattermost server identifies if notifications need to be sent.
3. If yes, Mattermost server sends a payload containing the push notification to the push proxy.
4. The push proxy parses the notification and relays it to APNS and FCM.
5. APNS and FCM informs the relevant devices that there is a push notification for Mattermost. This usually happens almost immediately, but may be delayed by a couple of minutes.
6. Mattermost processes the notification and displays it on the user's device.
## How do I deploy Mattermost with Enterprise Mobility Management (EMM) providers?
Mattermost enables customers with high privacy and custom security requirements to deploy mobile app and push notification services using keys that they alone control.
[Learn more about using AppConfig for EMM providers](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider).
## How do I host the Mattermost push notification service?
First, you can use the [Mattermost Hosted Push Notification Service (HPNS)](/administration-guide/configure/environment-configuration-settings#enable-push-notifications). Organizations can also [host their own push proxy server](/deployment-guide/mobile/host-your-own-push-proxy-service) instead. This is applicable when you want to:
1. Customize the Mattermost mobile apps;
2. Deploy your own push notification service, or
3. Repackage the mobile apps with BlueCedar or AppDome (both of which are not officially supported but have been successfully deployed by some organizations).
## How do I white label the app and customize build settings?
All files in the `/assets/base` folder can be overridden as needed without conflicting with changes made to the upstream version of the app. To do this:
1. Create the folder `/assets/override`.
2. Copy any files or folders that you wish to replace from `/assets/base` into `/assets/override`.
3. Make your changes to the files in `/assets/override`.
When you compile the app or run `make dist/assets`, the contents of those two folders will be merged with files in `/assets/override`, taking precedence in the case of any conflicts. For binary files such as images, an overridden file will completely replace the base version, while `JSON` files will be merged so that fields not set in the overridden copy use the base version.
For a more specific example of how to use this feature, see the following section.
## How do I preconfigure the server URL for my users?
You can preconfigure the server URL and other settings by overriding default `config.json` settings and building the mobile apps yourself.
1. Fork the [mattermost-mobile repository](https://github.com/mattermost/mattermost-mobile).
2. Create the file `/assets/override/config.json` in your forked mattermost-mobile repository.
3. Copy and paste all the settings from `assets/base/config.json` to the newly-created `/assets/override/config.json` file that you want to override.
4. To override the server URL, set `DefaultServerURL` to the server URL of your Mattermost server in `/assets/override/config.json`.
5. (Optional) If you want to prevent users from changing the server URL, set `AutoSelectServerUrl` to `true`.
6. (Optional) Override any other settings you like.
After the above, your `/assets/override/config.json` file would look something like this:
> ``` json
> &#123;
> "DefaultServerURL": "my-mattermost-instance.example.com",
> "AutoSelectServerUrl": true,
> "ExperimentalUsernamePressIsMention": true
> &#125;
> ```
7. Finally, [compile your own version](https://developers.mattermost.com/contribute/mobile/build-your-own/) of the Mattermost mobile app and Mattermost push proxy server.
## How can I get Google SSO to work with the Mattermost mobile app?
The apps on the Apple App Store and Google Play Store cannot support Google SSO out of the box. This is because Google requires a unique Google API key that's specific to each organization.
If you need Google SSO support, you can create a custom version of the app for your own organization. Fork the [mattermost-mobile](https://github.com/mattermost/mattermost-mobile) repository and add support for Google SSO before compiling the app yourself. If this is something you’re interested in, please [file an issue in GitHub](https://github.com/mattermost/mattermost-mobile/issues) to start the discussion.
## How do I configure deep linking?
The app checks for platform-specific configuration on app install. If no configuration is found, then the deep linking code sits silently and permalinks act as regular links.
**Set up for iOS**
1. Create an `apple-app-site-association` file in the `.well-known` directory at the root of your server. It should be accessible by navigating to `https://<your-site-name>/.well-known/apple-app-site-association`. There should not be a file extension.
2. In order to handle deep links, paste the following `JSON` into the `apple-app-site-association` file. Make sure to place your app ID in the `appID` property:
{/* */}
&#123;
"applinks": &#123;
"apps": [],
"details": [
&#123;
"appID": "&lt;your-app-id-here&gt;",
"paths": ["**/pl/*", "**/channels/*"]
&#125;
]
&#125;
&#125;
3. Add the associated domains entitlement to your app via the Apple developer portal.
4. Add an entitlement that specifies the domains your app supports via the Xcode entitlements manager.
5. Before installing the app with the new entitlement, make sure that you can view the contents of the `apple-app-site-association` file via a browser by navigating to `https://<your-site-name>/.well-known/apple-app-site-association`. The app will check for this file on install and, if found, will allow outside permalinks to open the app.
Official documentation for configuring deep linking on iOS can be found [here](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html).
**Set up for Android**
Please refer to the the App Links Assistant in Android Studio for configuring [deep linking on Android](https://developer.android.com/studio/write/app-link-indexing).
## How do I connect users across internal and external networks?
By setting up global network traffic management, you can send a user to an internal or external network when connecting with a mobile app. Moreover, you can have two separate layers of restrictions on internal and external traffic, such as:
> - In the internal network, deploy on a private network via per device VPN.
> - In the external network, deploy with [TLS mutual auth](/administration-guide/onboard/ssl-client-certificate) with an NGINX proxy, and [client-side certificates](/administration-guide/onboard/certificate-based-authentication) for desktop and iOS.
Many services such as Microsoft Azure provide options for [managing network traffic](https://learn.microsoft.com/en-us/azure/traffic-manager/traffic-manager-overview), or you can engage a services partner to assist.
## How do I receive mobile push notifications if my IT policy requires the use of a corporate proxy server?
When your IT policy requires a corporate proxy to scan and audit all outbound traffic the following options are available:
### Deploy Mattermost in a proxy-aware configuration with a pre-proxy relay
The Mattermost push notification service is designed to send traffic directly to the [Apple Push Notification Service (APNS)](https://developer.apple.com/documentation/usernotifications) and [Google Fire Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) services.
In a proxy-aware configuration, a pre-proxy relay accepts messages from the [Mattermost Push Proxy](https://developers.mattermost.com/contribute/mobile/push-notifications/service/) and forwards them to a corporate proxy enforcing your internal IT requirements, before transmitting to their final destination.
See a sample architectural overview below:
![The Mattermost push notification service is designed to send traffic directly to the Apple Push Notification Service (APNS) and Google Fire Cloud Messaging (FCM) services. However, if your organization requires a corporate proxy to scan and audit all outbound traffic, you can deploy Mattermost in a proxy-aware configuration with a pre-proxy relay. The relay accepts messages from the Mattermost Push Proxy, and forwards them to a corporate proxy that enforces your internal IT requirements before delivering the notification to a mobile device. This configuration requires a trusted root certificate.](/images/mobile-pre-proxy-relay.png)
This enables the **pre-proxy relay** to act as the APNS and to forward the request to its final destination via your corporate proxy, not requiring the APNS traffic to be proxy-aware. The APNS traffic is redirected to the pre-proxy relay via `/etc/hosts` entry. The entry uses a trusted CA that signs a certificate for the Mattermost Push Proxy to trust the pre-proxy relay. See the Apple Developer documentation on [user notifications](https://developer.apple.com/documentation/usernotifications) for more information.
Google's [FCM traffic](https://firebase.google.com/docs/cloud-messaging) is proxy-aware via environment variables, so no actions are required for it.
Moreover, APNS traffic requires HTTP/2, so your corporate proxy server must support HTTP/2 requests in order to send the push notifications to Apple devices. HTTP/2 support for the pre-proxy relay is also required.
### Deploy Mattermost with connection restricted post-proxy relay in DMZ or a trusted cloud environment
Some legacy corporate proxy configurations may be incompatible with the requirements of modern mobile architectures, such as the requirement of HTTP/2 requests from Apple to send push notifications to iOS devices.
In this case, a post-proxy relay can be deployed to take messages from the Mattermost server passing through your corporate IT proxy in the incompatible format, e.g. HTTP/1.1, transform it to HTTP/2 and relay it to its final destination, either to the [Apple Push Notification Service (APNS)](https://developer.apple.com/documentation/usernotifications) and [Google Fire Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) services.
Ths **post-proxy relay** [can be configured using the Mattermost Push Proxy installation guide](https://developers.mattermost.com/contribute/mobile/push-notifications/service/) with connection restrictions to meet your custom security and compliance requirements.
In place of a DMZ, you can also host in a trusted cloud environment such as AWS or Azure depending on your internal approvals and policies.
![The Mattermost push notification service is designed to send traffic directly to the Apple Push Notification Service (APNS) and Google Fire Cloud Messaging (FCM) services. However, if your organization doesn't support HTTP/2 requests to send push notifications to mobile devices, you can deploy a post-proxy relay to take messages form the Mattermost server, transform it from the incompatible format, and relay it to its final destination. The post-proxy relay can be configured using connection restrictions to meet your custom security and compliance requirements.](/images/mobile-post-proxy-relay.png)
### Whitelist Mattermost push notification proxy to bypass your corporate proxy server
Depending on your internal IT policy and approved waivers/exceptions, you may choose to deploy the [Mattermost Push Proxy](https://developers.mattermost.com/contribute/mobile/push-notifications/service/) to connect directly to [Apple Push Notification Service (APNS)](https://developer.apple.com/documentation/usernotifications) without your corporate proxy.
You will need to [whitelist one subdomain and one port from Apple](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW1) for this option:
- Development server: `api.development.push.apple.com:443`
- Production server: `api.push.apple.com:443`
### Run App Store versions of the Mattermost mobile apps
You can use the mobile applications hosted by Mattermost in the [Apple App Store](https://apps.apple.com/ca/app/mattermost/id1257222717) or [Google Play Store](https://play.google.com/store/apps/details?id=com.mattermost.rn) and connect with the [Mattermost Hosted Push Notification Service (HPNS)](/administration-guide/configure/push-notification-server-configuration-settings#hosted-push-notifications-service-hpns) through your corporate proxy.
<Note>
The use of hosted applications by Mattermost [can be deployed with Enterprise Mobility Management solutions via AppConfig](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider) but wrapping is not supported. See the [product documentation](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider#manage-app-configuration-using-appconfig) for details.
</Note>
### How the `deviceId` behaves
The `deviceId` is a identifier provided by a push notification service, such as Apple Push Notification service (APNs) and Firebase Cloud Messaging (FCM), that identifies the relationship between device, app, and the notification service.
When the app starts, if the push notification permissions are enabled, the app will try to connect with the corresponding notification service (APNs for iOS, FCM for Android) to get the `deviceId`. If there is any change to the `deviceId`, the app will notify any connected server about this change.
Based on the [Apple Developer Documentation on registering apps with APNS](https://developer.apple.com/documentation/usernotifications/registering-your-app-with-apns?changes=_8) and the [Google Documentation on FCM](https://firebase.google.com/docs/cloud-messaging/android/client#java_1), the `deviceId` only will change in the following cases:
- The app is restored from a backup from a different device
- The user clears the app data
- The user reinstalled the app
- The user installed the app on a different device
If the device has a `deviceId`, when the user logs into a Mattermost server, an audit log entry `login` will store the `deviceId`, and the `deviceId` will also be added in the session data in the database. However, it's possible the `deviceId` isn't available, due to several reasons including:
- The device is not connected to the network
- The notification service is not reachable for any reason
- The app is not properly signed
- The device has not been granted the needed permissions
In these scenarios, the `login` audit log won't have the `deviceId`, and the session data won't have the `deviceId`. If the app receives the `deviceId` later, the device will send the new `deviceId` to the server, generating an `attachDeviceId` audit log, and adding the `deviceId` to the session data in the database.
Since the `deviceId` relates to the application, connections through the web browser, even on mobile, won't have a `deviceID`.
## Where can I find mobile message notification logs?
Notification messages are logged to the `notifications.log` file. System admins must enable notification logs in the `config.json` file by setting `EnableFile` to `true`, and specifying an optional file location via `FileLocation`. When no location is configured, the `notifications.log` file is stored in the default Mattermost directory. See the [logging configuration settings](/administration-guide/configure/environment-configuration-settings#logging) documentation for details.
The team members / users can access their notification logs based on their device platform. Android users can view the logs using `logcat`. iOS users can acess the logs in the `console app` on their MacOS.
## How do I gather mobile app logs?
See the Mattermost Support Knowledge Base article on [gathering mobile app logs](https://support.mattermost.com/hc/en-us/articles/30147601934100-How-to-Gather-Mobile-App-Logs) for details.

View File

@@ -0,0 +1,162 @@
---
title: "Mobile security features"
---
<PlanAvailability slug="ent-adv" />
This document outlines the key security features implemented in the mobile application, explains the significance of each control, and details our continuous security practices to maintain an up-to-date security posture.
## Jailbreak and root detection
Mattermost leverages built-in checks from the Expo framework to identify jailbroken (iOS) and rooted (Android) devices:
- On **Android**, the app looks for the presence of known jailbreak/root binaries, such as the `su` binary in `/system/xbin/su`, which is a common indicator that the device has been rooted to allow unauthorized elevated access.
- On **iOS**, the detection process involves checking for unusual apps (e.g., Cydia), modified system paths, and testing whether the app can alter protected system files—all signs that the device may be jailbroken.
See the [jailbreak/root protection configuration setting](/administration-guide/configure/environment-configuration-settings#enable-jailbreakroot-protection) documentation for details on enabling this feature.
<Note>
Client-side detection methods are not bulletproof and can be bypassed by a sufficiently motivated user with root or jailbreak access. Determined users can employ reverse engineering to disable or modify these checks to produce false positives/negatives or even modify and recompile the source code to remove them entirely, allowing app usage on rooted/jailbroken devices.
</Note>
## Biometric authentication
Mattermost integrates with iOS Face ID/Touch ID and Android’s Biometric API. When enabled by the server administrator, biometric checks are required before accessing specific servers, and the Mattermost mobile app mandates that a device PIN or biometric lock is active.
See the [biometric authentication configuration setting](/administration-guide/configure/environment-configuration-settings#enable-biometric-authentication) documentation for details on enabling this feature and the user workflows in which users must authenticate.
<Note>
Biometric authentication, such as Face ID or fingerprint recognition, is handled by the device’s operating system. Mattermost does not provide or warrant the biometric functionality. The app will unlock if the OS determines that the biometric input is a positive match. Accuracy, security, and availability of biometric authentication depend entirely on the device and its underlying platform.
</Note>
## Screenshot and screen recording prevention
Preventing screenshots and screen recordings protects sensitive information from being inadvertently or maliciously shared. This control is essential in ensuring that confidential communications and data remain within the secure confines of the app. By blocking unauthorized screen captures, Mattermost significantly reduces the risk of data leakage via visual content.
- On **iOS**, the app detects attempts to capture the screen. For screen recordings, it immediately applies a blur overlay to the view to obscure any sensitive information, while screenshots will capture no content at all.
- On **Android**, the app utilizes the FLAG_SECURE flag to block screen captures and recordings.
See the [prevent screen capture configuration setting](/administration-guide/configure/environment-configuration-settings#prevent-screen-capture) documentation for details on enabling this feature.
<Note>
This feature prevents screen recording and screenshot capture on the mobile device where the Mattermost app is running. It cannot control or prevent recording from external devices, such as another phone or camera pointed at the screen. Mattermost provides these protections through mobile OS-level capabilities but cannot guarantee absolute prevention of visual data capture through other means.
</Note>
## Secure file previews
Preventing file downloads protects sensitive information from being inadvertently or maliciously shared. This control is essential in ensuring that confidential documents and media remain within the secure confines of the app. By enabling in-app previews for supported file types and restricting downloads, Mattermost significantly reduces the risk of data leakage while maintaining essential file-viewing capabilities.
See the [secure file preview](/administration-guide/configure/environment-configuration-settings#enable-secure-file-preview-on-mobile) and [managing PDF link navigation](/administration-guide/configure/environment-configuration-settings#allow-pdf-link-navigation-on-mobile) configuration settings documentation for details on enabling these features.
## Mobile watermarking
Mobile watermarking is an experimental Enterprise Advanced capability from Mattermost v11.7 onward, that helps organizations attribute mobile screenshots and shared screen captures to a specific user, server, and point in time. When this setting is enabled by a system admin, authenticated Mattermost mobile sessions display a visible watermark overlay on top of the app interface that includes:
- The user's username.
- The server domain.
- The current date in `YYYY-MM-DD` format.
- The current time in `HH:mm` format.
The watermark is intended to support data loss prevention (DLP) workflows by making it easier to identify the source and timing of any image taken of the Mattermost mobile app. Mobile watermarking is disabled by default.
See the [Enable Mobile Watermark](/administration-guide/configure/experimental-configuration-settings#enable-mobile-watermark) configuration setting documentation for details on enabling this experimental feature.
<Note>
- The mobile watermark is a visual overlay only. It does not prevent users from taking screenshots, recording the screen, exporting files, or sharing content through other means. For controls that block screen capture on the device itself, see [screenshot and screen recording prevention](#screenshot-and-screen-recording-prevention).
- This feature applies only to the Mattermost mobile app. It does not add a watermark to the Mattermost web app or desktop apps.
- This is an experimental capability. Its behavior, defaults, and visual presentation may change in future releases based on customer feedback.
</Note>
## Microsoft Intune Mobile Application Management (MAM)
Mattermost supports Microsoft Intune MAM to enforce identity-based, app-level data protection on iOS devices without requiring full device enrollment in a mobile device management (MDM) solution.
<Important>
Microsoft Intune MAM enforcement for Mattermost is currently supported on **iOS** only. We recommend using Android for Work profiles until Android Intune support is available.
</Important>
Intune MAM applies security policies directly to the Mattermost mobile app using Microsoft Entra ID as the identity authority. This enables organizations to protect corporate or mission-sensitive data on Bring Your Own Device (BYOD) and mixed-use devices while preserving user privacy.
Key security capabilities enabled through Intune MAM include:
- **Mandatory enrollment** before accessing Mattermost on mobile
- **Identity-based enforcement** using Microsoft Entra ID
- **Selective wipe** of Mattermost work data without affecting personal apps or device data
- **Clipboard, file sharing, and data transfer restrictions**
- **Screenshot and screen recording prevention**
- **Managed browser enforcement** and controlled link handling
- **Immediate enforcement** when policies or licensing change, including during active sessions
Intune MAM enforcement is applied **per Mattermost workspace** and evaluated continuously at runtime. If a device becomes non-compliant, enrollment fails, or required policies are not met, access to protected content is blocked automatically.
This approach allows organizations to extend zero-trust and data loss prevention (DLP) controls to mobile users without assuming ownership or management of the underlying device.
See the [Microsoft Intune MAM configuration guide](/deployment-guide/mobile/configure-microsoft-intune-mam) for deployment and configuration details.
## Mobile Ephemeral Mode
Mobile applications typically cache messages, files, and attachments on-device indefinitely. Two security concerns drive the need for administrator-controlled data lifecycle management on mobile devices:
- **Unbounded sensitive data accumulation.** Without data-age controls, weeks or months of sensitive content can accumulate on any device a user has logged into — well beyond what operational need justifies.
- **Offline exposure after device loss.** Remotely wiping a device requires it to be reachable — the condition least likely to hold when a device is lost, stolen, or in an adversarial environment. Unmanaged or personally-owned devices may not be enrolled in MDM at all, leaving cached content with no remote deletion path.
Mobile Ephemeral Mode addresses both concerns by giving administrators direct, server-side control over how long data persists on mobile devices. The app enforces this policy locally — including while offline and across app and device restarts — so data is removed based on elapsed time, not device reachability.
Mobile Ephemeral Mode generates an [audit log](/administration-guide/manage/logging#audit-logging) event for each delete, purge, and wipe operation. Because these operations can execute on a device that is unreachable — where no administrator has direct visibility — audit logging provides verifiable proof that ephemeral policies were enforced. This supports compliance requirements for data lifecycle management and destruction accountability. Events that occur while the device is offline are reported to the server on reconnection.
See the [Mobile Ephemeral Mode configuration settings](/administration-guide/configure/environment-configuration-settings#mobile-ephemeral-mode) to configure these controls.
## Mobile data isolation
Mattermost mobile applications are designed to ensure that sensitive data is stored securely and isolated from other applications on the device. This isolation is achieved through a combination of OS-level security features, app sandboxing, and secure data storage practices.
Mattermost stores 3 types of data within the mobile app:
- **SQLite Database**: For offline access to posts and channels that the user has viewed.
- **Cached Files**: For temporary storage (e.g., PDFs) of viewed files. They are periodically purged.
- **Logs**: Minimal logs kept for troubleshooting purposes.
The Mattermost mobile app for Apple iOS and Android devices uses the native OS security architecture to encrypt data-at-rest on mobile devices, ensuring that stored information remains secure even if the device is lost or stolen. This encryption protects sensitive data, such as messages and files, from unauthorized access.
Data stored by the Mattermost mobile app only resides within the app’s private storage container. This storage location is isolated by each platform’s rigorous sandboxing model. Learn more about [secure file storage](/deployment-guide/mobile/secure-mobile-file-storage) for Mattermost mobile applications.
### Security measures
- **OS sandboxing & app access isolation**: Mattermost’s data is confined within its app-specific sandbox (see [Apple’s iOS sandboxing](https://support.apple.com/guide/security/security-of-runtime-process-sec15bfe098e/web) and [Android’s sandboxing](https://source.android.com/docs/security/app-sandbox) guidelines). This sandboxing mechanism ensures that all stored data—whether in the SQLite databases, cached files, or logs—is isolated and inaccessible to other applications. This is why TikTok, and any other application is blocked from accessing Mattermost data.
- **iOS** employs a rigorous sandboxing model that relies on containerized file systems and strict process isolation. Each app operates within its own sandbox, with its home directory randomly assigned during installation. As a result, data stored within the Mattermost app’s sandbox directory remains accessible only to the app unless explicitly shared by the user.
- **Android** employs scoped storage by assigning each app its own Linux user ID and a dedicated private directory. This model prevents other applications from accessing an app’s private directory without explicit permission. As a result, the Mattermost app’s data remain inaccessible to other apps—unless the device is rooted, or the user explicitly shares the data.
- **Cache invalidation**: Cached files are periodically deleted.
- **No Google or Apple Cloud backup**: Mattermost files are not backed up during normal cloud backup procedures.
- On **Android**, the application explicitly disables backups (using the appropriate manifest settings), ensuring that all Mattermost files remain strictly on-device.
- On **iOS**, although the operating system automatically backs up files stored in the app's `Documents` folder, Mattermost intentionally stores its files in the `Library/Caches` directory, which is excluded from iCloud backups.
- **Controlled data export**: Data only leaves Mattermost through explicit user actions such as:
- Manually exporting a file.
- Takes a screenshot (if not blocked by policy or with a secondary camera).
- Sharing content using OS features (e.g., share sheet).
<Note>
This feature restricts direct access to stored data through robust OS-level sandboxing and storage controls. However, it cannot prevent unauthorized extraction if attackers employ alternative methods. For instance, on jailbroken (iOS) or rooted (Android) devices, where system integrity is compromised, an attacker may bypass standard security measures.
Similarly, exploiting zero-day or known OS vulnerabilities—or malicious apps that exploit permission weaknesses—could grant access to device storage. Mattermost uses mobile OS-level safeguards but cannot guarantee absolute prevention of such unauthorized data access.
</Note>
## Security compliance
- **Secure SDLC**: The mobile app adheres to the same secure Software Development Lifecycle (SDLC) process as all Mattermost components. This guarantees that new mobile features undergo comprehensive security reviews and that any issues are addressed before release.
- **Vulnerability management**: The Mattermost mobile app is included in Mattermost’s public bug bounty program, inviting security researchers to rigorously assess the application. Additionally, established remediation SLAs ensure that any security issues are resolved promptly.
- **Continuous dependency scanning**: Mattermost uses Snyk Open Source to conduct daily scans of all dependencies. This continuous approach ensures that any newly disclosed vulnerabilities are quickly identified and addressed within defined SLAs.
- **BESPIN compliance**: Mattermost adheres to strict security evaluations including:
- Device Protection Profiles (NIAP Evaluation)
- Security Dependency & Code Analysis
- Code Complexity & Testing Standards

View File

@@ -0,0 +1,153 @@
---
title: "Mobile deployment troubleshooting"
---
import useBaseUrl from '@docusaurus/useBaseUrl';
<PlanAvailability slug="all-commercial" />
## I keep getting a message "Cannot connect to the server. Please check your server URL and internet connection."
First, confirm that your server URL has no typos and that it includes `http://` or `https://` according to the server deployment configuration.
If the server URL is correct, there could be an issue with the SSL certificate configuration.
To check your SSL certificate set up, test it by visiting a site such as [SSL Labs](https://www.ssllabs.com/ssltest/index.html). If there’s an error about the missing chain or certificate path, there is likely an intermediate certificate missing that needs to be included.
Please note that the apps cannot connect to servers with self-signed certificates, consider using [Let's Encrypt](/deployment-guide/server/setup-nginx-proxy#configure-nginx-with-ssl-and-http2) instead.
## Login with ADFS/Office365 is not working
In line with Microsoft guidance we recommend [configuring intranet forms-based authentication for devices that do not support WIA](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configure-intranet-forms-based-authentication-for-devices-that-do-not-support-wia).
## How do I attach mobile app logs to a message?
Use `/mobile-logs` during mobile troubleshooting to let users attach Mattermost mobile app logs to messages. Running `/mobile-logs on` shows the **Attach app logs** option in the attachment menu of the message composer, so users can include device-side logs when messaging an administrator or support engineer. Users can also turn this option on or off from the **Report a problem** screen in the mobile app. The command responds with an ephemeral message visible only to the user who ran it.
<Important>
This command requires Mattermost mobile app v2.38 or later.
</Important>
- Enable **Attach app logs** for yourself using `/mobile-logs on`.
- Disable **Attach app logs** for yourself using `/mobile-logs off`.
- Check whether **Attach app logs** is enabled using `/mobile-logs status`.
- System admins can manage the setting for another user by appending a username, such as `/mobile-logs on @username`, `/mobile-logs off @username`, or `/mobile-logs status @username`.
<Important>
Non-admin users can only manage their own preference. Attempts to target another account return a neutral **Unable to change mobile log settings for that user** message to avoid username enumeration. Preference changes made through this command are recorded in the audit log.
</Important>
## I see a “Connecting…” bar that does not go away
If your app is working properly, you should see a grey “Connecting…” bar that clears or says “Connected” after the app reconnects.
If you are seeing this message all the time, and your internet connection seems fine, ask your server administrator if the server uses NGINX or another webserver as a reverse proxy. If so, they should check that it is configured correctly for [supporting the websocket connection for APIv4 endpoints](/deployment-guide/server/setup-nginx-proxy#configure-nginx-as-a-proxy-for-mattermost-server).
## All my outbound connections need to go through a proxy. How can I connect to the Mattermost Hosted Push Notification Service?
You can set up an internal server to proxy the connection out of their network to the Mattermost Hosted Push Notification Service (HPNS) by following the steps below:
1. Make sure your proxy server is properly configured to support SSL. Confirm it works by checking the URL at [https://www.digicert.com/help/](https://www.digicert.com/help/).
2. Setup a proxy to forward requests to the HPNS URL matching your server's [push notification server location](/administration-guide/configure/push-notification-server-configuration-settings#push-notification-server): `https://global.push.mattermost.com`, `https://us.push.mattermost.com`, `https://eu.push.mattermost.com`, or `https://ap.push.mattermost.com`.
3. In Mattermost set **System Console** \> **Notification Settings** \> **Mobile Push** \> **Enable Push Notifications** in prior versions or **System Console \> Environment \> Push Notification Server \> Enable Push Notifications** in versions after 5.12 to "Manually enter Push Notification Service location"
4. Enter the URL of your proxy in the **Push Notification Server** field.
<Note>
Depending on how your proxy is configured you may need to add a port number and create a URL like `https://push.internalproxy.com:8000` mapped to your region's HPNS URL, such as `https://us.push.mattermost.com`.
</Note>
## Build gets stuck at `bundleReleaseJsAndAssets`
As a workaround, you can bundle the `js` manually first with
``` sh
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
```
and then ignore the gradle task with
``` sh
./gradlew assembleRelease -x bundleReleaseJsAndAssets
```
## No image previews available in the mobile app
This can happen if the server running Mattermost has its mime types not set up correctly. A server running Linux has this file located in `/etc/mime.types`. This might vary depending on your specific OS and distribution.
Some distributions also ship without `mailcap` which can result in missing or incorrectly configured mime types.
## Messages with emojis aren't being sent from the Mobile App
This can occur if the server running Mattermost is configured with an incorrect character set. To resolve this issue, in the `config.json` file under `SqlSettings`, ensure that the `DataSource` key is configured correctly, then restart the Mattermost server.
For example:
``` text
"SqlSettings": {
"DataSource": "<user:pass>@<servername>/mattermost?charset=utf8mb4,utf8",
[...]
}
```
See our [Configuration Settings](/administration-guide/configure/environment-configuration-settings#data-source) documentation for details on configuring the connection string to the master database.
## Testing mobile push notifications
Make sure to configure push notifications for your [pre-built mobile apps](/deployment-guide/mobile/mobile-app-deployment), or for [your custom built mobile apps](/deployment-guide/mobile/distribute-custom-mobile-apps).
Then use the following instructions to confirm push notifications are working properly.
1. Log in to your mobile app with an account on your Mattermost Server, which we’ll refer to as “Account A”.
2. (iOS) When the app asks whether you wish to receive notifications, **confirm you want to receive notifications**.
<img src={useBaseUrl('/images/mobile_push_prompt.png')} width="300" alt="Mattermost prompts you to confirm whether you want to allow mobile push notifications. To test mobile push notifications, you must select Allow." />
3. Confirm push notifications are enabled for “Account A”.
1. Go to the notification settings menu in the mobile app.
<img src={useBaseUrl('/images/mobile_notification_settings.gif')} width="300" alt="Access notification settings by selecting your profile picture to access Settings &gt; Notifications." />
2. Check that the mobile push notifications are set to send.
<img src={useBaseUrl('/images/mobile_push_send_for.png')} width="300" alt="Select Push Notifications to confirm when mobile push notifications will be sent." />
<img src={useBaseUrl('/images/mobile_push_send_when.png')} width="300" alt="Specify whether all new messages or only mentions and direct messages send push notifications." />
4. Have “Account A” put the app to background or close the app.
5. Using a browser, log in to “Account B” on the same Mattermost Server.
6. Open a direct message with “Account A”, and send a message.
7. A push notification with the message should appear on the mobile device of “Account A”.
## Troubleshooting push notifications
If you did not receive a push notification when testing push notifications, use the following procedure to troubleshoot:
1. In **System Console \> Environment \> Logging \> File Log Level**, select **DEBUG** in order to watch for push notifications in the server log.
2. Delete your mobile application, and reinstall it.
3. Log in with "Account A" and **confirm you want to receive push notifications** when prompted by the mobile app.
4. Go to **Profile** \> **Security** \> **View and Logout of Active Sessions** to confirm that there is a session for the native mobile app matching your login time.
5. Retest push notifications.
6. If no push notification displays, go to **System Console** \> **Server Logs**, then select **Reload**. Look at the bottom of the logs for a message similar to:
`[2016/04/21 03:16:44 UTC] [DEBG] Sending push notification to 608xyz0... wi msg of '@accountb: Hello'`
> - If the log message displays, it means a message was sent to the HPNS server and was not received by your mobile app. Please [create a support ticket](https://support.mattermost.com/hc/en-us/requests/new) with the subject "HPNS issue" for help from Mattermost's Support team.
> - If the log message does not display, it means no mobile push notification was sent to “Account A”. Please repeat the process starting at step 2 and double-check each step.
<Important>
To conserve disk space, once your push notification issue is resolved, go to **System Console \> Environment \> Logging \> File Log Level**, then select **ERROR** to switch your logging detail level from **DEBUG** to **Errors Only**.
</Important>
If push notifications are not being delivered on the mobile device, confirm that you're logged in to the **Native** mobile app session through **Profile \> Security \> View and Log Out of Active Sessions**. Otherwise, the <code>DeviceId</code> won't get registered in the <code>Sessions</code> table and notifications won't be delivered.
## Integration posts (Mattermost Blocks) do not render or respond
If buttons, menus, or structured content from an integration post is missing or unresponsive on mobile, see the [Mattermost Blocks reference](https://developers.mattermost.com/integrate/reference/mm-blocks/) in the developer documentation.

View File

@@ -0,0 +1,163 @@
---
title: "Secure file storage"
---
<PlanAvailability slug="ent-plus" />
This document outlines the security measures governing file storage in the Mattermost mobile app for iOS and Android. It describes how files are stored, accessed, and protected within the application container, addressing concerns related to sensitive data on mobile devices. The objective is to ensure that only authorized personnel can view, access, or share such data while preventing exposure to unauthorized parties and ensuring isolation from third-party applications.
Mattermost leverages robust sandboxing mechanisms on both iOS and Android to securely store files in its cache folder within the application container, ensuring isolation from unauthorized third-party apps. User-initiated actions (download, share, copy link) are controlled by server-side permissions, allowing administrators to restrict access to sensitive data, like HIPAA-regulated information, to authorized personnel only.
## File storage and app sandbox security
Files uploaded or accessed via the Mattermost mobile app are stored in the app’s cache folder, which resides within the app’s private storage container. This storage location is isolated by each platform’s sandboxing model:
### iOS – app sandbox
- **Sandboxing & storage:**
iOS employs a rigorous sandboxing model that relies on containerized file systems and strict process isolation. Each app operates within its own sandbox, with its home directory randomly assigned during installation. As a result, files stored within the Mattermost app’s cache folder remain accessible only to the app unless explicitly shared by the user.
- **Secure file viewing:**
- Non-image and non-video files are rendered using secure frameworks such as QLPreviewController. This controller displays file previews within the app’s sandbox, ensuring that raw file data isn’t exposed to external processes.
- Supported image and video files are previewed directly within the app, with the files downloaded to the app's cache folder located within its secure sandbox. For unsupported image and video formats, the Mattermost mobile app uses the QLPreviewController framework, just as it does for other file types.
- If the file format is also unsupported by QLPreviewController and [mobile downloads are enabled](/administration-guide/configure/site-configuration-settings#allow-file-downloads-on-mobile) on the server, users can download the file to a location of their choosing. However, if mobile downloads are disabled, these files become unavailable to the user.
- **Official references:**
- [Apple App Sandbox Design Guide](https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html)
- [Security of runtime process in iOS, iPadOS and visionOS](https://support.apple.com/en-gb/guide/security/sec15bfe098e/web)
- [Apple Security Guide](https://help.apple.com/pdf/security/en_GB/apple-platform-security-guide-b.pdf)
### Android – scoped storage
- **Sandboxing & storage:**
Android employs scoped storage by assigning each app its own Linux user ID and a dedicated private directory. This model prevents other applications from accessing an app’s cache without explicit permission. As a result, the Mattermost app’s files remain inaccessible to other apps—unless the device is rooted, or the user explicitly shares the data.
- **Secure file viewing:**
- When users attempt to view non-image/video files, Mattermost uses an `Intent.ACTION_VIEW` to open the file. This intent delegates rendering to an external app only if the user explicitly triggers the action, while the file remains securely stored within Mattermost’s cache folder.
- Viewing non-image/video files is available only if [mobile downloads are enabled](/administration-guide/configure/site-configuration-settings#allow-file-downloads-on-mobile) on the server.
- Image and video files with supported formats are previewed directly within the app, with the files downloaded to the app's cache folder located within its secure sandbox. For unsupported image and video formats, the Mattermost mobile app uses `Intent.ACTION_VIEW` to open the file with an external application, just as it does for other file types.
- **Official reference:**
- [Scoped Storage](https://developer.android.com/about/versions/10/privacy/changes#scoped-storage)
Additionally, both platforms may clear cached data automatically (e.g., under low storage conditions or upon user logout), thereby reducing the risk of sensitive information remaining on the device.
## Differentiating file handling to external applications
- **Previewing files:**
File previewing follows the secure viewing practices described above in the “Secure File Viewing” sections for iOS and Android. All files prior to being previewed are stored in the cache folder of the Mattermost app sandbox. Images and videos with supported formats are previewed directly within the Mattermost mobile app. Non‑image and non‑video files are also previewed in-app in iOS but are handed off to an external application in Android while the raw data remains securely stored in the app’s cache. Previewing non-image/non-video files is possible only if [mobile downloads are enabled](/administration-guide/configure/site-configuration-settings#allow-file-downloads-on-mobile) on the server side.
- **Downloading files:**
- When a user initiates a file download, the file is first stored in Mattermost’s private cache directory. The user is then immediately prompted to save it to another destination via platform-specific sharing methods.
- On **iOS** devices:
- The built-in sandboxing ensures that the downloaded files remain inaccessible to other apps unless the user explicitly shares or saves them through the system’s file sharing mechanisms. Once downloaded, the file appears in the gallery.
- If the server has the download setting enabled, the user has two options:
1. Download the file: Opens the **Files** app, allowing the user to save the file to any permitted location, including iCloud.
2. Share the file: Launches the native share sheet, enabling the user to share the file with other compatible applications.
- On **Android** devices, the app employs the system’s file picker. This allows the end-user to select a preferred storage location. Once saved, the file becomes accessible to other apps based on the chosen location and the device’s file sharing permissions.
## File accessibility options
Depending on server configuration, users may download files, share them, or copy a public link directly from the Mattermost mobile app. These actions are always user‑initiated, ensuring that sensitive data is only exposed with explicit consent.
Additionally, administrators have the option to restrict mobile file uploading and downloading to ensure that sensitive content remains within approved channels. When mobile file downloads are disabled, the app allows only image and video file previews. However, if general file sharing is enabled on the Mattermost server, file operations via mobile browsers will still be possible.
## Layered defense strategies for sensitive eata
Mattermost is designed to protect sensitive data—such as sensitive information and HIPAA-regulated information—by ensuring that only authorized personnel can access or share it. The platform combines secure mobile app features with powerful server-side controls, providing a layered defense that minimizes the risk of data exposure.
### Core defense pillars
- **Robust authentication:** Mattermost requires user authentication through SSO (e.g., SAML, LDAP, OpenID Connect) or traditional username/password logins. This authentication is managed by server-side identity controls, ensuring that only verified users can access the app and its data. For more details, see the [Mattermost Security Overview](/security-guide/security-guide-index).
- **Server-side access controls:** Administrators can enforce policies through the System Console to restrict file downloads, sharing, and public link generation. Currently, policies are applied at the server level. For more details, see [Configuration Settings - File Sharing and Downloads](/administration-guide/configure/site-configuration-settings#file-sharing-and-downloads).
- **Sandbox isolation:** As discussed earlier, Mattermost’s mobile apps store files in a sandboxed environment. This isolation ensures that even if a device is shared or compromised, other apps cannot access the cached files without explicit user action.
- **Controlled file previews:** File previews (via QLPreviewController on **iOS** or open intent on **Android**) occur within the application’s controlled environment or delegate to OS-approved apps without duplicating sensitive data outside the sandbox.
- **OS-Level encryption:** While files in the cache folder are stored unencrypted by default, they are protected at rest by OS-level encryption (iOS File Data Protection and Android Full Disk Encryption).
By combining strict authentication, server-side controls, sandbox isolation, and secure file handling, Mattermost ensures that sensitive data remains confined to authorized users, with access and sharing tightly controlled by server policies, platform security features, and explicit user consent.
## Testing procedure to validate file isolation
The playbook below aims to test and confirm that files stored in the Mattermost app’s private cache folder—where sensitive data may reside—are not accessible by unauthorized third-party applications. The tests are designed to show that while public directories, such as Downloads/ can be accessed, the private Mattermost cache remains isolated unless a file is explicitly shared by an authorized user.
1. **Preparation**
- On **Android**:
- Install Adobe Acrobat Reader for PDF viewing.
- Install Files by Google as a file manager.
- Install Google Chrome as a system browser.
- On **iOS**:
- Install Adobe Acrobat Reader (from the App Store).
- Use the built-in Files app.
- Use Safari as the default browser.
- Any PDF viewer, file manager, or browser can be used for these steps.
2. **Control test: Verify public directory accessibility**
- **Android:**
- Open Files by Google.
- Navigate to a known public directory (e.g., Downloads/).
- Confirm that files in this location are visible and can be opened.
- **iOS:**
- Open the Files app.
- Browse to an accessible directory (e.g., iCloud Drive or “On My iPhone” public folders).
- Confirm these files are accessible.
This step demonstrates that allowed directories can be accessed, setting a baseline for comparison.
3. **Attempt unauthorized access to Mattermost’s private cache**
- **Android:**
- In Files by Google, try navigating through the directory structure to identify files of the Mattermost application.
- Verify that you cannot access private directories such as Mattermost app’s private cache folder.
- **iOS:**
- Open the Files app.
- Verify that the Mattermost app’s private cache folder does not appear under “On My iPhone/iPad.”
4. **Attempt unauthorized access to a specific file in Mattermost’s private cache**
- **Android:**
- Use the search functionality in Files by Google to search for a known file name from the Mattermost cache.
- Verify that the file does not appear in search results.
- **iOS:**
- Use the Files app’s search capability to look for a specific file name from the Mattermost cache.
- Confirm that the file does not appear in search results.
5. **Attempt authorized access to downloaded file**
- **Android:**
- Confirm that mobile downloads are enabled on the server.
- Download a file using the Mattermost mobile app.
- Open the Files by Google app and verify that the downloaded file is visible and opens correctly.
- **iOS:**
- Confirm that mobile downloads are enabled on the server.
- Download a file using the Mattermost mobile app.
- Open the iOS Files app and verify that the downloaded file appears and can be opened successfully.
6. **Repeat across multiple apps and devices**
The steps above use the Files app of Google and iOS. Repeat these tests using each suggested app on different devices and OS versions (both Android and iOS) to ensure that the private cache folder remains inaccessible under all conditions.
## Test execution & findings
Mattermost executed the playbook above, including scanning for hidden files, both during normal operation and after forcing the app to stop or crash, and observed the following results:
- **Devices Tested**: iPhone 12, iOS 18.4, Android 11
- **Apps Used**: Adobe Reader, Google Files app, Android’s native Files app, iOS Files app, Files Media Manager, Hidden Files Finder, Hidden Files Finder & Recover
- **Results**: Third-party file browsers and recovery tools consistently failed to access the Mattermost app’s cache folder or its contents. Access was only possible when files were explicitly downloaded or shared via Mattermost’s controlled functionality by an authorized user.
- **Outcome**: Files remain isolated within the app container, adhering to platform security guidelines and protecting against unauthorized access.
The documented testing procedures confirm that the app’s file storage remains inaccessible to unauthorized third-party applications, thereby maintaining a strong security posture. Coupled with strong authentication and native OS encryption, the Mattermost mobile app provides a robust framework that keeps sensitive data on mobile devices confined to authorized users while addressing key access control and risk mitigation requirements.

View File

@@ -0,0 +1,121 @@
---
title: "Quick Start Evaluation"
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
This guide provides instructions for quickly trying out Mattermost using either Docker or Azure Marketplace. These options are ideal for testing and evaluation purposes as they allow you to quickly get a Mattermost instance up and running for exploration and testing. However, these quick start options are not recommended for production use. They are configured for demonstration purposes only.
## Deployment options
<Tabs>
<TabItem value="azure-marketplace" label="Azure Marketplace">
Mattermost is published as an **Azure Marketplace** solution that deploys a single Ubuntu virtual machine with Mattermost, PostgreSQL, network configurations, and the necessary Azure resources. This quick start evaluation option is preferred for customers already using Azure, as it integrates seamlessly within their existing infrastructure.
## Prerequisites
- An active **Azure subscription** with permission to create resources and accept **Azure Marketplace** billing terms for the offer.
- Familiarity with the **Azure portal** (resource groups, networking, and virtual machines).
## What gets deployed
The template provisions a small, self-contained stack in the resource group you select, including:
1. **Virtual machine (Linux):** Runs Mattermost, PostgreSQL, and the reverse proxy.
2. **Public IP address:** Allows access to the Mattermost workspace over the public internet, enabling users to connect to the platform securely.
3. **Network interface:** Facilitates communication between the Virtual Machine and other Azure resources through a defined network layer.
4. **Network security group:** Acts as a virtual firewall, controlling inbound and outbound traffic to protect the deployed resources from unauthorized access.
5. **Managed OS disk:** Provides persistent storage mounted to the Virtual Machine for storing files generated by Mattermost, including uploaded documents and system configurations.
6. **Virtual network:** An isolated network environment for the deployed resources, enabling private and controlled connectivity between infrastructure components. This can be a newly created or existing environment depending on your selection in the portal.
## Step 1: Select a plan and start creation
Go to the [Mattermost - Quick Start Evaluation (VM)](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/mattermost.mattermost-all-in-one) Azure Marketplace application to begin. Click **Get it now**, then select the **Mattermost - Quick Start Evaluation (VM)** plan, and click **Create** to open the deployment wizard.
## Step 2: Basic Configuration
On the **Basics** tab, configure the following:
1. **Subscription:** Choose the Azure subscription where the deployment will live.
2. **Resource group:** Either select an existing resource group or create a new one. Using a **new** resource group keeps evaluation resources easy to find.
3. **Region:** Select the deployment region for your Virtual Machine (for example, **East US** or **West Europe**).
4. **Virtual Machine name:** Provide a unique name for your Virtual Machine.
5. **Username:** Linux administrator account on the VM.
6. **Email:** Used for Let's Encrypt registration when the instance requests a TLS certificate. Use a mailbox you can access since you may receive operational emails from the certificate authority.
7. **Support email:** Contact email for end users to reach the instance administrator for troubleshooting.
8. **Authentication type:** **Password** or **SSH public key** only for Linux sign-in to the VM. Password is often simpler for a quick trial; SSH key is appropriate if your organization requires key-based Linux access.
## Step 3: Virtual Machine Settings and Network Configuration
On **Virtual Machine Settings** tab, configure the following:
1. **Virtual machine size:** For trials, we recommend **Standard_F2s_v2** size but you can choose any other size available in your region.
2. **Public IP address:** Typically **create new**. You must set a **DNS prefix** (label) that is **globally unique** in Azure; it forms part of your URL. This DNS will allow public access to your workspace. It is important that you do not already have a matching DNS name within your Azure subscription, or your deployment may fail later in the process.
3. **Virtual network:** **Create new** with the suggested address space, or attach an existing VNet and subnet that meet the constraints. Using a new virtual network avoids collisions with overlapping address spaces in the same subscription.
The portal may show a preview of your URL in the form `https://<dns-label>.<region>.cloudapp.azure.com`. That is the address you will use once TLS and Mattermost are ready.
## Step 4: Review and create
Review settings, accept any **Marketplace** terms if prompted, then select **Create**. Provisioning usually takes a few minutes, and the first-boot configuration may take more time before HTTPS works reliably.
**After deployment completes:**
- In the Azure portal, open the **resource group** you used.
- Open the **Public IP address** resource (often named `<your-vm-name>-ip` unless you changed it).
- Under **Essentials**, note the **DNS name**. Your site URL is:
`https://<dns-label>.<region>.cloudapp.azure.com`
Example: `https://myorg.eastus.cloudapp.azure.com`
Use **https**; the deployment is intended to serve Mattermost over TLS.
## Step 5: Open Mattermost and create your administrator
In a browser, go to your **HTTPS** URL. Mattermost will prompt you to **create the first user**, which becomes the **System Administrator**. That account is different from the **Linux** username and password (or SSH key) you configured in Step 3.
Congratulations! You’ve successfully deployed Mattermost for evaluation.
</TabItem>
<TabItem value="docker-preview-container" label="Docker Preview Container">
The fastest way to try Mattermost is using the official Docker preview container. This method requires minimal setup and provides a fully functional Mattermost instance.
## Docker Preview Prerequisites
- Docker installed on your system
- At least 1GB of available RAM
- At least 1GB of available disk space
## Run Mattermost using Docker
1. Pull and run the Mattermost preview container:
> ``` bash
> docker run --name mattermost-preview -d --publish 8065:8065 mattermost/mattermost-preview
> ```
2. Access Mattermost at `http://localhost:8065`
3. Create your first admin account when prompted.
</TabItem>
</Tabs>
## Next steps
After setting up your Mattermost instance using either method:
- Create your first team and channels
- Invite users to join your workspace
- Explore Mattermost features and integrations
- Review the [Application architecture](/deployment-guide/application-architecture) to understand the system better
- [Plan your deployment](/deployment-guide/server/server-deployment-planning) before moving to production
For additional help or questions, visit the [Mattermost community forums](https://forum.mattermost.com/) or refer to the [Deployment troubleshooting](/deployment-guide/server/troubleshooting) guide.
[Book a live demo](https://mattermost.com/request-demo/) or [talk to a Mattermost expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization's secure collaboration needs. Or try Mattermost yourself with a [1-hour preview](https://mattermost.com/sign-up/) for instant access to a live sandbox environment.

View File

@@ -0,0 +1,7 @@
---
title: Additional HA considerations
unlisted: true
---
[Elasticsearch](https://www.elastic.co) provides enterprise-scale deployments with optimized search performance and prevents performance degradation and timeouts. Elasticsearch allows you to search large volumes of data quickly, in near real-time, by creating and managing an index of post data. Mattermost’s implementation uses [Elasticsearch](https://www.elastic.co) as a distributed, RESTful search engine supporting highly efficient database searches in a [cluster environment](/deployment-guide/server/high-availability-cluster-based-deployment). Visit the [Mattermost Elasticsearch product documentation](/deployment-guide/scale/elasticsearch-setup) for deployment and configuration details.
Performance monitoring support enables a Mattermost server to track system health for large Enterprise deployments through integrations with [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/). These integrations support data collection from several Mattermost servers, which is particularly useful if you’re running Mattermost [in high availability mode](/deployment-guide/server/high-availability-cluster-based-deployment). Once you’re tracking system health, you can [set up performance alerts](/administration-guide/scale/performance-alerting) on your Grafana dashboard. Visit the [Mattermost Performance Monitoring product documentation](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring) for installation details.

View File

@@ -0,0 +1,156 @@
---
title: "Backing storage benchmarks"
---
Understanding the performance characteristics of your backing storage is critical for optimizing your Mattermost deployment. These benchmarks offer insights into the relative performance of each storage option, helping you make informed decisions based on your use case and infrastructure needs.
This page provides detailed write and read benchmark results for supported storage options including [local file system (EBS, gp3)](#local), [network file system (EFS)](#efs), and [object storage (S3)](#s3).
## Write operations
<table style={{width: '73%'}}>
<colgroup>
<col style={{width: '10%'}} />
<col style={{width: '20%'}} />
<col style={{width: '20%'}} />
<col style={{width: '22%'}} />
</colgroup>
<thead>
<tr>
<th>File Size</th>
<th>Local (EBS)</th>
<th>EFS</th>
<th>S3</th>
</tr>
</thead>
<tbody>
<tr>
<td>100KB</td>
<td>0.57 ms (±0.26 ms, p50: 0.63 ms)</td>
<td>34.47 ms (±6.33 ms, p50: 32.57 ms)</td>
<td>181.59 ms (±39.05 ms, p50: 174.83 ms)</td>
</tr>
<tr>
<td>1MB</td>
<td>2.08 ms (±0.92 ms, p50: 2.28 ms)</td>
<td>57.43 ms (±7.32 ms, p50: 58.16 ms)</td>
<td>277.13 ms (±49.95 ms, p50: 279.36 ms)</td>
</tr>
<tr>
<td>10MB</td>
<td>18.15 ms (±5.31 ms, p50: 18.23 ms)</td>
<td>180.58 ms (±97.95 ms, p50: 150.35 ms)</td>
<td>469.29 ms (±166.32 ms, p50: 462.12 ms)</td>
</tr>
<tr>
<td>100MB</td>
<td>585.14 ms (±274.38 ms, p50: 795.78 ms)</td>
<td>390.87 ms (±166.32 ms, p50: 339.20 ms)</td>
<td>1.09 s (±0.04 s, p50: 1.09 s)</td>
</tr>
<tr>
<td>1GB</td>
<td>7.42 s (±2.13 s, p50: 7.99 s)</td>
<td>3.05 s (±1.09 s, p50: 2.93 s)</td>
<td>10.65 s (±0.82 s, p50: 10.44 s)</td>
</tr>
<tr>
<td>10GB</td>
<td>70.66 s (±7.05 s, p50: 80.50 s)</td>
<td>26.54 s (±2.47 s, p50: 26.86 s)</td>
<td>109.05 s (±12.47 s, p50: 105.13 s)</td>
</tr>
</tbody>
</table>
<Note>
**Write Performance**: Local EBS storage is fastest for small files (100KB - 10MB), while EFS performs better for larger files (100MB - 10GB). S3 is consistently the slowest for writes across all file sizes.
</Note>
## Read operations
<table style={{width: '74%'}}>
<colgroup>
<col style={{width: '10%'}} />
<col style={{width: '20%'}} />
<col style={{width: '20%'}} />
<col style={{width: '22%'}} />
</colgroup>
<thead>
<tr>
<th>File Size</th>
<th>Local (EBS)</th>
<th>EFS</th>
<th>S3</th>
</tr>
</thead>
<tbody>
<tr>
<td>100KB</td>
<td>0.05 ms (±0.02 ms, p50: 0.04 ms)</td>
<td>0.66 ms (±0.17 ms, p50: 0.60 ms)</td>
<td>28.55 ms (±4.12 ms, p50: 27.63 ms)</td>
</tr>
<tr>
<td>1MB</td>
<td>0.18 ms (±0.06 ms, p50: 0.18 ms)</td>
<td>0.82 ms (±0.19 ms, p50: 0.72 ms)</td>
<td>27.03 ms (±4.28 ms, p50: 27.54 ms)</td>
</tr>
<tr>
<td>10MB</td>
<td>1.27 ms (±0.27 ms, p50: 1.16 ms)</td>
<td>7.83 ms (±18.12 ms, p50: 1.68 ms)</td>
<td>108.24 ms (±0.56 ms, p50: 108.18 ms)</td>
</tr>
<tr>
<td>100MB</td>
<td>16.50 ms (±0.95 ms, p50: 16.16 ms)</td>
<td>73.53 ms (±182.32 ms, p50: 16.91 ms)</td>
<td>1.05 s (±0.00 s, p50: 1.05 s)</td>
</tr>
<tr>
<td>1GB</td>
<td>167.89 ms (±2.19 ms, p50: 167.72 ms)</td>
<td>773.41 ms (±1768.89 ms p50: 168.17 ms)</td>
<td>10.49 s (±0.02 s, p50: 10.49 s)</td>
</tr>
<tr>
<td>10GB</td>
<td>1.57 s (±0.03 s, p50: 1.56 s)</td>
<td>1.56 s (±0.02 s, p50: 1.55 s)</td>
<td>150.66 s (±33.47 s, p50: 146.51 s)</td>
</tr>
</tbody>
</table>
<Note>
- **Read Performance**: Local and EFS have comparable read performance for very large files (10GB), but local storage outperforms for smaller files. S3 read performance is significantly slower, especially for large files (150.66s versus ~1.56s for 10GB files).
- **Consistency**: Local storage shows the most consistent performance (lower standard deviations) for small files, while EFS shows more consistent performance for large files. S3 generally has higher variability across all metrics.
- **Median vs Average**: The median (p50) values generally align with the averages, but in some cases (particularly EFS read operations), the median reveals that outliers significantly affect the average. For example, EFS read performance for 100MB and 1GB files shows much better median values than averages.
</Note>
![Read and Write Performance](/images/read-write-storage-performance.png)
## Testing notes
- For S3 tests, [Amazon S3 exported upload part size](/administration-guide/configure/environment-configuration-settings#amazon-s3-upload-part-size) was set to the default value (100MB).
- Local EBS storage is the stock gp3 (3000 IOPS) provided by EC2 instances.
- Both EBS and EFS solutions tested are considered `local` storage options from the application's perspective, where the [file storage system](/administration-guide/configure/environment-configuration-settings#file-storage-system) is set to `local` in both cases. EFS is essentially AWS's managed NFS, which enables it to serve as a potential alternative to S3 by allowing multiple Mattermost nodes in a high-availability (HA) deployment to share a common file system. In such HA scenarios, the standard local file storage (e.g., an EBS volume attached to a single instance) [is not suitable, as it can't be shared across multiple nodes](/deployment-guide/server/high-availability-cluster-based-deployment#file-storage). EFS is a good alternative in this case, but EFS is not a block storage solution like EBS.
## Supported storage options
### Local
The local file system of the Mattermost server. If running in a cloud environment like AWS, this often utilizes Elastic Block Storage (EBS), which provides block-level storage attached directly to the instances. This setup typically offers high performance with low latency since the storage is local to the server. This option is often the fastest for small files due to low latency.
### EFS
Amazon Elastic File System, a managed file storage solution that supports shared access across multiple instances. EFS supports shared access across multiple instances but adds network overhead, which can impact performance compared to local storage options. EFS is generally slower than local storage but can be beneficial for certain use cases requiring shared access.
### S3
Amazon Simple Storage Service, an object storage solution that provides high durability and scalability. While S3 is great for storing large amounts of data reliably, it introduces higher latency and slower performance due to network-based access and its nature as object storage rather than block or file storage.

View File

@@ -0,0 +1,56 @@
---
title: "Set server connection details"
unlisted: true
---
{/* Snippet include: imported by elasticsearch-setup and opensearch-setup. Kept as
its own page because admin-onboarding-tasks deep-links to its "enterprise
search limitations" anchor. */}
1. (Optional) Enter **Server Username** used to access the enterprise search server.
2. (Optional) Enter **Server Password** associated with the username.
3. Set **Enable Cluster Sniffing** (Optional). Sniffing finds and connects to all data nodes in your cluster automatically.
<Warning>
Do not enable cluster sniffing when using cloud-hosted search providers such as Elastic Cloud or Amazon OpenSearch Service. Cloud providers typically hide search cluster nodes behind a proxy, so sniffed node addresses may be unreachable from your network. The provider handles connection pooling for you, making sniffing unnecessary and potentially disruptive.
</Warning>
4. Optional CA and client certificate configuration settings are available for use with basic authentication credentials or to replace them. See the [Enterprise search configuration settings](/administration-guide/configure/environment-configuration-settings#enterprise-search) documentation for details.
5. Select **Test Connection** and then select **Save**. If the server connection is unsuccessful you won't be able to save the configuration or enable searching with Elasticsearch or AWS OpenSearch.
<Note>
From Mattermost v11, enterprise search server connections are tested during [Support Packet generation](/administration-guide/manage/admin/generating-support-packet). Any connection errors encountered during Support Packet generation are automatically included in the packet to help diagnose configuration issues.
</Note>
# Build the post index of existing messages
Select **Index Now**. This process can take up to a few hours depending on the size of the post database and number of messages. The progress percentage can be seen as the index is created. To avoid downtime, set **Enable Elasticsearch for search queries** to `false` so that database search is available during the indexing process.
# Enable enterprise search
Ensure bulk indexing is complete before enabling enterprise search, otherwise search results will be incomplete.
Set **Enable Elasticsearch for search queries** to `true`, and setting **Enable Elasticsearch for autocomplete** to `true`. Save your configuration updates and restart the Mattermost server.
<Note>
For high post volume deployments, we strongly encourage you to read and properly configure the Mattermost [LiveIndexingBatchSize](/administration-guide/configure/environment-configuration-settings#live-indexing-batch-size) configuration setting.
</Note>
<Warning>
For high post volume deployments, we also strongly recommend *disabling* Database Search once Elasticsearch or AWS OpenSearch is fully configured and running. The Mattermost Server will fall back on Database search if Elasticsearch or OpenSearch are unavailable, which can lead to performance degradation on high post volume deployments. From Mattermost v11.7, the server proactively detects outages through periodic health checks and falls back to database search on the first health check failure, rather than waiting for requests to time out. See the [outage handling FAQ](/deployment-guide/scale/enterprise-search#how-does-mattermost-handle-elasticsearch-or-opensearch-outages) for details.
</Warning>
Once the configuration is saved, new posts made to the database are automatically indexed on the Elasticsearch or AWS OpenSearch server.
## Enterprise search limitations
1. Elasticsearch and AWS OpenSearch use a standard selection of "stop words" to keep search results relevant. Results for the following words will not be returned: "a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", and "with".
2. Searching stop words in quotes returns more results than just the searched terms ([ticket](https://mattermost.atlassian.net/browse/MM-7216)).
3. By default, search results are limited to a user's team and channel membership. This is enforced by the Mattermost server. The entities are indexed in Elasticsearch or AWS OpenSearch in a way that allows Mattermost to filter them when querying, so the Mattermost server narrows down the results on every Elasticsearch or AWS OpenSearch request applying those filters. From Mattermost v11.6, admins can [allow searching public channels without membership](/administration-guide/configure/environment-configuration-settings#allow-searching-public-channels-without-membership) so that users can find messages in public channels they haven't joined, scoped to teams they belong to.
4. User search and autocomplete served by Elasticsearch or AWS OpenSearch match on username, nickname, and first and last name only. Email addresses aren't indexed, so no user can be found by email address, including system admins. User searches served from the database continue to match on email address. For channel and team member searches, system admins always match on email address, and all other users also require [Show email address](/administration-guide/configure/site-configuration-settings#show-email-address) to be enabled. The **System Console > User Management > Users** list always matches on email address, independently of that setting.

View File

@@ -0,0 +1,123 @@
---
title: "Elasticsearch server setup"
---
import Inc0_common_configure_mattermost_for_enterprise_search from './common-configure-mattermost-for-enterprise-search.mdx';
<PlanAvailability slug="ent-plus" />
Elasticsearch allows you to search large volumes of data quickly, in near real-time, by creating and managing an index of post data. The indexing process can be managed from the System Console after setting up and connecting an Elasticsearch server. The post index is stored on the Elasticsearch server and updated constantly after new posts are made. In order to index existing posts, a bulk index of the entire post database must be generated.
Deploying Elasticsearch includes the following two steps: [setting up Elasticsearch](#set-up-elasticsearch), and [configuring Mattermost](#configure-mattermost).
## Set up Elasticsearch
We highly recommend that you set up Elasticsearch server on a dedicated machine separate from the Mattermost Server.
1. Download and install the latest release of [Elasticsearch v9](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html) or [Elasticsearch v8](https://www.elastic.co/guide/en/elasticsearch/reference/8.19/install-elasticsearch.html). See the Elasticsearch documentation for installation details.
2. Set up Elasticsearch with `systemd` by running the following commands:
> ``` sh
> sudo /bin/systemctl daemon-reload
> sudo /bin/systemctl enable elasticsearch.service
> sudo systemctl start elasticsearch.service
> ```
3. Confirm Elasticsearch is working on the server by running the following command:
> ``` sh
> curl localhost:9200
> ```
4. Get your network interface name by running the following command:
> ``` sh
> ip addr
> ```
5. Edit the Elasticsearch configuration file in `vi` by running the following command:
> ``` sh
> vi /etc/elasticsearch/elasticsearch.yml
> ```
6. In this file, replace the `network.host` value of `_eth0_` with your network interface name, and save your changes.
7. Ensure you set `action.destructive_requires_name` to `false` in `elasticsearch.yml` to allow for wildcard operations to work.
8. Restart Elasticsearch by running the following commands:
> ``` sh
> sudo systemctl stop elasticsearch
> sudo systemctl start elasticsearch
> ```
9. Confirm the ports are listenings by running the following command:
> ``` sh
> netstat -plnt
> ```
>
> You should see the following ports, including the ones listening on ports 9200 and 9300. Confirm these are listening on your server's IP address.
10. Create an Elasticsearch directory and give it the proper permissions.
11. Install the [icu-analyzer plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-icu.html) to the `/usr/share/elasticsearch/plugins` directory by running the following command:
> <Important>
>
> The `analysis-icu` plugin is **required on every node in the cluster**, not optional. Mattermost's post and file index templates depend on it. Without the plugin, Mattermost cannot create these templates.
>
> </Important>
>
> ``` sh
> sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-icu
> ```
>
> Restart Elasticsearch on each node to load the newly installed plugin before verifying it; `_cat/plugins` only reports active plugins, so a restart is required first. For production clusters, restart nodes one at a time (rolling restart) rather than all at once. Confirm the plugin is installed and active on every node before continuing. Replace `<your-elasticsearch-host>` and `<password>`, and update the CA path if needed:
>
> ``` sh
> curl --silent --show-error --fail-with-body --cacert /etc/elasticsearch/certs/http_ca.crt --user 'elastic:<password>' 'https://<your-elasticsearch-host>:9200/_cat/plugins?v&h=name,component,version&s=name,component'
> ```
>
> Running this command should show `analysis-icu` once per node in the cluster. If the `analysis-icu` line is missing for any node, the plugin is not installed there. Use plain HTTP without credentials only for a cluster where Elasticsearch security has been explicitly disabled.
>
> **(Optional) CJK language analyzer plugins**: To improve search for Korean, Japanese, or Chinese content, install one or more of the following language-specific analyzer plugins: `analysis-nori` (Korean), `analysis-kuromoji` (Japanese), and `analysis-smartcn` (Chinese).
>
> ``` sh
> sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-nori
> sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji
> sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-smartcn
> ```
>
> After installing the CJK plugins, restart Elasticsearch to load them:
>
> ``` sh
> sudo systemctl restart elasticsearch
> ```
>
> Then enable the [EnableCJKAnalyzers](/administration-guide/configure/environment-configuration-settings#enable-cjk-analyzers) configuration setting. See [Enabling Chinese, Japanese, and Korean Search](/administration-guide/configure/enabling-chinese-japanese-korean-search) for additional CJK search configuration options.
>
> <div class="important">
>
> <div class="title">
>
> Important
>
> </div>
>
> If you enable CJK analyzers on a server with existing indexed content, you must purge and rebuild the search index in **System Console \> Environment \> Elasticsearch** for the CJK analyzers to take effect on existing posts.
>
> </div>
12. Test the connection from Mattermost to Elasticsearch by running the following command:
> ``` sh
> curl 172.31.80.220:9200
> ```
## Configure Mattermost
Follow these steps to configure Mattermost to use your Elasticsearch server and to generate the post index:
1. Go to **System Console \> Environment \> Elasticsearch**.
2. Set **Enable Elasticsearch Indexing** to `true` to enable the other the settings on the page. Once the configuration is saved, new posts made to the database are automatically indexed on the Elasticsearch server.
3. Ensure **Backend type** is set to `elasticsearch`.
<Inc0_common_configure_mattermost_for_enterprise_search />

View File

@@ -0,0 +1,211 @@
---
title: "Enterprise search"
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<PlanAvailability slug="ent-plus" />
Mattermost database search starts to show performance degradation at around 2 million posts, on a server with 32 GB RAM and 4 CPUs. If you anticipate your Mattermost server reaching more than 2.5 million posts, we recommend enabling [Elasticsearch](#elasticsearch) or [AWS OpenSearch Service](#aws-opensearch-service) for optimum search performance **before** reaching 3 million posts. Both tools are highly capable and can handle enterprise-scale workloads. The choice between them depends on the following factors:
- **Licensing and cost**: AWS OpenSearch may be preferable for organizations avoiding proprietary licensing or opting for cost-effective solutions.
- **Feature requirements**: Elasticsearch's proprietary features (e.g., advanced analytics, security suites) may be preferred by organizations needing powerful out-of-the-box functionality.
- **Infrastructure alignment**: AWS OpenSearch aligns well with AWS-centric environments, while Elasticsearch offers broader integrations.
## Elasticsearch
Elasticsearch is a well-established and widely used search engine with a large ecosystem and community support that provides enterprise-scale deployments with optimized search performance, dedicated indexing, and usage resourcing via cluster support for fast, predicable search results.
Mattermost's implementation uses [Elasticsearch](https://www.elastic.co) as a distributed, RESTful search engine supporting highly efficient database searches in a [cluster environment](/deployment-guide/server/high-availability-cluster-based-deployment). Learn more about [setting up and configuring Mattermost for an Elasticsearch server](/deployment-guide/scale/elasticsearch-setup).
## AWS OpenSearch Service
AWS OpenSearch Service is the official path forward from Elasticsearch v7.10.x for AWS customers. It's a fully managed service that makes it easy to deploy, operate, and scale OpenSearch clusters in the AWS Cloud to provide a simple and cost-effective way to search, analyze, and visualize data in real time.
The AWS OpenSearch Service is built on the open-source OpenSearch project, which is a community-driven fork of Elasticsearch. Learn more about [setting up and configuring Mattermost for an OpenSearch server](/deployment-guide/scale/opensearch-setup).
## Supported paths
Review the following support paths for enterprise search based on the version you're using:
<Tabs>
<TabItem value="elasticsearch-v9" label="Elasticsearch v9">
[Elasticsearch v9](https://www.elastic.co/guide/en/elasticsearch/reference/current/elasticsearch-intro.html) is supported from Mattermost v11.7. We recommend upgrading to Elasticsearch v9 for the latest features and security updates. See the [Elasticsearch upgrade](https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-upgrade.html) documentation for upgrade details, and see the [Elasticsearch setup](/deployment-guide/scale/elasticsearch-setup) documentation for details on configuring your Mattermost deployment to use Elasticsearch.
</TabItem>
<TabItem value="elasticsearch-v8" label="Elasticsearch v8">
[Elasticsearch v8](https://www.elastic.co/guide/en/elasticsearch/reference/8.19/elasticsearch-intro.html) is supported from Mattermost v9.11. We recommend upgrading to Elasticsearch v9 for the latest features and security updates. See the [Elasticsearch upgrade](https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-upgrade.html) documentation for upgrade details, and see the [Elasticsearch setup](/deployment-guide/scale/elasticsearch-setup) documentation for details on configuring your Mattermost deployment to use Elasticsearch.
<Note>
Elasticsearch v7.17 is no longer supported as of Mattermost v11.7. If you're still using Elasticsearch v7, you must upgrade to Elasticsearch v8 or v9.
</Note>
</TabItem>
<TabItem value="aws-opensearch-service" label="AWS OpenSearch Service">
AWS OpenSearch Service is the official path forward from Elasticsearch v7.10.x for AWS customers to provide a simple and cost-effective way to search, analyze, and visual data in real time. It's essentially a continuation of Elasticsearch v7.10.x but maintained as open source by AWS. It provides long-term support, active development, and compatibility with AWS clients, libraries, and managed services.
See the **AWS Elasticsearch v7.10.x** tab on this page for details on upgrading to AWS OpenSearch, and see the [AWS OpenSearch setup](/deployment-guide/scale/opensearch-setup) documentation for details on configuring your Mattermost deployment to use AWS OpenSearch.
</TabItem>
<TabItem value="aws-elasticsearch-v7-10-x" label="AWS Elasticsearch v7.10.x">
If you're using Elasticsearch v7.10.x under AWS’s managed services, you can't use newer Elasticsearch clients like the v8 or v9 client without changing backend infrastructure. If you're using AWS Elasticsearch v7.10.x, you must [upgrade to AWS OpenSearch](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/version-migration.html) for future compatibility.
The migration path from Elasticsearch v7.10.x to OpenSearch has been designed to be straightforward, minimizing effort:
1. Disable "compatibility mode" in OpenSearch.
2. Upgrade Mattermost server.
3. Update the Mattermost `ElasticsearchSettings.Backend` configuration setting value from `elasticsearch` to `opensearch` manually or using [mmctl](/administration-guide/manage/mmctl-command-line-tool#mmctl-config-set). This value cannot be changed using the System Console. See the Mattermost search [backend type](/administration-guide/configure/environment-configuration-settings#backend-type) configuration setting documentation for additional details.
4. Restart the Mattermost server.
</TabItem>
</Tabs>
## Frequently asked questions (FAQ)
### Do I need to use Elasticsearch or AWS OpenSearch?
No. Enterprise search engines are designed for large Enterprise deployments to run highly efficient database searches in a cluster environment. The default Mattermost database search starts to show performance degradation at around 2.5 million posts, depending on the specifications for the database server. If you expect your Mattermost server to have more than 2.5 million posts, we recommend using Elasticsearch or AWS OpenSearch for optimum search performance.
### Should I install Elasticsearch or OpenSearch on the same machine as Mattermost Server?
No. We strongly recommend that you install Elasticsearch or AWS OpenSearch on a dedicated machine that's separate from the Mattermost server.
### What types of indexes are created?
Mattermost creates three types of indexes: users, channels, and posts. Users and channels have one index each. Posts are aggregated by date, into multiple indexes.
### Can I pause an search indexing job?
Yes. From Mattermost v6.7, the search indexing job is resumable. Stopping a server while the search indexing job is running puts the job in pending status. The job resumes when the server restarts. System admins can cancel an indexing job through the System Console.
### Can an index rollover policy be defined?
The [AggregatePostsAfterDays](/administration-guide/configure/environment-configuration-settings#aggregate-search-indexes) configuration setting defines a cutoff value. All posts preceding this value are reindexed and aggregated into new and bigger indexes. The default setting is 365 days.
### Are there any new search features offered with Elasticsearch?
The current implementation of Elasticsearch matches the search features currently available with database search. The Mattermost team is working on extending the Elasticsearch feature set with file name and content search, date filters, and operators and modifiers.
### Are my files stored in Elasticsearch or OpenSearch?
No, files and attachments are not stored.
### How do I monitor system health of an Elasticsearch server?
You can use this Prometheus exporter to monitor [various metrics](https://github.com/justwatchcom/elasticsearch_exporter#metrics) about Elasticsearch: [justwatchcom/elasticsearch_exporter](https://github.com/justwatchcom/elasticsearch_exporter).
You can also refer to this [article about Elasticsearch performance monitoring](https://www.datadoghq.com/blog/monitor-elasticsearch-performance-metrics/#key-elasticsearch-performance-metrics-to-monitor). It's not written specifically for Prometheus, which [Mattermost's performance monitoring](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring) system uses, but has several tips and best practices.
### What form of data is sent to Elasticsearch or OpenSearch?
Mattermost communicates with Elasticsearch or OpenSearch through its REST API using JSON messages for indexing and querying entities.
### How much data is sent to Elasticsearch or OpenSearch and when?
Every time a message is published, a channel is created, or a user changes, (either because their properties change e.g.: change of the first name or because they join/leave a channel), the data associated with that event is sent to Elasticsearch or OpenSearch.
If search via Elasticsearch or OpenSearch is enabled, every search will generate a query. If autocompletion is enabled, every user or channel autocompletion associated with writing a message or user search will generate a query.
### How do I know if a search job fails?
Mattermost provides the status of each Elasticsearch or OpenSearch indexing job in **System Console \> Environment \> Elasticsearch**. Here you can see if the job succeeded or failed, including the details of the error.
Failures are returned in the server logs. The error log begins with the string `Failed job` and includes a job_id key/value pair. Search job failures are identified with worker name `EnterpriseElasticsearchAggregator` and `EnterpriseElasticsearchIndexer`. You can optionally create a script that programmatically queries for such failures and notifies the appropriate system.
### How do I diagnose enterprise search connection issues?
From Mattermost v11, [Support Packet generation](/administration-guide/manage/admin/generating-support-packet) automatically tests the connection to your configured Elasticsearch or AWS OpenSearch server and includes any connection errors in the Support Packet. This provides valuable diagnostic information including server version, installed plugins, and specific error details if the connection fails.
The enterprise search connection test results appear in the Support Packet and can help identify configuration issues such as network connectivity problems, authentication failures, or server availability issues. If connection errors are present, they will be clearly documented with specific error messages to aid in troubleshooting.
### How does Mattermost handle Elasticsearch or OpenSearch outages?
From Mattermost v11.7, the server includes an automatic health monitor for Elasticsearch and OpenSearch connections. The health monitor runs periodic health checks and automatically manages the connection lifecycle:
- **Health checks**: The server checks the health of the search engine cluster every 60 seconds. After 3 consecutive health check failures, the engine is stopped and search falls back to the database.
- **Fast-fail on first failure**: On the very first health check failure, the engine is immediately marked as unhealthy and search requests are routed to the database. This happens before the consecutive failure threshold is reached, so users experience minimal disruption.
- **Automatic retry**: When the search engine is unavailable, the server retries connecting with exponential backoff, starting at 15 seconds and doubling up to a maximum of 5 minutes between attempts.
- **Automatic recovery**: When the search engine becomes available again, the server automatically reconnects and resumes using it for search queries. No manual intervention or server restart is required.
- **Configuration changes**: Changes to Elasticsearch or OpenSearch configuration settings, or license changes, immediately trigger the health monitor to re-evaluate the connection state.
- **Monitoring**: A `mattermost_search_engine_status` Prometheus metric reports the health of the search engine (`1` = healthy or not configured, `0` = configured but unavailable). Use this metric to [set up alerts](/administration-guide/scale/performance-alerting) for search engine outages. See [performance monitoring metrics](/administration-guide/scale/performance-monitoring-metrics) for details.
During an outage, you may see the following log messages:
| Level | Log message | Meaning |
|---|---|---|
| Error | `Search engine health check failed repeatedly; stopping engine` | The failure threshold was reached and the engine has been stopped. Search falls back to the database. |
| Warn | `Search engine health check failed` | An individual health check failed. Includes a `consecutive_failures` count. |
| Warn | `Search engine health check failed: it is now marked as unhealthy` | A previously healthy engine failed a health check and has been marked unhealthy. Search requests will fall back to the database immediately. |
| Error | `Search engine watcher: Start() failed, will retry` | A reconnection attempt failed. Includes a `next_backoff` field indicating the time until the next retry. |
| Info | `Search engine health check succeeded: it is now marked as healthy` | The engine passed a health check after being unhealthy and is now handling search requests again. |
| Info | `Search engine watcher: engine started successfully` | The engine has recovered and is active again. |
| Info | `Search engine watcher: engine disabled, parking` | The health monitor is idle because the search engine is disabled in configuration. |
### My search indexes won't complete, what should I do?
If you have an search indexing job that's paused, it's likely your Elasticsearch or OpenSearch server has restarted. If you restart that server, you must also restart Mattermost to ensure jobs are completed. If restarting the Mattermost server does not resolve the issue, [customers with a Mattermost subscription can contact Mattermost Support](https://mattermost.com/support/) for assistance.
### Do I need to purge first then bulk index each time?
Yes. Every time you choose to remove old data (purge), you must follow it up with a bulk index operation to repopulate them with new data. When you purge (delete) indices, you are removing the existing data from Elasticsearch. After purging, if you want to repopulate the indices with fresh data, you perform a bulk index operation to rebuild the indices efficiently. The bulk API allows for indexing, deleting, or updating multiple documents in a single request, which is faster and more efficient than processing documents one by one.
## Required Permissions For Mattermost Service Account
In "least privilege" environments you may need to further constrain the service account permissions to limit the access your Elasticsearch or AWS OpenSearch service account has.
The following JSON provides an example of a "least privilege" permission set that allows Mattermost to operate correctly with Elasticsearch or AWS OpenSearch:
> ``` json
> &#123;
> "cluster_permissions": [
> "cluster:monitor/*",
> "indices:admin/template/put",
> "indices:data/write/bulk"
> ],
> "index_permissions": [
> &#123;
> "index_patterns": [
> "\<IndexPrefix\>*"
> ],
> "allowed_actions": [
> "indices:admin/get",
> "indices:admin/create",
> "indices:admin/delete",
> "indices:admin/mapping/put",
> "indices:admin/mappings/fields/get*",
> "indices:data/read*",
> "indices:data/write*"
> ]
> &#125;
> ]
> &#125;
> ```
A simpler, more flexible, and resilient variant of the above would be:
``` json
{
"cluster_permissions": [
"cluster:monitor/*",
"indices:admin/template/put",
"indices:data/write/bulk"
],
"index_permissions": [
{
"index_patterns": [
"\<IndexPrefix\>*"
],
"allowed_actions": [
"indices:*"
]
}
]
}
```

View File

@@ -0,0 +1,17 @@
---
title: Estimated storage per user, per month
unlisted: true
---
File usage per user varies significantly across industries. The below benchmarks are recommended:
- **Low usage teams** (1-5 MB/user/month)
> - Primarily using text messages and links to communicate. Examples would include software development teams that heavily use web-based document creation and management tools, and therefore rarely upload files to the server.
- **Medium usage teams** (5-25 MB/user/month)
> - Using a mix of text messages as well as shared documents and images to communicate. Examples might include business teams that may commonly drag and drop screenshots, PDFs and Microsoft Office documents into Mattermost for sharing and review.
- **High usage teams** (25-100 MB/user/month)
> - Heaviest utilization comes from teams uploading a high number of large files into Mattermost on a regular basis. Examples include creative teams who share and store artwork and media with tags and commentary in a pipeline production process.

View File

@@ -0,0 +1,9 @@
---
title: Lifetime storage
unlisted: true
---
To forecast your own storage usage, begin with a Mattermost server approximately 600 MB to 800 MB in size including operating system and database, then add the multiplied product of:
- Estimated storage per user per month (see below), multiplied by 12 months in a year
- Estimated mean average number of users in a year
- A 1-2x safety factor

View File

@@ -0,0 +1,341 @@
---
title: "AWS OpenSearch server setup"
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Inc0_common_configure_mattermost_for_enterprise_search from './common-configure-mattermost-for-enterprise-search.mdx';
<PlanAvailability slug="ent-plus" />
AWS OpenSearch Service allows you to search large volumes of data quickly, in near real-time, by creating and managing an index of post data. The indexing process can be managed from the System Console after setting up and connecting an OpenSearch server. The post index is stored on the OpenSearch server and updated constantly after new posts are made. In order to index existing posts, a bulk index of the entire post database must be generated.
Deploying AWS OpenSearch includes the following two steps: [setting up AWS OpenSearch](#set-up-aws-opensearch), and [configuring Mattermost](#configure-mattermost).
## Set up AWS OpenSearch
From Mattermost v9.11, beta support is available for [AWS OpenSearch v1.x and v2.x](https://opensearch.org/). This document covers both on‑premises and AWS OpenSearch setup, including manual steps and Terraform examples.
We highly recommend that you set up an AWS OpenSearch server on a separate machine from the Mattermost server.
<Important>
Starting in Mattermost v12.0 (October 2026), OpenSearch v1.x is no longer supported. Upgrading to OpenSearch v2.x or later is required.
</Important>
<Tabs>
<TabItem value="on-premises-opensearch" label="On-Premises OpenSearch">
1. To install on-premise OpenSearch, provision a dedicated server (e.g. Ubuntu 22.04 LTS).
2. Install Java (OpenSearch requires Java 11+):
``` sh
sudo apt update
sudo apt install -y openjdk-11-jdk
java -version
```
3. Download & extract OpenSearch 2.x:
``` sh
wget https://artifacts.opensearch.org/releases/bundle/opensearch/2.9.0/opensearch-2.9.0-linux-x64.tar.gz
tar -xzf opensearch-2.9.0-linux-x64.tar.gz
sudo mv opensearch-2.9.0 /usr/share/opensearch
```
4. Create a dedicated user & set permissions:
``` sh
sudo useradd --no-create-home --shell /bin/false opensearch
sudo chown -R opensearch:opensearch /usr/share/opensearch
```
5. Configure systemd:
``` sh
[Unit]
Description=OpenSearch
Wants=network-online.target
After=network-online.target
[Service]
Type=notify
User=opensearch
Group=opensearch
ExecStart=/usr/share/opensearch/bin/opensearch
Restart=on-failure
LimitNOFILE=65536
LimitNPROC=4096
[Install]
WantedBy=multi-user.target
```
6. Edit `opensearch.yml` to include the following:
``` yaml
cluster.name: mattermost-cluster
node.name: node-1
path.data: /var/lib/opensearch
path.logs: /var/log/opensearch
network.host: 0.0.0.0
discovery.seed_hosts: ["<other-node-ip>"]
cluster.initial_master_nodes: ["node-1", "node-2"]
```
<Note>
Ensure `path.data` and `path.logs` directories exist and are owned by the `opensearch` user before starting the service:
``` sh
sudo mkdir -p /var/lib/opensearch /var/log/opensearch
sudo chown -R opensearch:opensearch /var/lib/opensearch /var/log/opensearch
```
</Note>
7. Enable & start OpenSearch:
``` sh
sudo systemctl daemon-reload
sudo systemctl enable opensearch
sudo systemctl start opensearch
sudo systemctl status opensearch
```
8. Install the [icu-analyzer plugin](https://docs.opensearch.org/latest/install-and-configure/additional-plugins/index/) to the `/usr/share/opensearch/plugins` directory by running the following command:
<Important>
The `analysis-icu` plugin is **required on every node in the cluster**, not optional. Mattermost's post and file index templates depend on it. Without the plugin, Mattermost cannot create these templates.
</Important>
``` sh
sudo /usr/share/opensearch/bin/opensearch-plugin install analysis-icu
```
Restart OpenSearch on each node to load the newly installed plugin before verifying it; `_cat/plugins` only reports active plugins, so a restart is required first. For production clusters, restart nodes one at a time (rolling restart) rather than all at once. Confirm the plugin is installed and active on every node before continuing. Replace the host, admin password, and path to your cluster's CA certificate:
``` sh
curl --silent --show-error --fail-with-body --cacert <path-to-root-ca.pem> --user 'admin:<password>' 'https://<your-opensearch-host>:9200/_cat/plugins?v&h=name,component,version&s=name,component'
```
Running this command should show `analysis-icu` once per node in the cluster. If the `analysis-icu` line is missing for any node, the plugin is not installed there.
**(Optional) CJK language analyzer plugins**: To improve search for Korean, Japanese, or Chinese content, install one or more of the following language-specific analyzer plugins: `analysis-nori` (Korean), `analysis-kuromoji` (Japanese), and `analysis-smartcn` (Chinese).
``` sh
sudo /usr/share/opensearch/bin/opensearch-plugin install analysis-nori
sudo /usr/share/opensearch/bin/opensearch-plugin install analysis-kuromoji
sudo /usr/share/opensearch/bin/opensearch-plugin install analysis-smartcn
```
After installing the CJK plugins, restart OpenSearch to load them:
``` sh
sudo systemctl restart opensearch
```
Then enable the [EnableCJKAnalyzers](/administration-guide/configure/environment-configuration-settings#enable-cjk-analyzers) configuration setting. See [Enabling Chinese, Japanese, and Korean Search](/administration-guide/configure/enabling-chinese-japanese-korean-search) for additional CJK search configuration options.
<Important>
If you enable CJK analyzers on a server with existing indexed content, you must purge and rebuild the search index in **System Console \> Environment \> Elasticsearch** for the CJK analyzers to take effect on existing posts.
</Important>
## Terraform (Docker) Example
``` sh
provider "docker" {
host = "unix:///var/run/docker.sock"
}
resource "docker_image" "opensearch" {
name = "opensearchproject/opensearch:2.9.0"
}
resource "docker_container" "opensearch" {
name = "opensearch"
image = docker_image.opensearch.latest
ports {
internal = 9200
external = 9200
}
ports {
internal = 9600
external = 9600
}
env = [
"cluster.name=mattermost-cluster",
"network.host=0.0.0.0",
"discovery.type=single-node", # remove for multi-node
]
restart = "unless-stopped"
}
resource "null_resource" "install_icu_plugin" {
depends_on = [docker_container.opensearch]
provisioner "local-exec" {
command = "docker exec opensearch /usr/share/opensearch/bin/opensearch-plugin install analysis-icu && docker restart opensearch"
}
}
```
</TabItem>
<TabItem value="aws-opensearch-console-setup" label="AWS OpenSearch Console Setup">
1. To install AWS OpenSearch, open the **AWS Console \> OpenSearch Service**.
2. Create a domain, where:
- Domain name: `mattermost-os`
- Engine version: `OpenSearch 2.x`.
3. Configure the cluster, where:
- instance type: `r6g.xlarge.search`
- data nodes: 2
- master nodes: 2
- storage: EBS gp3 (1536 GiB, 4608 IOPS, 250 MiB/s)
4. Specify the network for: VPC with 2 subnets, and a security group allowing Mattermost IPs on port `443`.
<Note>
Port 9200 is commonly used for local or on-premise OpenSearch. The AWS OpenSearch domain only supports HTTPS over port 443.
</Note>
5. Configure the access policy (JSON). Mattermost doesn't sign OpenSearch requests with AWS SigV4, so restrict access at the network layer with the VPC and security group from step 4, and use an open principal in the domain access policy:
``` sh
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "AWS": "*" },
"Action": "es:ESHttp*",
"Resource": "arn:aws:es:us-east-1:123456789012:domain/mattermost-os/*" }]
}
```
<Warning>
IAM principal-based access policies (for example, `"Principal": { "AWS": "arn:aws:iam::<account-id>:role/<role-name>" }`) are not supported. Mattermost's OpenSearch client doesn't sign requests with AWS SigV4, so AWS treats the requests as anonymous and an IAM-restricted policy will reject them with `User: anonymous is not authorized to perform: es:ESHttpGet`. If you need authentication enforced at the OpenSearch layer rather than the network layer, enable [fine-grained access control](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html) on the domain with an internal master user, and enter those credentials as the **Server Username** and **Server Password** in the Mattermost Elasticsearch configuration.
</Warning>
6. Configure the following advanced settings (JSON):
``` sh
{
"action.destructive_requires_name": "false",
"rest.action.multi.allow_explicit_index": "true",
"indices.query.bool.max_clause_count": "1024",
"indices.fielddata.cache.size": "20"
}
```
7. Configure the automated snapshot start hour as 23 (UTC), enforce HTTPS, then review & create.
8. To test, run the following command:
``` sh
curl https://mattermost-os-xxxxxxxxxxx.us-east-1.es.amazonaws.com
```
## AWS Terraform Example
``` sh
provider "aws" {
region = "us-east-1"
}
resource "aws_iam_role" "os_service_role" {
name = "OSServiceRole"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": { "Service": "es.amazonaws.com" }
}]
}
EOF
}
resource "aws_opensearch_domain" "mattermost" {
domain_name = "mattermost-os"
engine_version = "OpenSearch_2.9"
cluster_config {
instance_type = "r6g.xlarge.search"
instance_count = 2
dedicated_master_enabled = true
dedicated_master_type = "r6g.xlarge.search"
dedicated_master_count = 2
zone_awareness_enabled = true
}
ebs_options {
ebs_enabled = true
volume_type = "gp3"
volume_size = 1536
iops = 4608
}
vpc_options {
subnet_ids = ["subnet-blah1", "subnet-blah2"]
security_group_ids = ["sg-1234567890"]
}
advanced_options = {
"rest.action.multi.allow_explicit_index" = "true"
"indices.query.bool.max_clause_count" = "1024"
"indices.fielddata.cache.size" = "20"
"action.destructive_requires_name" = "false"
}
access_policies = <<POLICY
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:ESHttp*",
"Resource": "arn:aws:es:us-east-1:123456789012:domain/mattermost-os/*"
}]
}
POLICY
service_software_options {
automated_snapshot_start_hour = 23
}
domain_endpoint_options {
enforce_https = true
}
}
```
</TabItem>
</Tabs>
## Configure Mattermost
Follow these steps to configure Mattermost to use your AWS OpenSearch server and to generate the post index:
1. Go to **System Console \> Environment \> Elasticsearch**.
2. Set **Enable Elasticsearch Indexing** to `true` to enable the other the settings on the page.
3. Ensure **Backend type** is set to `opensearch`.
4. Set the **Server Connection Address** to your Elasticsearch or OpenSearch cluster endpoint.
5. Monitor cluster health: `curl https://mattermost-os-xxxxx.us-east-1.es.amazonaws.com/_cluster/health`
<Inc0_common_configure_mattermost_for_enterprise_search />

View File

@@ -0,0 +1,99 @@
---
title: "Redis"
---
<PlanAvailability slug="ent-adv" />
Redis is an open-source, in-memory data structure store used as a database, cache, message broker, and streaming engine. Mattermost uses Redis as an external cache to improve performance at scale. When properly configured, Redis can help support Mattermost installations with more than 100,000 users by providing improved performance through efficient caching.
## Deployment guide
Deploying Redis with Mattermost includes the following 2 steps: [setting up the Redis server](#set-up-a-redis-server), and [configuring Redis in Mattermost](#configure-redis-in-mattermost).
### Set up a Redis server
1. Download and install the latest release of [Redis 7.x](https://redis.io/download/). See the Redis documentation for installation details specific to your operating system.
2. Configure Redis appropriately for your environment. Ensure that Redis is secured and accessible only by trusted systems.
3. For high availability deployments, consider setting up Redis in a cluster configuration for improved reliability and performance.
### Configure Redis in Mattermost
Follow these steps to configure Mattermost to use your Redis server:
1. Go to **System Console \> Environment \> Cache**.
2. Set **Cache Type** to `redis` to enable the Redis-specific settings.
3. Set the Redis server connection details:
> 1. Enter **Redis Address** for the Redis server you set up earlier (e.g., `redis.example.com:6379`).
> 2. (Optional) Enter **Redis Password** if your Redis server requires authentication.
> 3. (Optional) Enter **Redis Database** to specify which Redis database to use (-1 by default, which uses Redis's default database).
4. Save your configuration and restart the Mattermost server.
Alternatively, you can configure Redis in the `config.json` file:
``` json
"CacheSettings": {
"CacheType": "redis",
"RedisAddress": "redis.example.com:6379",
"RedisPassword": "",
"RedisCachePrefix": "",
"RedisDB": -1,
"DisableClientCache": false
}
```
## Deploy with AWS ElastiCache
For enterprise-scale deployments, AWS ElastiCache for Redis provides a fully managed Redis service that simplifies deployment, operation, and scaling.
When deploying Mattermost with AWS ElastiCache:
1. Create an ElastiCache for Redis instance, choosing Redis OSS version 7.1 or later.
2. Based on load testing results, we recommend starting with a `cache.m7g.2xlarge` instance for deployments supporting over 100,000 users.
3. Configure your Mattermost server to connect to the ElastiCache endpoint.
4. Monitor CPU utilization closely, as Redis is single-threaded and performance bottlenecks are typically CPU-bound rather than memory-bound.
### Performance considerations
When using Redis with Mattermost, consider the following performance insights:
- Current load tests indicate that memory usage of Redis is relatively low, with CPU being the primary bottleneck because Redis is single-threaded.
- When planning your Redis deployment, use CPU utilization as the primary metric for scaling decisions.
## Implementation details
Mattermost uses the [rueidis](https://github.com/redis/rueidis) library instead of the more popular [go-redis](https://github.com/redis/go-redis), primarily because rueidis offers more performance optimizations out of the box, including:
- Automatic pipelining of concurrent queries
- Client-side caching
- Additional performance tuning options like MaxFlushDelay
The primary implementation files include:
- `platform/services/cache/provider.go` - Contains the library initialization code
- `platform/services/cache/redis.go` - Contains the cache interface implementation
## Frequently asked questions (FAQ)
### Do I need to use Redis?
While Redis is not required for smaller Mattermost deployments, it is highly recommended for large-scale installations. - If your installation has more than 100K users, Redis is highly recommended. Redis significantly improves performance by reducing database load and optimizing common operations. - If your installation has less than 100K users, Redis is not recommended.
It is suggested to keep an eye on the `sum(rate(mattermost_cache_mem_invalidation_total[5m]))` metric which indicates the rate of cache invalidations happening. A single cache invalidation will send a message across your HA cluster to all nodes, leading to database calls from all of them. So the metric, combined with the number of nodes in your cluster should be used to determine when is the right time to use Redis.
For example, if you have more than 10 nodes in your cluster, and the rate of invalidations goes beyond 10, then you should definitely start considering adding Redis.
### Should I install Redis on the same machine as Mattermost Server?
For production deployments, we recommend running Redis on a separate machine from the Mattermost server. This separation allows for better resource allocation and improved system reliability.
### What Redis metrics should I monitor?
When running Redis with Mattermost, monitor the following metrics:
- CPU utilization (primary bottleneck)
- Memory usage
- Connected clients
- Cache hit ratio
- Operation latency
- Mattermost's `mattermost_db_cache_time` Grafana metric with labels of `cache_name` and `operation`, which can be used to further monitor the performance of Redis

View File

@@ -0,0 +1,127 @@
---
title: "Scale Mattermost up to 100,000 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
import Inc2_additional_ha_considerations from './additional-ha-considerations.mdx';
<PlanAvailability slug="ent-plus" />
This page describes the Mattermost reference architecture designed for the load of up to 100,000 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Required
- **Database Configuration**: writer, multiple readers
<Note>
\- Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are. - From Mattermost v10.4, Mattermost Enterprise customers can configure [Redis](https://redis.io/) (Remote Dictionary Server) as an alternative cache backend. Using Redis can help ensure that Mattermost remains performant and efficient, even under heavy usage. See the [Redis cache backend](/administration-guide/configure/environment-configuration-settings#redis-cache-backend) configuration settings documentation for details. - While the following Elasticsearch specifications may be more than sufficient for some use cases, we have not extensively tested configurations with lower resource allocations for this user scale. If cost optimization is a priority, admins may choose to experiment with smaller configurations, but we recommend starting with the tested specifications to ensure system stability and performance. Keep in mind that under-provisioning can lead to degraded user experience and additional troubleshooting effort.
</Note>
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th, .scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
text-align: left;
vertical-align: top;
word-wrap: break-word;
overflow-wrap: break-word;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
&#125;
.scale-requirements-table col:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table col:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table col:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table col:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table col:nth-child(5) &#123; width: 24%; &#125;
</style>
<table class="scale-requirements-table">
<colgroup>
<col style={{width: '25%'}} />
<col style={{width: '10%'}} />
<col style={{width: '18%'}} />
<col style={{width: '23%'}} />
<col style={{width: '24%'}} />
</colgroup>
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>6</td>
<td>16/32</td>
<td>c7i.4xlarge</td>
<td>F16s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>16/128</td>
<td>db.r7g.4xlarge</td>
<td>E16ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>5</td>
<td>16/128</td>
<td>db.r7g.4xlarge</td>
<td>E16ds v5</td>
</tr>
<tr>
<td>Elasticsearch cluster</td>
<td>4</td>
<td>8/64</td>
<td>r6g.2xlarge.search</td>
<td>E8ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>1</td>
<td>16/64</td>
<td>m7i.4xlarge</td>
<td>D16s v6</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 100000-person team with medium usage (with a safety factor of 2x) would require between 10.56TB <sup>1</sup> and 52.8TB <sup>2</sup> of free space per annum.
<sup>1</sup> 100000 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 100000 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
<Inc2_additional_ha_considerations />

View File

@@ -0,0 +1,146 @@
---
title: "Scale Mattermost up to 15,000 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
import Inc2_additional_ha_considerations from './additional-ha-considerations.mdx';
<PlanAvailability slug="ent-plus" />
This page describes the Mattermost reference architecture designed for the load of up to 15,000 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Required
- **Database Configuration**: writer, reader
<Note>
Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are.
</Note>
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th,
.scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
vertical-align: top;
word-wrap: break-word !important;
overflow-wrap: break-word !important;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
text-align: left;
&#125;
.scale-requirements-table th:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table th:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table th:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table th:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table th:nth-child(5) &#123; width: 24%; &#125;
/* Dark mode support */
body:not([data-custom-theme="light"]) .scale-requirements-table &#123;
background-color: #2d3748;
&#125;
body:not([data-custom-theme="light"]) .scale-requirements-table th &#123;
background-color: #4a5568 !important;
color: #fff;
border-color: #718096 !important;
&#125;
body:not([data-custom-theme="light"]) .scale-requirements-table td &#123;
color: #e2e8f0;
border-color: #718096 !important;
&#125;
/* Mobile responsiveness */
@media (max-width: 768px) &#123;
.scale-requirements-table &#123;
font-size: 0.8em;
&#125;
.scale-requirements-table th,
.scale-requirements-table td &#123;
padding: 6px 4px;
&#125;
&#125;
</style>
<table class="scale-requirements-table">
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/ Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>2</td>
<td>4/8</td>
<td>c7i.xlarge</td>
<td>F4s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>4/32</td>
<td>db.r7g.xlarge</td>
<td>E4ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>1</td>
<td>4/32</td>
<td>db.r7g.xlarge</td>
<td>E4ds v5</td>
</tr>
<tr>
<td>Elasticsearch Node</td>
<td>2</td>
<td>4/32</td>
<td>r6g.xlarge.search</td>
<td>E4ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>1</td>
<td>16/64</td>
<td>m7i.4xlarge</td>
<td>D16s v6</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 15000-person team with medium usage (with a safety factor of 2x) would require between 1.8TB <sup>1</sup> and 9TB <sup>2</sup> of free space per annum.
<sup>1</sup> 15000 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 15000 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
<Inc2_additional_ha_considerations />

View File

@@ -0,0 +1,143 @@
---
title: "Scale Mattermost up to 200 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
This page describes the Mattermost reference architecture designed for the load of up to 200 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Not required
- **Database Configuration**: Single
<Note>
Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are.
</Note>
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th,
.scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
vertical-align: top;
word-wrap: break-word !important;
overflow-wrap: break-word !important;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
text-align: left;
&#125;
.scale-requirements-table th:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table th:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table th:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table th:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table th:nth-child(5) &#123; width: 24%; &#125;
/* Dark mode support */
body:not([data-custom-theme="light"]) .scale-requirements-table &#123;
background-color: #2d3748;
&#125;
body:not([data-custom-theme="light"]) .scale-requirements-table th &#123;
background-color: #4a5568 !important;
color: #fff;
border-color: #718096 !important;
&#125;
body:not([data-custom-theme="light"]) .scale-requirements-table td &#123;
color: #e2e8f0;
border-color: #718096 !important;
&#125;
/* Mobile responsiveness */
@media (max-width: 768px) &#123;
.scale-requirements-table &#123;
font-size: 0.8em;
&#125;
.scale-requirements-table th,
.scale-requirements-table td &#123;
padding: 6px 4px;
&#125;
&#125;
</style>
<table class="scale-requirements-table">
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/ Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>1</td>
<td>2/4</td>
<td>c7i.large</td>
<td>F2s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>2/16</td>
<td>db.r7g.large</td>
<td>E2ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>0</td>
<td>2/16</td>
<td>db.r7g.large</td>
<td>E2ds v5</td>
</tr>
<tr>
<td>Elasticsearch Node</td>
<td>0</td>
<td>4/32</td>
<td>r6g.xlarge.search</td>
<td>E4ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>1</td>
<td>16/64</td>
<td>m7i.4xlarge</td>
<td>D16s v6</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 200-person team with medium usage (with a safety factor of 2x) would require between 12GB <sup>1</sup> and 60GB <sup>2</sup> of free space per annum.
<sup>1</sup> 200 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 200 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
Smaller deployments will need an increase in resources due to the fact the database is hosted on the same server as the Mattermost application.

View File

@@ -0,0 +1,146 @@
---
title: "Scale Mattermost up to 2,000 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
import Inc2_additional_ha_considerations from './additional-ha-considerations.mdx';
<PlanAvailability slug="ent-plus" />
This page describes the Mattermost reference architecture designed for a minimum load of 100 concurrent users and up to 2,000 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Required
- **Database Configuration**: writer, reader
<Note>
Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are.
</Note>
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th,
.scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
vertical-align: top;
word-wrap: break-word !important;
overflow-wrap: break-word !important;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
text-align: left;
&#125;
.scale-requirements-table th:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table th:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table th:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table th:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table th:nth-child(5) &#123; width: 24%; &#125;
/* Dark mode support */
body:not([data-custom-theme="light"]) .scale-requirements-table &#123;
background-color: #2d3748;
&#125;
body:not([data-custom-theme="light"]) .scale-requirements-table th &#123;
background-color: #4a5568 !important;
color: #fff;
border-color: #718096 !important;
&#125;
body:not([data-custom-theme="light"]) .scale-requirements-table td &#123;
color: #e2e8f0;
border-color: #718096 !important;
&#125;
/* Mobile responsiveness */
@media (max-width: 768px) &#123;
.scale-requirements-table &#123;
font-size: 0.8em;
&#125;
.scale-requirements-table th,
.scale-requirements-table td &#123;
padding: 6px 4px;
&#125;
&#125;
</style>
<table class="scale-requirements-table">
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/ Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>2</td>
<td>2/4</td>
<td>c7i.large</td>
<td>F2s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>2/16</td>
<td>db.r7g.large</td>
<td>E2ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>1</td>
<td>2/16</td>
<td>db.r7g.large</td>
<td>E2ds v5</td>
</tr>
<tr>
<td>Elasticsearch Node</td>
<td>2</td>
<td>4/32</td>
<td>r6g.xlarge.search</td>
<td>E4ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>1</td>
<td>16/64</td>
<td>m7i.4xlarge</td>
<td>D16s v6</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 2000-person team with medium usage (with a safety factor of 2x) would require between 120GB <sup>1</sup> and 600GB <sup>2</sup> of free space per annum.
<sup>1</sup> 2000 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 2000 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
<Inc2_additional_ha_considerations />

View File

@@ -0,0 +1,142 @@
---
title: "Scale Mattermost up to 200,000 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
import Inc2_additional_ha_considerations from './additional-ha-considerations.mdx';
<PlanAvailability slug="ent-adv" />
This page describes the Mattermost reference architecture designed for the load of up to 200,000 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Required
- **Database Configuration**: writer, multiple readers
<Note>
\- Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are. - From Mattermost v10.4, Mattermost Enterprise customers can configure [Redis](https://redis.io/) (Remote Dictionary Server) as an alternative cache backend. Using Redis can help ensure that Mattermost remains performant and efficient, even under heavy usage. See the [Redis cache backend](/administration-guide/configure/environment-configuration-settings#redis-cache-backend) configuration settings documentation for details. - While the following Elasticsearch specifications may be more than sufficient for some use cases, we have not extensively tested configurations with lower resource allocations for this user scale. If cost optimization is a priority, admins may choose to experiment with smaller configurations, but we recommend starting with the tested specifications to ensure system stability and performance. Keep in mind that under-provisioning can lead to degraded user experience and additional troubleshooting effort.
</Note>
## User login scalability
Tests across all architectures were conducted at a rate of 4 user logins per second (14,400 users per hour). For this architecture, we performed additional testing at higher rates, reaching up to 30 user logins per second.
Results show that this architecture supports logging in up to 150,000 users within 1.5 hours at the higher rate. Beyond this 150,000-user mark, the only available data is at the base rate of 4 logins per second, and no conclusive performance data exists at larger rates.
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th, .scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
text-align: left;
vertical-align: top;
word-wrap: break-word;
overflow-wrap: break-word;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
&#125;
.scale-requirements-table col:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table col:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table col:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table col:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table col:nth-child(5) &#123; width: 24%; &#125;
</style>
<table class="scale-requirements-table">
<colgroup>
<col style={{width: '25%'}} />
<col style={{width: '10%'}} />
<col style={{width: '18%'}} />
<col style={{width: '23%'}} />
<col style={{width: '24%'}} />
</colgroup>
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>14</td>
<td>16/32</td>
<td>c7i.4xlarge</td>
<td>F16s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>16/128</td>
<td>db.r7g.4xlarge</td>
<td>E16ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>6</td>
<td>16/128</td>
<td>db.r7g.4xlarge</td>
<td>E16ds v5</td>
</tr>
<tr>
<td>Elasticsearch cluster</td>
<td>4</td>
<td>8/64</td>
<td>r6g.2xlarge.search</td>
<td>E8ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>4</td>
<td>32/128</td>
<td>m6in.8xlarge</td>
<td>D32s v6</td>
</tr>
<tr>
<td>Redis</td>
<td>1</td>
<td>8/32</td>
<td>cache.m7g.2xlarge</td>
<td>Azure Cache Redis P3</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 200000-person team with medium usage (with a safety factor of 2x) would require between 21.12TB <sup>1</sup> and 105.6TB <sup>2</sup> of free space per annum.
<sup>1</sup> 200000 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 200000 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
<Inc2_additional_ha_considerations />
[Book a live demo](https://mattermost.com/request-demo/) or [talk to a Mattermost expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization's secure collaboration needs. Or try Mattermost yourself with a [1-hour preview](https://mattermost.com/sign-up/) for instant access to a live sandbox environment.

View File

@@ -0,0 +1,128 @@
---
title: "Scale Mattermost up to 30,000 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
import Inc2_additional_ha_considerations from './additional-ha-considerations.mdx';
<PlanAvailability slug="ent-plus" />
This page describes the Mattermost reference architecture designed for the load of up to 30,000 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Required
- **Database Configuration**: writer, multiple readers
<Note>
- Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are.
- While the following Elasticsearch specifications may be more than sufficient for some use cases, we have not extensively tested configurations with lower resource allocations for this user scale. If cost optimization is a priority, admins may choose to experiment with smaller configurations, but we recommend starting with the tested specifications to ensure system stability and performance. Keep in mind that under-provisioning can lead to degraded user experience and additional troubleshooting effort.
</Note>
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th, .scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
text-align: left;
vertical-align: top;
word-wrap: break-word;
overflow-wrap: break-word;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
&#125;
.scale-requirements-table col:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table col:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table col:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table col:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table col:nth-child(5) &#123; width: 24%; &#125;
</style>
<table class="scale-requirements-table">
<colgroup>
<col style={{width: '25%'}} />
<col style={{width: '10%'}} />
<col style={{width: '18%'}} />
<col style={{width: '23%'}} />
<col style={{width: '24%'}} />
</colgroup>
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>2</td>
<td>8/16</td>
<td>c7i.2xlarge</td>
<td>F8s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>8/64</td>
<td>db.r7g.2xlarge</td>
<td>E8ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>1</td>
<td>8/64</td>
<td>db.r7g.2xlarge</td>
<td>E8ds v5</td>
</tr>
<tr>
<td>Elasticsearch cluster</td>
<td>4</td>
<td>8/64</td>
<td>r6g.2xlarge.search</td>
<td>E8ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>1</td>
<td>16/64</td>
<td>m7i.4xlarge</td>
<td>D16s v6</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 30000-person team with medium usage (with a safety factor of 2x) would require between 3TB <sup>1</sup> and 15TB <sup>2</sup> of free space per annum.
<sup>1</sup> 30000 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 30000 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
<Inc2_additional_ha_considerations />

View File

@@ -0,0 +1,128 @@
---
title: "Scale Mattermost up to 50,000 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
import Inc2_additional_ha_considerations from './additional-ha-considerations.mdx';
<PlanAvailability slug="ent-plus" />
This page describes the Mattermost reference architecture designed for the load of up to 50,000 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Required
- **Database Configuration**: writer, multiple readers
<Note>
- Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are.
- While the following Elasticsearch specifications may be more than sufficient for some use cases, we have not extensively tested configurations with lower resource allocations for this user scale. If cost optimization is a priority, admins may choose to experiment with smaller configurations, but we recommend starting with the tested specifications to ensure system stability and performance. Keep in mind that under-provisioning can lead to degraded user experience and additional troubleshooting effort.
</Note>
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th, .scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
text-align: left;
vertical-align: top;
word-wrap: break-word;
overflow-wrap: break-word;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
&#125;
.scale-requirements-table col:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table col:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table col:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table col:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table col:nth-child(5) &#123; width: 24%; &#125;
</style>
<table class="scale-requirements-table">
<colgroup>
<col style={{width: '25%'}} />
<col style={{width: '10%'}} />
<col style={{width: '18%'}} />
<col style={{width: '23%'}} />
<col style={{width: '24%'}} />
</colgroup>
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>5</td>
<td>8/16</td>
<td>c7i.2xlarge</td>
<td>F8s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>8/64</td>
<td>db.r7g.2xlarge</td>
<td>E8ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>4</td>
<td>8/64</td>
<td>db.r7g.2xlarge</td>
<td>E8ds v5</td>
</tr>
<tr>
<td>Elasticsearch cluster</td>
<td>4</td>
<td>8/64</td>
<td>r6g.2xlarge.search</td>
<td>E8ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>1</td>
<td>16/64</td>
<td>m7i.4xlarge</td>
<td>D16s v6</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 50000-person team with medium usage (with a safety factor of 2x) would require between 6TB <sup>1</sup> and 30TB <sup>2</sup> of free space per annum.
<sup>1</sup> 50000 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 50000 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
<Inc2_additional_ha_considerations />

View File

@@ -0,0 +1,128 @@
---
title: "Scale Mattermost up to 80,000 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
import Inc2_additional_ha_considerations from './additional-ha-considerations.mdx';
<PlanAvailability slug="ent-plus" />
This page describes the Mattermost reference architecture designed for the load of up to 80,000 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Required
- **Database Configuration**: writer, multiple readers
<Note>
- Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are.
- While the following Elasticsearch specifications may be more than sufficient for some use cases, we have not extensively tested configurations with lower resource allocations for this user scale. If cost optimization is a priority, admins may choose to experiment with smaller configurations, but we recommend starting with the tested specifications to ensure system stability and performance. Keep in mind that under-provisioning can lead to degraded user experience and additional troubleshooting effort.
</Note>
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th, .scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
text-align: left;
vertical-align: top;
word-wrap: break-word;
overflow-wrap: break-word;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
&#125;
.scale-requirements-table col:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table col:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table col:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table col:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table col:nth-child(5) &#123; width: 24%; &#125;
</style>
<table class="scale-requirements-table">
<colgroup>
<col style={{width: '25%'}} />
<col style={{width: '10%'}} />
<col style={{width: '18%'}} />
<col style={{width: '23%'}} />
<col style={{width: '24%'}} />
</colgroup>
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>4</td>
<td>16/32</td>
<td>c7i.4xlarge</td>
<td>F16s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>16/128</td>
<td>db.r7g.4xlarge</td>
<td>E16ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>3</td>
<td>16/128</td>
<td>db.r7g.4xlarge</td>
<td>E16ds v5</td>
</tr>
<tr>
<td>Elasticsearch cluster</td>
<td>4</td>
<td>8/64</td>
<td>r6g.2xlarge.search</td>
<td>E8ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>1</td>
<td>16/64</td>
<td>m7i.4xlarge</td>
<td>D16s v6</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 80000-person team with medium usage (with a safety factor of 2x) would require between 10.56TB <sup>1</sup> and 52.8TB <sup>2</sup> of free space per annum.
<sup>1</sup> 80000 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 80000 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
<Inc2_additional_ha_considerations />

View File

@@ -0,0 +1,128 @@
---
title: "Scale Mattermost up to 90,000 users"
---
import Inc0_lifetime_storage from './lifetime-storage.mdx';
import Inc1_estimated_storage_per_user_per_month from './estimated-storage-per-user-per-month.mdx';
import Inc2_additional_ha_considerations from './additional-ha-considerations.mdx';
<PlanAvailability slug="ent-plus" />
This page describes the Mattermost reference architecture designed for the load of up to 90,000 concurrent users. Unsure which reference architecture to use? See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for details.
- **High Availability**: Required
- **Database Configuration**: writer, multiple readers
<Note>
- Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are.
- While the following Elasticsearch specifications may be more than sufficient for some use cases, we have not extensively tested configurations with lower resource allocations for this user scale. If cost optimization is a priority, admins may choose to experiment with smaller configurations, but we recommend starting with the tested specifications to ensure system stability and performance. Keep in mind that under-provisioning can lead to degraded user experience and additional troubleshooting effort.
</Note>
## Requirements
<style>
.scale-requirements-table &#123;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse;
font-size: 0.9em;
overflow-wrap: break-word !important;
word-wrap: break-word !important;
&#125;
.scale-requirements-table th, .scale-requirements-table td &#123;
border: 1px solid #ddd;
padding: 8px;
text-align: left;
vertical-align: top;
word-wrap: break-word;
overflow-wrap: break-word;
&#125;
.scale-requirements-table th &#123;
background-color: #f8f9fa;
font-weight: bold;
&#125;
.scale-requirements-table col:nth-child(1) &#123; width: 25%; &#125;
.scale-requirements-table col:nth-child(2) &#123; width: 10%; &#125;
.scale-requirements-table col:nth-child(3) &#123; width: 18%; &#125;
.scale-requirements-table col:nth-child(4) &#123; width: 23%; &#125;
.scale-requirements-table col:nth-child(5) &#123; width: 24%; &#125;
</style>
<table class="scale-requirements-table">
<colgroup>
<col style={{width: '25%'}} />
<col style={{width: '10%'}} />
<col style={{width: '18%'}} />
<col style={{width: '23%'}} />
<col style={{width: '24%'}} />
</colgroup>
<thead>
<tr>
<th>Resource Type</th>
<th>Nodes</th>
<th>vCPU/Memory (GiB)</th>
<th>AWS Instance</th>
<th>Azure Instance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mattermost Application</td>
<td>5</td>
<td>16/32</td>
<td>c7i.4xlarge</td>
<td>F16s v2</td>
</tr>
<tr>
<td>RDS Writer</td>
<td>1</td>
<td>16/128</td>
<td>db.r7g.4xlarge</td>
<td>E16ds v5</td>
</tr>
<tr>
<td>RDS Reader</td>
<td>4</td>
<td>16/128</td>
<td>db.r7g.4xlarge</td>
<td>E16ds v5</td>
</tr>
<tr>
<td>Elasticsearch cluster</td>
<td>4</td>
<td>8/64</td>
<td>r6g.2xlarge.search</td>
<td>E8ads v6</td>
</tr>
<tr>
<td>Proxy</td>
<td>1</td>
<td>16/64</td>
<td>m7i.4xlarge</td>
<td>D16s v6</td>
</tr>
</tbody>
</table>
## Lifetime storage
<Inc0_lifetime_storage />
### Estimated storage per user, per month
<Inc1_estimated_storage_per_user_per_month />
### Example
A 90000-person team with medium usage (with a safety factor of 2x) would require between 10.56TB <sup>1</sup> and 52.8TB <sup>2</sup> of free space per annum.
<sup>1</sup> 90000 users \* 5 MB \* 12 months \* 2x safety factor
<sup>2</sup> 90000 users \* 25 MB \* 12 months \* 2x safety factor
We strongly recommend that you review storage utilization at least quarterly to ensure adequate free space is available.
## Additional considerations
<Inc2_additional_ha_considerations />

View File

@@ -0,0 +1,82 @@
---
title: "Scaling for Enterprise"
---
<PlanAvailability slug="ent-plus" />
Mattermost is designed to scale from small teams hosted on a single server to large enterprises running in cluster-based, highly available deployment configurations.
- Mattermost supports any 64-bit x86 processor architecture
- **Databases supported**: PostgreSQL, Amazon RDS for PostgreSQL
- **Storage supported**: Amazon S3 or a local filestore
Server requirements vary based on usage and we highly recommend that you run a pilot before an enterprise-wide deployment in order to estimate full scale usage based on your specific organizational needs.
## Backing storage
Review detailed [write and read storage benchmark results](/deployment-guide/scale/backing-storage-benchmarks) for supported storage options including local file system (EBS, gp3), network file system (EFS), and object storage (S3) to make informed decisions based on your use case and infrastructure needs.
## Enterprise search
We highly recommend a dedicated server for large enterprise deployments to run highly efficient database searches in a cluster environment.
For deployments with over 5 million posts, [Enterprise search](/deployment-guide/scale/enterprise-search) using [Elasticsearch](/deployment-guide/scale/enterprise-search#elasticsearch) or [AWS OpenSearch Service](/deployment-guide/scale/enterprise-search#aws-opensearch-service) is required for optimized search performance, dedicated indexing and usage resourcing via cluster support without performance degradation and timeouts, resulting in faster, more predicable search results.
## High availability
A [high availability cluster-based deployment](/deployment-guide/server/high-availability-cluster-based-deployment) enables a Mattermost system to maintain service during outages and hardware failures through the use of redundant infrastructure.
## Redis
[Redis](/deployment-guide/scale/redis) is an in-memory data structure store that can be used as a database, cache, and message broker. Mattermost uses Redis as an external cache to improve performance at scale. When properly configured, Redis can help support Mattermost installations with more than 100,000 users by providing improved performance through efficient caching.
## Available reference architectures
The following reference architectures are available as recommended starting points for your self-hosted Mattermost deployment, where user counts refer to the number of concurrent users for a given deployment. The number of concurrent numbers is commonly lower than the total number of user accounts.
- [Scale up to 200 users](/deployment-guide/scale/scale-to-200-users) - Learn how to scale Mattermost to up to 200 users.
- [Scale up to 2,000 users](/deployment-guide/scale/scale-to-2000-users) - Learn how to scale Mattermost to up to 2,000 users.
- [Scale up to 15,000 users](/deployment-guide/scale/scale-to-15000-users) - Learn how to scale Mattermost to up to 15,000 users.
- [Scale up to 30,000 users](/deployment-guide/scale/scale-to-30000-users) - Learn how to scale Mattermost to up to 30,000 users.
- [Scale up to 50,000 users](/deployment-guide/scale/scale-to-50000-users) - Learn how to scale Mattermost to up to 50,000 users.
- [Scale up to 80,000 users](/deployment-guide/scale/scale-to-80000-users) - Learn how to scale Mattermost to up to 80,000 users.
- [Scale up to 90,000 users](/deployment-guide/scale/scale-to-90000-users) - Learn how to scale Mattermost to up to 90,000 users.
- [Scale up to 100,000 users](/deployment-guide/scale/scale-to-100000-users) - Learn how to scale Mattermost to up to 100,000 users.
- [Scale up to 200,000 users](/deployment-guide/scale/scale-to-200000-users) - Learn how to scale Mattermost to up to 200,000 users.
<Important>
Due to constraints in testing, the proxy instance specifications were fixed for all the scaling tests from which we derived these reference architectures. This was done to avoid a combinatorial explosion of variables in tests, but it resulted in minor gaps in our understandings of certain aspects of the reference architectures. In particular, the proxy instance is overspecified for the smaller user counts.
</Important>
## Testing methodology and updates
All tests were executed with the custom load test tool built by the Mattermost development teams to determine supported users for each deployment size. Over time, this guide will be updated with new deployment sizes, deployment architectures, and newer versions of the Mattermost Server will be tested using an ESR.
At a high level, each deployment size was fixed (Mattermost server node count/sizing, database reader/writer count/sizing), and unbounded tests were used to report the maximum numbers of concurrent users the deployment can support. Each test included populated PostgreSQL v14 databases and a post table history of 100 million posts, ~200000 users, 20 teams, and ~720000 channels to provide a test simulation of a production Mattermost deployment.
Tests were defined by configuration of the actions executed by each simulated user (and the frequency of these actions) where the coordinator metrics define a health system under load. Tests were performed using the Mattermost v9.5 Extended Support Release (ESR). Job servers weren't used. All tests with more than a single app node had an NGINX proxy running in front of them.
For the last test of 200K users, further infrastructure changes were made. Elasticsearch nodes were added. A Redis instance was added, and multiple NGINX proxies were used to distribute traffic evenly across all nodes in the cluster. More details can be found on the [scale to 200000 users](/deployment-guide/scale/scale-to-200000-users) documentation page.
Full testing methodology, configuration, and setup is available, incluidng a [fixed database dump with 100 million posts](https://us-east-1.console.aws.amazon.com/backup/home?region=us-east-1#/resources/arn%3Aaws%3Ards%3Aus-east-1%3A729462591288%3Acluster%3Adb-pg-100m-posts-v9-5-5). Visit the [Mattermost Community](https://community.mattermost.com/) and join the [Developers: Performance channel](https://community.mattermost.com/core/channels/developers-performance) for details.
The performance specifications and user capacities provided in these reference architectures are based on extensive testing conducted in AWS environments.
For Azure deployments, the instance specifications have been extrapolated using equivalent configurations, drawing upon AWS performance data and industry expertise. While these configurations are designed to meet the stated requirements, we have not yet conducted formal testing in Azure environments to validate performance under load. Azure Blob Storage support is in active development, and not yet natively supported by Mattermost.
## Mattermost load testing tools
Mattermost provides a set of tools written in Go to help profiling Mattermost under heavy load, simulating real-world usage of a server installation at scale. The [Mattermost Load Test Tool](https://github.com/mattermost/mattermost-load-test-ng) estimates the maximum number of concurrently active users the target system supports, and enables you to control the load to generate.
Visit the [Mattermost Load Test Tool](https://github.com/mattermost/mattermost-load-test-ng/tree/master/docs) documentation on GitHub for details on getting started with the tools, and visit [the Go documentation](https://pkg.go.dev/github.com/mattermost/mattermost-load-test-ng) for code-specific documentation details.
<Important>
- The Mattermost Load Test Tool was designed by and is used by our performance engineers to compare and benchmark the performance of the service from month to month to prepare for new releases. It's also used extensively in developing our recommended hardware sizing.
- We recommend deploying [Prometheus and Grafana](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring) with our [dashboards](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring#getting-started) for ongoing monitoring and scale guidance.
- If you encounter performance concerns, we recommend [collecting performance metrics](/administration-guide/scale/collect-performance-metrics) and sharing them with us as a first troubleshooting step.
</Important>
[Book a live demo](https://mattermost.com/request-demo/) or [talk to a Mattermost expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization's secure collaboration needs. Or try Mattermost yourself with a [1-hour preview](https://mattermost.com/sign-up/) for instant access to a live sandbox environment.

View File

@@ -0,0 +1,95 @@
---
title: "Deployment Architecture at Scale"
---
import useBaseUrl from '@docusaurus/useBaseUrl';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
The following diagrams detail suggested architecture configurations of [high availability Mattermost deployments](/deployment-guide/server/high-availability-cluster-based-deployment#deployment-guide) at different scales. Hardware and infrastructure requirements will vary significantly based on usage and policies. See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for reference architecture guidance at scale, including hardware and infrastructure requirements.
High availability in Mattermost consists of running redundant Mattermost application servers, redundant database servers, and redundant load balancers so that failure of any one of these components does not interrupt operation of the system. Upon failure of one component, the remaining application servers, database servers, and load balancers must be sized and configured to carry the full load of the system. If this requirement is not met, an outage of one component can result in an overload of the remaining components, causing a complete system outage.
<Important>
Mattermost does not support high availability deployments spanning multiple datacenters. All nodes in a high availability cluster must reside within the same datacenter to ensure proper functionality and performance.
</Important>
You can apply most configuration changes and dot release security updates without interrupting service, provided that you update the system components in the correct sequence. Changes to configuration settings that require a server restart, and server version upgrades that involve a change to the database schema, require a short period of downtime. Downtime for a server restart is around 5 seconds. For a database schema update, downtime can be up to 30 seconds.
## Designed for scale
Mattermost is designed to be able to handle a large number of concurrent users, and the architecture can be scaled up or down as needed. The architecture is also designed to be flexible, allowing for the addition of new components or services as needed. The following diagrams show the recommended architecture for Mattermost deployments at 5,000, 10,000, 25,000, and 50,000 users. The diagrams are organized by user count and include a general diagram, AWS and Azure versions of each diagram, and an Oracle diagram for 5,000 users. See the [scaling for enterprise](/deployment-guide/scale/scaling-for-enterprise) documentation for more information on scaling Mattermost deployments.
- Each generalized diagram represents a full High Availability deployment across all critical components. The proxy, database, file storage, and Elasticsearch layers can be replaced by cloud services.
- Each AWS diagram represents a full High Availability deployment on Amazon Web Services making full use of the available services.
- Each Azure diagram represents a full High Availability deployment on Microsoft Azure making full use of the available services.
- Each Oracle diagram represents a full High Availability deployment on Oracle Cloud Infrastructure making full use of the available services. Currently, only the 5,000-user diagram is available for Oracle.
- Push proxy can be replaced by the Mattermost [hosted push notification service](/administration-guide/configure/push-notification-server-configuration-settings#hosted-push-notifications-service-hpns).
<Tabs>
<TabItem value="aws" label="AWS">
<Tabs>
<TabItem value="5-000-users" label="5,000 users">
<img src={useBaseUrl('/images/MattermostDeployment5kaws.png')} class="bg-white" alt="Mattermost high availability deployment architecture on AWS for 5,000 users" />
</TabItem>
<TabItem value="10-000-users" label="10,000 users">
<img src={useBaseUrl('/images/MattermostDeployment10kaws.png')} class="bg-white" alt="Mattermost high availability deployment architecture on AWS for 10,000 users" />
</TabItem>
<TabItem value="25-000-users" label="25,000 users">
<img src={useBaseUrl('/images/MattermostDeployment25kaws.png')} class="bg-white" alt="Mattermost high availability deployment architecture on AWS for 25,000 users" />
</TabItem>
<TabItem value="50-000-users" label="50,000 users">
<img src={useBaseUrl('/images/MattermostDeployment50kaws.png')} class="bg-white" alt="Mattermost high availability deployment architecture on AWS for 50,000 users" />
</TabItem>
</Tabs>
</TabItem>
<TabItem value="azure" label="Azure">
<Tabs>
<TabItem value="5-000-users" label="5,000 users">
<img src={useBaseUrl('/images/MattermostDeployment5kAzure.png')} class="bg-white" alt="Mattermost high availability deployment architecture on Azure for 5,000 users" />
</TabItem>
<TabItem value="10-000-users" label="10,000 users">
<img src={useBaseUrl('/images/MattermostDeployment10kAzure.png')} class="bg-white" alt="Mattermost high availability deployment architecture on Azure for 10,000 users" />
</TabItem>
<TabItem value="25-000-users" label="25,000 users">
<img src={useBaseUrl('/images/MattermostDeployment25kAzure.png')} class="bg-white" alt="Mattermost high availability deployment architecture on Azure for 25,000 users" />
</TabItem>
<TabItem value="50-000-users" label="50,000 users">
<img src={useBaseUrl('/images/MattermostDeployment50kAzure.png')} class="bg-white" alt="Mattermost high availability deployment architecture on Azure for 50,000 users" />
</TabItem>
</Tabs>
</TabItem>
<TabItem value="oracle" label="Oracle">
<Tabs>
<TabItem value="5-000-users" label="5,000 users">
<img src={useBaseUrl('/images/MattermostDeployment5kOracle.png')} class="bg-white" alt="Mattermost high availability deployment architecture on Oracle Cloud Infrastructure for 5,000 users" />
</TabItem>
</Tabs>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,27 @@
---
title: "FIPS / STIG Container Builds"
sidebar_label: "FIPS / STIG container builds"
---
From Mattermost v11, each release provides two variants: a FIPS-compliant build and a non-FIPS build. This ensures that organizations with strict compliance requirements can adopt the FIPS version while others can continue with the standard release, both staying in sync with Mattermost’s overall product lifecycle.
FIPS/STIG compliance in Mattermost is a property of the **container image**, not a separate install method. This page applies equally whether you [deploy with Docker](/deployment-guide/server/deploy-containers) or [deploy on Kubernetes](/deployment-guide/server/deploy-kubernetes). In both cases, you point your deployment at `mattermost/mattermost-enterprise-fips-edition` instead of the standard tag.
Mattermost FIPS-compliant Docker images are built using Chainguard’s FIPS-certified base containers. These images help organizations meet stringent security requirements by ensuring compliance with the Federal Information Processing Standards (FIPS).
On top of this foundation, Mattermost product code itself is aligned with FIPS requirements, using only FIPS-approved cryptographic algorithms. This ensures that both the underlying container base and the application layer meet compliance expectations.
In addition, the Chainguard base images are STIG-hardened and rigorously scanned against the DISA General Purpose Operating System SRG, providing a robust and secure operational posture.
Mattermost’s FIPS-compliant images are built using two Chainguard base images:
- [Build-Time Image](https://images.chainguard.dev/directory/image/go-msft-fips/overview): Ensures compiled Mattermost binaries invoke OpenSSL through CGO for FIPS-compliance during compilation.
- [Runtime Image](https://images.chainguard.dev/directory/image/glibc-openssl-fips/overview): Enforces FIPS compliance in the runtime environment using strict OpenSSL configurations.
All application-level code uses only FIPS-approved algorithms, ensuring that cryptographic requirements are consistently enforced across every layer of the system.
<Note>
- The Mattermost FIPS image includes only prepackaged Boards, Playbooks, and Agents. Additional plugins can be added to the Mattermost FIPS image, but they will run in non-FIPS mode.
- Existing Docker or Kubernetes-based deployments can change the image from `mattermost/mattermost-enterprise-edition` to `mattermost/mattermost-enterprise-fips-edition`. See [Migrate an existing deployment to FIPS-compliant images](/administration-guide/manage/admin/fips-migration) for step-by-step instructions.
</Note>

View File

@@ -0,0 +1,334 @@
---
title: "Deploy Mattermost using Containers"
---
You can deploy Mattermost Server using container technologies for exploring functionality, testing, and development purposes, as it allows you to quickly set up a Mattermost instance without needing to manage the underlying infrastructure. This deployment method shouldn't be used in production environments as it doesn't support clustered deployments or High Availability (HA) configurations out-of-the-box.
<Warning>
- Mattermost server deployment using Docker is officially supported on Linux operating systems only.
- macOS and Windows Docker deployments are supported for testing and development purposes only.
- Docker is not ideal for High Availability (HA) because it lacks key features including automatic failover, shared storage, and load balancing. Docker also has challenges managing multiple nodes and recovering from failures. We recommend [deploying on Kubernetes](/deployment-guide/server/deploy-kubernetes) for HA for these features to ensure reliability.
</Warning>
If you don't have Docker installed, follow the instructions below based on your operating system. You'll need [Docker Engine](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/) (release 1.28 or later).
<Tip>
**Need a FIPS / STIG-compliant image?** Mattermost publishes a FIPS-compliant, STIG-hardened variant of every container image. Swapping the image tag is the only change required — see [FIPS / STIG container builds](/deployment-guide/server/containers/fips-stig).
</Tip>
## Deploy Mattermost on Docker
This section provides a quick start guide for deploying Mattermost on Docker by leveraging [Docker Compose](https://docs.docker.com/compose/install/).
<Note>
- The deployment configuration results in two separate containers: a container for the database and a container for the application. An optional third container results when using NGINX for reverse proxy.
- Encountering issues with your Docker deployment? See the [Docker deployment troubleshooting](/deployment-guide/server/docker-troubleshooting) documentation for details.
</Note>
1. In a terminal window, clone the repository and enter the directory.
``` sh
git clone https://github.com/mattermost/docker
cd docker
```
2. Create your `.env` file by copying and adjusting the `env.example` file.
``` sh
cp env.example .env
```
<Important>
- At a minimum, you must edit the `DOMAIN` value in the `.env` file to correspond to the domain for your Mattermost server.
- We recommend configuring the [Support Email](/administration-guide/configure/site-configuration-settings#support-email-address) via `MM_SUPPORTSETTINGS_SUPPORTEMAIL`. This is the email address your users will contact when they need help.
</Important>
3. Create the required directories and set their permissions.
``` sh
mkdir -p ./volumes/app/mattermost/{config,data,logs,plugins,client/plugins,bleve-indexes}
sudo chown -R 2000:2000 ./volumes/app/mattermost
```
4. *(Optional)* Configure TLS for NGINX. If you're not using the included NGINX reverse proxy, you can skip this step.
<Note>
**Resource limits:** If you're using a custom `docker-compose.yml` file that sets <code>pids_limit</code>, we recommend using `mem_limit` instead to constrain resources while allowing normal connection scaling. Low `pids_limit` values can prevent the container from creating enough processes or threads, which may lead to unstable behavior under load. The current default in `docker-compose.yml` is set to `mem_limit: 4G`.
</Note>
### Create a new certificate and key
``` sh
bash scripts/issue-certificate.sh -d <YOUR_MM_DOMAIN> -o ${PWD}/certs
```
To include the certificate and key, uncomment the following lines in your `.env` file and ensure they point to the appropriate files.
``` sh
#CERT_PATH=./certs/etc/letsencrypt/live/${DOMAIN}/fullchain.pem
#KEY_PATH=./certs/etc/letsencrypt/live/${DOMAIN}/privkey.pem
```
### Use a pre-existing certificate and key
``` sh
mkdir -p ./volumes/web/cert
cp <PATH-TO-PRE-EXISTING-CERT>.pem ./volumes/web/cert/cert.pem
cp <PATH-TO-PRE-EXISTING-KEY>.pem ./volumes/web/cert/key-no-password.pem
```
To include the certificate and key, ensure the following lines in your `.env` file points to the appropriate files.
``` sh
CERT_PATH=./volumes/web/cert/cert.pem
KEY_PATH=./volumes/web/cert/key-no-password.pem
```
5. Deploy Mattermost.
### Deploy without using the included NGINX
``` sh
docker compose -f docker-compose.yml -f docker-compose.without-nginx.yml up -d
```
To access your new Mattermost deployment, navigate to `http://<YOUR_MM_DOMAIN>:8065/` in your browser.
To shut down your deployment:
``` sh
docker compose -f docker-compose.yml -f docker-compose.without-nginx.yml down
```
### Deploy using the included NGINX
``` sh
docker compose -f docker-compose.yml -f docker-compose.nginx.yml up -d
```
To access your new Mattermost deployment via HTTPS, navigate to `https://<YOUR_MM_DOMAIN>/` in your browser.
To shut down your deployment:
``` sh
docker compose -f docker-compose.yml -f docker-compose.nginx.yml down
```
6. Create your first Mattermost system admin user, [invite more users](/end-user-guide/collaborate/manage-channel-members), and explore the Mattermost platform.
### Configure SSO with GitLab (optional)
To use SSO with GitLab with a self-signed certificate, you have to add the PKI chain for your authority. This is required to avoid the `Token request failed: certificate signed by unknown authority` error.
To add the PKI chain, uncomment the following line in your `.env` file, and ensure it points to your `pki_chain.pem` file:
``` sh
#GITLAB_PKI_CHAIN_PATH=<path_to_your_gitlab_pki>/pki_chain.pem
```
Then uncomment the following line in your `docker-compose.yml` file, and ensure it points to the same `pki_chain.pem` file:
``` sh
# - ${GITLAB_PKI_CHAIN_PATH}:/etc/ssl/certs/pki_chain.pem:ro
```
### Upgrade from mattermost-docker
The [mattermost-docker](https://github.com/mattermost/mattermost-docker) GitHub repository is deprecated. Visit the [mattermost/docker](https://github.com/mattermost/docker) GitHub repository to access the official Docker deployment solution for Mattermost.
To migrate from an existing `mattermost/mattermost-prod-app` image, we recommend migrating to either `mattermost/mattermost-enterprise-edition` or `mattermost/mattermost-team-edition` images, which are the official images supported by Mattermost. These images support PostgreSQL v11+ databases, which we know has been a long-running challenge for the community, and you will not lose any features or functionality by moving to these new images.
For additional help or questions, please refer to [this issue](https://github.com/mattermost/mattermost-docker/issues/489).
### Install a different version of Mattermost
1. Shut down your deployment.
2. Run `git pull` to fetch any recent changes to the repository, paying attention to any potential `env.example` changes.
3. Adjust the `MATTERMOST_IMAGE_TAG` in the `.env` file to point your desired [enterprise](https://hub.docker.com/r/mattermost/mattermost-enterprise-edition/tags?page=1&ordering=last_updated) or [team](https://hub.docker.com/r/mattermost/mattermost-team-edition/tags?page=1&ordering=last_updated) image version.
<Important>
**For production environments**, we recommend using specific version tags such as `MATTERMOST_IMAGE_TAG=release-10.5` rather than generic tags like `MATTERMOST_IMAGE_TAG=release-10`. Generic `release-x` tags are intended for development use only and do not automatically receive new patch releases within that major version. Using specific version tags ensures a more reproducible and deterministic environment for your production deployment.
</Important>
4. Redeploy Mattermost.
## Troubleshooting your Docker deployment
If deploying on an M1 Mac and encountering permission issues in the Docker container, redo the "create the required directories" step above and skip this command:
``` sh
sudo chown -R 2000:2000 ./volumes/app/mattermost
```
If having issues deploying on Docker generally, ensure the docker daemon is enabled and running:
``` sh
sudo systemctl enable --now docker
```
To remove all data and settings for your Mattermost deployment:
``` sh
sudo rm -rf ./volumes
```
### Troubleshooting PostgreSQL
For quick start deployments, you can change the Postgres username and/or password (recommended) in the `.env` file. If your database is managed externally, you'll need to change the password in your database management tool. Then, update the `.env` file with the new credentials.
### Troubleshooting TLS & NGINX
For an in-depth guide to configuring the TLS certificate and key for Nginx, please refer to [this document in the repository](https://github.com/mattermost/docker/blob/main/docs/issuing-letsencrypt-certificate.md).
## Trial Mattermost using Docker Preview
Looking for a way to evaluate Mattermost on a single local machine using Docker? We recommend using the [Mattermost Docker Preview Image](https://github.com/mattermost/mattermost-docker-preview) to install Mattermost in Preview Mode.
<Important>
- This local image is self-contained (i.e., it has an internal database and works out of the box). Dropping a container using this image removes data and configuration as expected. You can see the [configuration settings](/administration-guide/configure/configuration-settings) documentation to learn more about customizing your trial deployment.
- **Preview Mode** shouldn't be used in a production environment, as it uses a known password string, contains other non-production configuration settings, has email disabled, keeps no persistent data (all data lives inside the container), and doesn't support upgrades.
- If you are planning to use the calling functionality in **Preview Mode** on a non-local environment, you should ensure that the server is running on a secure (HTTPs) connection and that the [network requirements](/deployment-guide/calls/calls-rtcd-setup#network-requirements) to run calls are met.
</Important>
1. Install [Docker](https://www.docker.com/get-started/).
2. Once you have Docker, run the following command in a terminal window:
``` sh
docker run --name mattermost-preview -d --publish 8065:8065 --publish 8443:8443 mattermost/mattermost-preview
```
3. When Docker is done fetching the image, navigate to `http://localhost:8065/` in your browser to preview Mattermost.
4. Select **Don't have an account** in the top right corner of the screen to create an account for your preview instance. If you don't see this option, ensure that the [Enable open server](/administration-guide/configure/authentication-configuration-settings#enable-open-server) configuration setting is enabled. This setting is disabled for self-hosted Mattermost deployments by default.
5. Log in to your preview instance with your user credentials.
### Troubleshooting your preview deployment
The **Preview Mode** Docker instance for Mattermost is designed for product evaluation, and sets `SendEmailNotifications=false` so the product can function without enabling email. See the [Configuration Settings](/administration-guide/configure/configuration-settings) documentation to customize your deployment.
To update your Mattermost preview image and container, you must first stop and delete your existing **mattermost-preview** container by running the following commands:
``` sh
docker pull mattermost/mattermost-preview
docker stop mattermost-preview
docker rm mattermost-preview
```
Once the new image is pulled and the container is stopped and deleted you need to run the `docker run` command from above.
<Important>
On Linux, include `sudo` in front of all `docker` commands.
</Important>
To access a shell inside the container, run the following command:
``` sh
docker exec -ti mattermost-preview /bin/bash
```
<Note>
See [Docker deployment troubleshooting](/deployment-guide/server/docker-troubleshooting) for resolutions to common container issues, or [Deployment troubleshooting](/deployment-guide/server/troubleshooting) for issues that aren't specific to containers.
</Note>
## Secure your Mattermost deployment
Deploying Mattermost using Docker containers can be made secure with proper configurations for HTTPS and reverse proxying. This guide outlines the steps to set up TLS and an NGINX reverse proxy for your Mattermost deployment, ensuring secure communication between users and your server.
1. Set Up an NGINX Container to serve as the reverse proxy. You can use NGINX either as a separate container or installed on the host machine.
2. Bind Volumes for NGINX Configuration and TLS Certificates:
> - Bind Docker volumes for NGINX configuration files and TLS certificates to ensure persistent and secure storage of these assets.
> - Use permission restrictions on host directories where sensitive files such as TLS keys are stored.
3. Create the NGINX Configuration File by designing a robust `nginx.conf` file to configure reverse proxying and HTTPS. Here's a basic example:
``` nginx
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://mattermost:8065;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
```
Verify the configuration with `nginx -t` before applying.
4. Obtain TLS Certificates:
> - Use Let's Encrypt for free, automated certificates. Tools like Certbot can help automate the process.
> - Alternatively, purchase certificates from a trusted certificate authority (CA) and ensure proper setup of intermediate and root certificate chains.
>
> Keep private keys secure and avoid storing them directly inside Docker images.
5. Connect Containers Using Docker Networking:
> - Use Docker's networking features to isolate and link containers.
>
> - Create a custom Docker bridge network to ensure secure communication. For example:
>
> ``` sh
> docker network create mattermost-network
> ```
>
> - Launch the Mattermost and NGINX containers on the same network:
>
> ``` sh
> docker network connect mattermost-network mattermost
> docker network connect mattermost-network nginx
> ```
6. Point your domain to the server IP address:
Ensure your domain (e.g., your-domain.com) points to the public IP address of your server. If your IP is dynamic, consider setting up Dynamic DNS (DDNS) for seamless connectivity.
7. After placing the certificates and updating the configuration, restart the NGINX container:
8. Use logs (docker logs nginx) to troubleshoot and validate the container's operation.
9. Verify HTTPS Access by visiting `https://your-domain.com` in a web browser to confirm Mattermost is running securely over HTTPS.
10. Use tools such as SSL Labs : [https://www.ssllabs.com/ssltest/](https://www.ssllabs.com/ssltest/) to validate the quality of your TLS setup.
11. Enable HTTP Strict Transport Security (HSTS) in your NGINX configuration to prevent downgrade attacks.
12. Use NGINX rate-limiting features to restrict abusive traffic, such as excessive requests:
Additionally, consider:
- Use Docker's security features such as Seccomp profiles and AppArmor to secure your container runtime.
- Avoid running containers with elevated privileges `--privileged` and utilize user namespaces.
- Always use trusted images (e.g., official NGINX and Mattermost images) to prevent exposure to vulnerabilities in third-party images.
- Update Mattermost, NGINX, and Docker to their latest versions regularly to ensure patches for known vulnerabilities are applied.
- Set up proper firewall rules to restrict unauthorized access and monitor traffic using tools like Fail2Ban or Wazuh.
By following these steps, your Mattermost deployment using Docker containers will be accessible securely over HTTPS with efficient proxying through NGINX. Implementing the additional security recommendations will further protect your environment against evolving threats.

View File

@@ -0,0 +1,64 @@
---
title: "Deploy Mattermost on Kubernetes"
---
<PlanAvailability slug="entry-ent" />
Mattermost server can be deployed on various Kubernetes platforms, providing a scalable and robust infrastructure for your team communication needs. This guide covers deployment options for major cloud providers and general Kubernetes installations.
<Tip>
To learn how to safely upgrade your deployment in Kubernetes for High Availability with Active/Active support, see the [Upgrading Mattermost in Kubernetes and High Availability Environments](/administration-guide/upgrade/upgrade-mattermost-kubernetes-ha) documenation.
</Tip>
## Choose an install method
<CardGrid columns={2} cards={[
{
title: 'Mattermost Operator',
description: 'Deploy using the Mattermost Kubernetes Operator with S3-compatible storage and a managed database service. Recommended for most Kubernetes and cloud-native production deployments.',
to: '/deployment-guide/server/kubernetes/deploy-k8s',
},
{
title: 'Oracle (OKE)',
description: 'Deploy Mattermost Enterprise Edition on Oracle Cloud Infrastructure using Oracle Kubernetes Engine (OKE) via the Oracle Cloud Marketplace listing.',
to: '/deployment-guide/server/kubernetes/deploy-k8s-oke',
},
]} />
## Frequently Asked Questions
### Why are my pods failing with a `CrashLoopBackOff` error after adding a custom CA certificate to my Docker image?
You may see a `CrashLoopBackOff` error after adding a custom CA certificate to your Docker image's `/etc/ssl/certs` directory and deploying it to your Kubernetes environment via the Mattermost Enterprise Edition Helm Chart. This issue typically arises because the custom CA certificate is not being recognized by the system's certificate trust store, leading to TLS handshake failures when the application attempts to connect to services that require the custom CA.
While core functionality may remain operational, you may notice the following symptoms:
- Pods stuck in a crashloop with the error message: backoff - restarting failed container in pod.
- Debugging commands like `kubectl describe` and `kubectl logs` provide little to no valuable information.
- Integrations may be blocked.
### Can I resolve this issue without rebuilding the Docker image?
Yes. We recommend using Kubernetes-native solutions to manage custom CA certificates to simplify deployment processes and minimize disruptions caused by image rebuilds. You can inject the certificate directly into the pod using Kubernetes resources instead of modifying the Docker image to manage custom CA certificates dynamically without needing to rebuild and redeploy your Docker image every time the certificate changes.
Use a Kubernetes secret to store your custom CA certificate and then mount it into the pod:
1. Create a Kubernetes secret with your custom CA certificate.
2. Mount the certificate into the pod using the Helm chart’s configuration options. This method simplifies management and avoids the need to rebuild your Docker image for future certificate updates.
Alternatively, to dynamically inject certificates without modifying the Docker image, use an `initContainer` to copy the certificate into the pod's filesystem and update the certificate trust store before the main container starts.
### How to troubleshoot the root cause of the `CrashLoopBackOff` error?
Use `kubectl describe pods` to check detailed event logs.
Consider logging tools like Grafana to aggregate and analyze logs for additional insights.
### Where is data stored in a self-hosted Kubernetes deployment?
Where data is stored depends on the backend database (such as RDS, Azure Postgres, self-hosted PostgreSQL), and the backend filestore (such as AWS S3, other S3-compatible services, or a mounted volume) configured during deployment.
For volume mounts, we recommend using an NFS volume to provide filestores as a "local" directory to the Mattermost server.
Not all types of [Kubernetes persistent volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes) have been tested with Mattermost, and some may have limitations or specific configurations that may require additional setup to ensure proper permissions and access. We recommend system admins review documentation for their preferred persistent volume types and test to ensure compatibility with Mattermost.

View File

@@ -0,0 +1,57 @@
---
title: "Deploy Mattermost on Linux"
---
Mattermost Server runs on any 64-bit Linux system. For production, run Mattermost and the PostgreSQL database on separate hosts. A single-host install is suitable for development and testing.
## Choose an install method
<CardGrid columns={4} cards={[
{
title: 'Ubuntu / Debian',
description: 'Install from the signed Mattermost APT repository (deb). Recommended for Ubuntu 20.04 / 22.04 / 24.04 LTS and Debian — provides automatic security updates via apt.',
to: '/deployment-guide/server/linux/deploy-ubuntu',
},
{
title: 'Red Hat (RHEL)',
description: 'Install from the release tarball with manual systemd setup, including SELinux contexts. Covers RHEL, Rocky, Alma, Oracle Linux 7+.',
to: '/deployment-guide/server/linux/deploy-rhel',
},
{
title: 'Manual (tarball)',
description: 'Install on any 64-bit Linux distribution from the release tarball. Maximum flexibility — typically chosen by advanced administrators and air-gapped environments.',
to: '/deployment-guide/server/linux/deploy-tar',
},
{
title: 'Azure Native VM',
description: 'Deploy a production-ready Mattermost stack from the Azure Marketplace, provisioned into your own Azure subscription with managed compute, database, storage, and load balancing.',
to: '/deployment-guide/server/linux/deploy-azure-native-vm',
},
]} />
## Before you install
The Ubuntu/Debian, Red Hat (RHEL), and manual (tarball) methods all require you to bring your own host and database:
- A 64-bit Linux host with at least **1 vCPU and 2 GB RAM** (supports up to ~1,000 users)
- **PostgreSQL 14+** — either local to the host, on a separate server, or a managed service. See [Set up the database](/deployment-guide/server/prepare-database), or [PostgreSQL Migration](/administration-guide/manage/admin/postgres-migration) if you're moving from MySQL.
- Inbound ports **80** and **443** (HTTPS) and **8065** (System Console). See [Network ports](/deployment-guide/server/prepare-network) for the full list, and [Prepare](/deployment-guide/server/preparations) for the pre-install checklist.
- Outbound port **10025** if you'll send notification email through a relay.
The Azure Native VM method provisions its own compute, managed PostgreSQL, and storage from the Azure Marketplace — see its [prerequisites](/deployment-guide/server/linux/deploy-azure-native-vm#prerequisites) instead.
## After you install
Once Mattermost is running, complete these steps before exposing it to users:
- [Set up an NGINX reverse proxy](/deployment-guide/server/setup-nginx-proxy) and [terminate TLS](/deployment-guide/server/setup-tls) at the proxy. Don't run Mattermost as an internet-facing service without a proxy.
- Configure [pre-authentication secrets](/deployment-guide/server/pre-authentication-secrets) if your environment requires them.
- Work through [Configure Mattermost](/administration-guide/configure/configure-index) and [onboard your users](/administration-guide/onboard/onboard-index).
:::tip Air-gapped environments
If you're deploying into a network-isolated enclave, see [Air-Gapped Operations](/deployment-guide/air-gapped-operations/quick-start-runbook) instead of the connected install paths above. It covers package mirroring and the configuration changes needed on top of the standard install.
:::
:::note[Troubleshooting]
See [Deployment troubleshooting](/deployment-guide/server/troubleshooting) for common install failures.
:::

View File

@@ -0,0 +1,77 @@
---
title: "Deploy the Mattermost server"
---
All three deployment methods below install the same Mattermost Server. They differ in how you provision and operate the host, whether high availability is available, and which Mattermost plan you need. Choose one, then follow its install path.
Before you get here, work through [Plan](/deployment-guide/server/server-deployment-planning) to size the deployment, and [Prepare](/deployment-guide/server/preparations) to stand up the database, file storage, reverse proxy, and TLS.
<CardGrid columns={3} cards={[
{
title: 'Kubernetes',
description: 'Deploy with the Mattermost Operator. Recommended for production: high availability, rolling upgrades, and infrastructure as code.',
to: '/deployment-guide/server/deploy-kubernetes',
},
{
title: 'Linux',
description: 'Install directly on a 64-bit Linux host from the APT repository or the release tarball. The most common choice for self-hosted and private-cloud deployments.',
to: '/deployment-guide/server/deploy-linux',
},
{
title: 'Containers',
description: 'Run Mattermost with Docker Compose. For evaluation, testing, and development only. Not supported for production.',
to: '/deployment-guide/server/deploy-containers',
},
]} />
## Deployment options
### Kubernetes
<PlanAvailability slug="entry-ent" />
Deploying with the [Mattermost Kubernetes Operator](/deployment-guide/server/deploy-kubernetes) is our recommended approach for production, because it offers:
- High availability and horizontal scaling across multiple app nodes
- Automated updates and rollbacks
- Infrastructure as code
- Built-in monitoring and logging
- Integration with existing DevOps workflows
The Operator works on any conformant cluster. Mattermost publishes a dedicated guide for [Oracle Kubernetes Engine (OKE)](/deployment-guide/server/kubernetes/deploy-k8s-oke); guidance for Azure Kubernetes Service has been withdrawn, so deploy on AKS with the Operator as you would on any other cluster.
### Linux
[Installing directly on Linux](/deployment-guide/server/deploy-linux) gives you full control over the host and doesn't require a container platform. Choose it when:
- Containers or Kubernetes aren't available or aren't preferred in your environment
- You want a straightforward setup on a host you already manage
- You're deploying into an air-gapped enclave from the release tarball
High availability is available on this path too, but you configure and operate the cluster yourself. See [High availability cluster-based deployment](/deployment-guide/server/high-availability-cluster-based-deployment).
Install methods: [Ubuntu/Debian](/deployment-guide/server/linux/deploy-ubuntu), [RHEL and derivatives](/deployment-guide/server/linux/deploy-rhel), [manual tarball](/deployment-guide/server/linux/deploy-tar), and [Azure Native VM](/deployment-guide/server/linux/deploy-azure-native-vm) from the Azure Marketplace.
### Containers
[Docker Compose deployments](/deployment-guide/server/deploy-containers) get a Mattermost instance running quickly without provisioning the infrastructure yourself. Use this path for exploring functionality, testing, and development.
<Warning>
Container deployments aren't supported for production. Docker lacks automatic failover, shared storage, and load balancing, so it can't provide clustered or High Availability deployments out of the box. Deploy on [Kubernetes](/deployment-guide/server/deploy-kubernetes) for production HA. Docker deployments are officially supported on Linux only; macOS and Windows are for testing and development.
</Warning>
A FIPS-compliant, STIG-hardened variant of every container image is published for regulated environments. See [FIPS and STIG container builds](/deployment-guide/server/containers/fips-stig).
## Don't want to deploy it yourself?
Third-party and community-maintained solutions can deploy and upgrade Mattermost for you. See [Deployment Solution Programs](/get-help/deployment-solution-programs) for the recognition tiers and what each commits to.
## What's next
After the server is running:
- [Secure your deployment](/deployment-guide/encryption-options) with encryption at rest and [in transit](/deployment-guide/transport-encryption).
- [Scale](/deployment-guide/scale/scaling-for-enterprise) with clustering, search infrastructure, and Redis caching.
- [Back up and recover](/deployment-guide/backup-disaster-recovery) to set the backup strategy before you have users.
- If the install fails, see [Deployment troubleshooting](/deployment-guide/server/troubleshooting).

View File

@@ -0,0 +1,64 @@
---
title: "Docker deployment troubleshooting"
---
## Permission issues on M1 Mac
If you're deploying the Mattermost server using Docker on an M1 Mac and encountering permission issues in the Docker container, re-create the required directories and set their permissions, then skip the following command because it causes the deploy to stop working.
``` sh
sudo chown -R 2000:2000 ./volumes/app/mattermost
```
If you're experiencing issues deploying on Docker generally, ensure the docker daemon is enabled and running:
``` sh
sudo systemctl enable --now docker
```
To remove all data and settings for your Mattermost deployment:
``` sh
sudo rm -rf ./volumes
```
## TLS and NGINX issues
For an in-depth guide to configuring the TLS certificate and key for NGINX, please refer to [this document in the repository](https://github.com/mattermost/docker/blob/main/docs/issuing-letsencrypt-certificate.md).
## Install a different version of Mattermost
1. Shut down your deployment.
2. Run `git pull` to fetch any recent changes to the repository, paying attention to any potential `env.example` changes.
3. Adjust the `MATTERMOST_IMAGE_TAG` in the `.env` file to point your desired [enterprise](https://hub.docker.com/r/mattermost/mattermost-enterprise-edition/tags?page=1&ordering=last_updated) or [team](https://hub.docker.com/r/mattermost/mattermost-team-edition/tags?page=1&ordering=last_updated) image version.
<div class="important">
<div class="title">
Important
</div>
**For production environments**, we recommend using specific version tags such as `MATTERMOST_IMAGE_TAG=release-10.5` rather than generic tags like `MATTERMOST_IMAGE_TAG=release-10`. Generic `release-x` tags are intended for development use only and do not automatically receive new patch releases within that major version. Using specific version tags ensures a more reproducible and deterministic environment for your production deployment.
</div>
4. Redeploy Mattermost.
## Unintentional version downgrades
If you experience an unintentional downgrade when using generic `MATTERMOST_IMAGE_TAG=release-x` tags, this is because these tags are designed for development use and may not point to the latest patch release within that major version.
**Solution**: Use a more specific version tag for your Docker image, such as `MATTERMOST_IMAGE_TAG=release-10.5`, to avoid unexpected version changes and ensure consistent deployments.
<Note>
A [pipeline improvement](https://github.com/mattermost/mattermost/issues/30656) is in progress to ensure that generic `release-x` tags are updated to the latest version from the corresponding release branch. Once this improvement is implemented, the behavior of these tags will be more predictable.
</Note>
## Upgrading from `mattermost-docker`
For an in-depth guide to upgrading from the deprecated [mattermost-docker repository](https://github.com/mattermost/mattermost-docker), please refer to [this document](https://github.com/mattermost/docker/blob/main/scripts/UPGRADE.md). For additional help, please refer to [this issue](https://github.com/mattermost/mattermost-docker/issues/489).

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
---
title: "(Optional) Use an Image proxy"
---
<PlanAvailability slug="all-commercial" />
When enabled, the image proxy needs to be publicly accessible to both the Mattermost client and server.
Mattermost clients will use the image proxy to load all external images. The Mattermost server will use the image proxy when possible, but will not use it when requesting content that may not be an image, such as for [image previews of plaintext URLs](https://github.com/mattermost/mattermost/issues/11857).
Configure an image proxy by going to **System Console \> Environment \> Image Proxy**.
## Local image proxy
The local image proxy is available as part of the Mattermost server deployment. When using the local image proxy, images are served to clients through the server which helps anonymize users. If SSL is enabled on the server, it provides a secure connection. This method does not offer any caching behavior.
<Note>
With the local image proxy enabled, requests for images hosted on the local network are now affected by the `AllowUntrustedInternalConnections` setting. See [documentation](/administration-guide/configure/environment-configuration-settings#allow-untrusted-internal-connections) for more information or if you are seeing unintentionally blocked images.
</Note>
## atmos/camo image proxy
The [atmos/camo](https://github.com/atmos/camo) image proxy is a standalone image proxy that can be deployed separately from the Mattermost server. It provides additional configuration options over the built-in image proxy, and it can also be used if isolation between the Mattermost server and image proxy is desired.
Once you've deployed an `atmos/camo` ([https://github.com/atmos/camo](https://github.com/atmos/camo)) instance, you must specify the **Remote Image Proxy URL** and **Remote Image Proxy Options** settings. The **Remote Image Proxy Options** should be set to the image proxy's shared key which is specified with the `CAMO_KEY` environment variable used when setting up the image proxy.
For example, if the image proxy is located at `https://image-proxy.mattermost.com`, it would be configured as follows:
> - **Image Proxy Type**: `atmos/camo`
> - **Remote Image Proxy URL**: `https://image-proxy.mattermost.com`
> - **Remote Image Proxy Options**: `CAMO_KEY`, which is the secret string used for the sample `atmos/camo` deployment.
![Enable and configure an atmos/camo image proxy in the System Console by going to Environment \> Image Proxy, specifying atmos/camo as the proxy type, providing the URL of the remote image proxy server, and by specifying the CAMO_KEY secret string.](/images/image-proxy.png)

View File

@@ -0,0 +1,193 @@
---
title: "Deploy Mattermost on Oracle Kubernetes Engine (OKE)"
sidebar_label: "Deploy on OKE (Oracle)"
---
You can use the supported [Oracle Cloud Marketplace listing](https://cloudmarketplace.oracle.com/marketplace/en_US/listing/188386963), **Mattermost - OCI-Native (Kubernetes-based)**, to deploy a high-availability Mattermost environment on Oracle Cloud Infrastructure (OCI). One guided stack provisions a new Oracle Kubernetes Engine (OKE) cluster, a managed OCI Database with PostgreSQL system, an Object Storage bucket for file attachments, the Mattermost Kubernetes Operator, and HTTPS ingress through the OCI Native Ingress Controller.
## Before you begin
Before deploying, make sure you have the following:
- **An Oracle Cloud tenancy and compartment** you have permission to create resources in (VCN, OKE, IAM policies, OCI Database with PostgreSQL, Object Storage, Resource Manager)
- **Sufficient service limits** for a new OKE cluster and its default worker pool (3 nodes, `VM.Standard.E5.Flex` at 2 OCPUs/16GB each) and for an OCI Database with PostgreSQL system
- **A registered domain name** you can create a DNS `A` record for, pointing to the Mattermost load balancer
- **A TLS certificate for that domain, imported into OCI Certificate Service**, with its OCID ready before you deploy. The stack does not accept a raw PEM/private key, only a certificate OCID.
- **A Mattermost Enterprise license** if you plan to deploy for more than 100 users. Larger sizes run Mattermost and PostgreSQL in high-availability mode, which requires a license.
## Installation steps
The installation process includes deploying Mattermost and configuring the necessary components.
### Step 1: Start from Oracle Cloud Marketplace
Go to the **Mattermost - OCI-Native (Kubernetes-based)** listing and select **Launch Stack**.
![Oracle Cloud Marketplace listing for Mattermost - OCI-Native (Kubernetes-based)](/images/oracle/marketplace-listing.png)
### Step 2: Stack Information
On the **Create stack** page, review the information, and then set the stack name, description, compartment, and Terraform version.
![Create stack information page for Mattermost on OKE](/images/oracle/stack-info.png)
### Step 3: Configure Variables
Set all the details for your Mattermost deployment. Variables are grouped by area; advanced groups are hidden behind a **Show advanced options** toggle so the default flow stays simple.
#### General Configuration
- **Compartment:**
- Target compartment for every resource the stack creates: the OKE cluster, VCN, PostgreSQL DB system, and Object Storage bucket.
- **Cluster Name Prefix:**
- Used as a prefix on all OCI resources created by the stack (default: `mattermost`).
- **Show Recovery Options:**
- Leave off for a normal deployment. Only enable this if a previous apply failed and left resources blocking re-apply; it reveals a **Deploy ID Revision** field that forces new resource names.
#### Mattermost Installation
- **Mattermost Installation Name:**
- Name for this installation (default: `mattermost-prod`).
- **Mattermost Installation Size:**
- Choose the size that matches your expected active user count: `100users`, `1000users`, `5000users`, `10000users`, or `25000users` (default: `100users`). This drives both the Mattermost pod resources and the PostgreSQL topology (instance count, shape). It's a **create-time-only setting**: changing it later requires deploying a new stack because OCI can't modify PostgreSQL topology in place. Sizes above 100 users deploy Mattermost and PostgreSQL in high-availability mode and require an Enterprise license.
- **Mattermost Version:**
- The Mattermost server version to install.
- **Mattermost License Key:**
- Upload your Enterprise license file. Optional at `100users`; leave empty to start unlicensed and add a license later from **System Console > Edition and License**. Required for every larger size.
- **Mattermost FQDN:**
- The hostname end users will browse to (for example, `mattermost.domain.com`). You'll point its DNS `A` record at the stack's output load balancer IP after deployment.
- **OCI Certificate Service OCID:**
- The OCID of the certificate you imported into OCI Certificate Service for that FQDN.
- **Mattermost LB Allowed CIDR Blocks:**
- IP ranges allowed to reach Mattermost over HTTPS. Default (`0.0.0.0/0`) allows access from anywhere; restrict this for corporate or internal-only deployments.
- **Show Advanced Mattermost Options:**
- Turn this on to reveal the following fields, all of which have sensible defaults for most deployments:
- **Kubernetes Namespace:** The namespace Mattermost is installed into (default: `mattermost`).
- **Helm Repository URL:** Source of the Mattermost Operator Helm chart (default: `https://helm.mattermost.com`).
- **Operator Helm Chart Version:** Choose the Mattermost Operator Helm chart version to install from the list (default: the newest version offered).
- **NIC Readiness Wait Timeout:** How long to wait for the Native Ingress Controller to become ready before failing the apply (default: 180 seconds).
#### OKE Configuration
- **Kubernetes Version:**
- Leave empty to auto-select the newest version OKE publishes.
- **Worker OS Version:**
- Oracle Linux `8` or `9` (default: `8`).
- **Worker Count:**
- Number of worker nodes in the cluster (default: 3, recommended for high availability). You can adjust this later by editing and re-applying the stack.
- **Show Advanced OKE Options:**
- Turn this on to reveal the following fields, all of which have sensible defaults for most deployments:
- **Virtual Cloud Network (VCN) CIDR:** IP address range for the cluster's network (default: `10.20.0.0/16`). Only change this if it conflicts with an existing network you need to peer with.
- **API Endpoint Allowed CIDR Blocks:** IP ranges allowed to reach the Kubernetes API (default: `0.0.0.0/0`, i.e. anywhere). Restrict this to your corporate gateway or VPN range for tighter security. Make sure the range you choose covers your own admin access, since there's no bastion host as a fallback path.
- **Cluster CNI:** The pod networking mode: `OCI_VCN_IP_NATIVE` (default, recommended for better performance and tighter VCN integration) or `FLANNEL_OVERLAY`.
- **Worker Shape:** Compute shape for each worker node (default: `VM.Standard.E5.Flex` with 2 OCPUs/16 GB memory), suitable for most Mattermost deployments.
- **Worker Pool Name:** The name for the worker node pool as it appears in the OCI Console and CLI.
#### Cluster Tools
- **Install Metrics Server:**
- Enables `kubectl top` and the metrics API HPA relies on, if you add your own autoscaler later. On by default; recommended for all deployments.
- **Create OKE IAM Policies:**
- Automatically creates the IAM policies OKE needs to manage cluster resources. On by default; disable only if these policies already exist in your compartment.
#### PostgreSQL
- **PostgreSQL Database Name / Description:**
- The display name and description for the OCI Database with PostgreSQL system (separate from the Mattermost application database name below).
- **PostgreSQL Major Version:**
- `14`, `15`, `16`, or `17` (default: `16`).
- **PostgreSQL Admin Username / Password:**
- Admin credentials for the DB system. Passwords must be 8–32 characters with at least one uppercase letter, one lowercase letter, one number, and one special character, and cannot contain single quotes, double quotes, backslashes, or semicolons.
- **Mattermost Database Name / User / Password:**
- The database, user, and password Mattermost itself connects with inside PostgreSQL (defaults: `mattermost` / `mmuser`). The password follows the same rules as the PostgreSQL Admin Password above (8–32 characters, upper/lowercase, number, special character; no quotes, backslashes, or semicolons).
- **Create a Subnet for the Mattermost Database:**
- On by default, to create a dedicated subnet for the DB system. Disable to select an existing subnet instead.
- **PostgreSQL Backup Retention (Days):**
- Automatic-backup retention, 7–35 days (default: 30).
- **Show Advanced PostgreSQL Options:**
- Turn this on to reveal the following fields, all of which have sensible defaults for most deployments:
- **PostgreSQL Port:** The port PostgreSQL listens on (default: `5432`).
- **Backup Window:** Daily UTC time window for automatic backups.
- **Maintenance Window:** Weekly UTC time window for maintenance operations.
- **Per-Tier Overrides:** Instance count, OCPUs, and memory overrides for each Mattermost Installation Size tier.
#### Object Storage
- **Bucket Compartment:**
- Compartment for the Object Storage bucket. Defaults to the main compartment.
- **Object Storage Bucket Name:**
- Name of the bucket used to store Mattermost file attachments.
#### Tagging
- **Tag Resources:**
- Optionally apply OCI free-form or defined tags to every resource the stack creates.
### Step 4: Review and Apply
Check all your settings and select **Create** to start the deployment. Monitor the Resource Manager job and logs. The first apply takes about 30 minutes.
![Resource Manager job monitor](/images/oracle/job-monitor.png)
### Step 5: After Deployment
When the job finishes, open the stack's **Application information** tab to review the deployment details:
![Application information tab showing deployment, Kubernetes, and Mattermost details](/images/oracle/application-information.png)
- **Load Balancer IP Address**: Copy the IP shown beside this label and create a DNS `A` record from your **Mattermost FQDN** to it. This reserved OCI Public IP stays stable across re-applies.
- **Mattermost URL** (top-right button): The public HTTPS URL, reachable once DNS propagates.
- **OKE Cluster OCID** and **Deployed Kubernetes Version:** Identify the OKE cluster if you need to connect with `kubectl` or the OCI CLI.
Once the `A` record resolves, open your browser and go to the Mattermost URL.
### Step 6: Upgrade Mattermost
To upgrade your Mattermost installation:
1. Go to your Resource Manager stack and select **Edit**.
2. Update the **Mattermost Version** variable to the target release.
3. Save and run **Plan**, then **Apply**.
The Native Ingress Controller uses Pod Readiness Gates to hold new pods out of rotation until their OCI load balancer backend reports healthy. On an HA-sized installation (above `100users`, multiple Mattermost replicas), this minimizes disruption during the rollout since other replicas keep serving traffic. On the default `100users` size, which runs a single replica, a brief interruption while that pod restarts is expected.
<Tip>
**Tips for Success**
- Make sure you have all the permissions you need before you start.
- Import your TLS certificate into OCI Certificate Service and have its OCID ready before configuring variables. The stack won't accept a raw certificate/key pair.
- Choose your **Mattermost Installation Size** carefully: it can't be changed on an existing stack without recreating the PostgreSQL system.
- To run `kubectl` against the cluster (for example, from OCI Cloud Shell), pull a kubeconfig using the **OKE Cluster OCID** and **Deployment Region** from the Application Information tab: `oci ce cluster create-kubeconfig --cluster-id <oke_cluster_ocid> --region <deployment_region> --file $HOME/.kube/config --kube-endpoint PUBLIC_ENDPOINT --token-version 2.0.0`. Run `kubectl get nodes` to confirm access.
- Always monitor logs from the Resource Manager job and from pods with `kubectl logs` for more specific error messages.
- For more details, see the official [OCI Database with PostgreSQL documentation](https://www.oracle.com/cloud/postgresql/) and [OKE documentation](https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengoverview.htm).
</Tip>
## Common Errors and How to Avoid Them
- **Error: Stack creation fails with missing permissions**
- *Cause:* IAM policies are not set properly for the user or group running the stack.
- *Solution:* Ensure you have permissions for Resource Manager, OKE, Networking, OCI Database with PostgreSQL, Object Storage, and Certificate Service.
- **Error: Plan fails because a Mattermost license is required**
- *Cause:* **Mattermost Installation Size** is set above `100users` without a license uploaded; larger sizes deploy in high-availability mode, which is Enterprise-licensed.
- *Solution:* Upload a valid Mattermost Enterprise license, or choose `100users`.
- **Error: Mattermost URL doesn't resolve after deployment**
- *Cause:* The DNS `A` record for your FQDN hasn't been created yet, or hasn't propagated.
- *Solution:* Create an `A` record from your **Mattermost FQDN** to the `mattermost_lb_ip` output, then wait for DNS propagation.
- **Error: Certificate OCID rejected or ingress never becomes healthy**
- *Cause:* The **OCI Certificate Service OCID** doesn't exist, isn't in the same tenancy, or doesn't match the configured FQDN.
- *Solution:* Re-check the certificate in OCI Certificate Service and confirm the OCID was copied correctly.
- **Error: PostgreSQL password rejected**
- *Cause:* The **PostgreSQL Admin Password** or **Mattermost Database Password** doesn't meet the required complexity rules (8–32 characters, upper/lowercase, number, special character; no quotes, backslashes, or semicolons).
- *Solution:* Re-enter a password that satisfies the pattern shown in the field description.
- **Error: Terraform destroy fails on the PostgreSQL system or the bucket**
- *Cause:* The database system has destroy protection enabled by design, and OCI refuses to delete a non-empty Object Storage bucket.
- *Solution:* Empty the bucket first, then disable the database's lifecycle protection before destroying.
<Important>
You are responsible for Oracle Cloud Infrastructure costs for the resources you create. Oracle Cloud credits cannot be used to buy a Mattermost license.
</Important>
Learn more about managing your Mattermost server in the [Administration Guide](/administration-guide/administration-guide-index).

View File

@@ -0,0 +1,308 @@
---
title: "Deploy Mattermost with the Mattermost Operator"
sidebar_label: "Mattermost Operator"
---
You can use the Mattermost Kubernetes Operator to deploy Mattermost on Kubernetes using S3-compatible storage and a managed database service. While the operator supports a range of configurations, we strongly recommend using a cloud-native approach for production environments.
<Tip>
**Need a FIPS / STIG-compliant image?** Point the Operator manifest's `version`/image field at `mattermost/mattermost-enterprise-fips-edition` image and the rest of this procedure is unchanged. See [FIPS / STIG container builds](/deployment-guide/server/containers/fips-stig).
</Tip>
Before you begin, ensure you have the following:
- A functioning Kubernetes cluster (see the [Kubernetes setup guide](https://kubernetes.io/docs/setup/)). Your cluster should be running a [supported Kubernetes version](https://kubernetes.io/releases/).
- The <code>kubectl</code> command-line tool installed on your local machine (see the [kubectl installation guide](https://kubernetes.io/docs/reference/kubectl/)).
- A fundamental understanding of Kubernetes concepts, such as deployments, pods, and applying manifests.
- Sufficient Kubernetes resources allocated based on your expected user load. Consult the [scaling for Enterprise](/deployment-guide/scale/scaling-for-enterprise#available-reference-architectures) documentation for resource requirements at different scales.
## Installation steps
The installation process involves setting up necessary operators and then deploying Mattermost itself.
### Step 1: Install the NGINX Ingress Controller
Follow the instructions in the [Kubernetes deployment documentation](https://kubernetes.github.io/ingress-nginx/deploy/) to install the NGINX ingress controller on your Kubernetes cluster. Mattermost recommends installing the Nginx Operator via helm, regardless of platform you are installing to.
### Step 2: Install the Mattermost Operator
The Mattermost Kubernetes Operator can be installed using Helm.
1. Install Helm (version 3.13.0 or later). See the [Helm quickstart documentation](https://helm.sh/docs/using_helm/) for installation instructions.
2. Add the Mattermost Helm repository:
``` sh
helm repo add mattermost https://helm.mattermost.com
```
3. Create a file named `config.yaml` and populate it with the contents of the [Mattermost operator values file](https://github.com/mattermost/mattermost-helm/blob/master/charts/mattermost-operator/values.yaml). This file allows for customization of the operator.
4. Create a namespace for the Mattermost Operator:
``` sh
kubectl create ns mattermost-operator
```
5. Install the Mattermost Operator. If you don't specify a version, the latest version of the Mattermost Operator will be installed. We recommend using the latest version of the Mattermost Operator.
``` sh
helm install <your-release-name> mattermost/mattermost-operator -n <namespace_name>
```
For example:
``` sh
helm install mattermost-operator mattermost/mattermost-operator -n mattermost-operator
```
To use your custom `config.yaml` file:
``` sh
helm install mattermost-operator mattermost/mattermost-operator -n mattermost-operator -f config.yaml
```
### Step 3: Deploy Mattermost
<Note>
- A Mattermost Enterprise license is required for multi-server deployments.
- For single-server deployments without an Enterprise license, add `Replicas: 1` to the `spec` section in step 2 below. See the [high availability documentation](/deployment-guide/server/high-availability-cluster-based-deployment) for more on highly-available deployments.
</Note>
1. **(Mattermost Enterprise only)** Create a Mattermost license secret. Create a file named `mattermost-license-secret.yaml` with the following content, replacing `[LICENSE_FILE_CONTENTS]` with your actual license:
``` yaml
apiVersion: v1
kind: Secret
metadata:
name: my-mattermost-license
type: Opaque
stringData:
license: <LICENSE_FILE_CONTENTS>
```
2. Create a Mattermost installation manifest file named `mattermost-installation.yaml`. File names in this guide are suggestions; you can use different names. Use the following template, adjusting the values as needed:
``` yaml
apiVersion: installation.mattermost.com/v1beta1
kind: Mattermost
metadata:
name: <INSTALLATION_NAME_HERE>
spec:
size: <SIZE_VALUE_HERE>
ingress:
enabled: true
host: <FULL_DOMAIN_NAME_HERE>
annotations:
kubernetes.io/ingress.class: nginx
version: <VERSION_HERE>
licenseSecret: ""
```
Key fields in the manifest include:
- `metadata.name`: The name of your Mattermost deployment in Kubernetes.
- `spec.size`: The size of your installation (e.g., "100users", "1000users", etc.).
- `spec.ingress.host`: The DNS name for your Mattermost installation.
- `spec.version`: The Mattermost version. See the [server version archive](/product-overview/version-archive) for available versions. You should use a [supported version](/product-overview/release-policy) of Mattermost in conjunction with the latest version of the Mattermost Operator.
- `spec.licenseSecret`: The name of the Kubernetes secret containing your license (required for Enterprise).
For a full list of configurable fields, see the [example manifest](https://github.com/mattermost/mattermost-operator/blob/master/docs/examples/mattermost_full.yaml) and the [Custom Resource Definition](https://github.com/mattermost/mattermost-operator/blob/master/config/crd/bases/installation.mattermost.com_mattermosts.yaml).
3. Create a file named `mattermost-database-secret.yaml` for database credentials. This secret must be in the same namespace as the Mattermost installation.
``` yaml
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
```
Example for AWS Aurora with PostgreSQL (`DB_CONNECTION_CHECK_URL`, `DB_CONNECTION_STRING`, and `MM_SQLSETTINGS_DATASOURCEREPLICAS` are the base64-encoded form of your Aurora connection URL, e.g. `postgres://user:password@host:5432/mattermost`):
``` yaml
apiVersion: v1
data:
DB_CONNECTION_CHECK_URL: cG9zdGdyZXM6Ly91c2Vy...
DB_CONNECTION_STRING: cG9zdGdyZXM6Ly91c2Vy...
MM_SQLSETTINGS_DATASOURCEREPLICAS: cG9zdGdyZXM6...
kind: Secret
metadata:
name: my-postgres-connection
type: Opaque
```
<Note>
The `DB_CONNECTION_CHECK_URL` value is consumed by the operator's legacy `postgres:13` + `pg_isready` readiness init container (the default `external` mode of `spec.database.readinessCheck`). New deployments are encouraged to set `spec.database.readinessCheck.mode: builtin` (see Step 5 below), in which case the readiness init container runs the in-image `mattermost db ping` command and the `DB_CONNECTION_CHECK_URL` field is no longer required. The legacy `external` mode remains the default for backward compatibility but is slated for deprecation in a future operator release.
</Note>
### Step 4: Create the Filestore Secret
Create a file named `mattermost-filestore-secret.yaml` to store the credentials for your object storage service (e.g., AWS S3 or any S3-compatible service). This secret must be created in the same namespace where you intend to install Mattermost. The file should contain the following YAML structure:
``` yaml
apiVersion: v1
kind: Secret
metadata:
name: <secret-name>
type: Opaque
data:
accesskey: <base64-encoded-access-key>
secretkey: <base64-encoded-secret-key>
```
<table>
<thead>
<tr>
<th>Key</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr>
<td>accesskey</td>
<td>Base64-encoded access key for your storage service.</td>
<td>Yes</td>
</tr>
<tr>
<td>secretkey</td>
<td>Base64-encoded secret key for your storage service.</td>
<td>Yes</td>
</tr>
<tr>
<td>metadata.name</td>
<td>The name of the Kubernetes secret.</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<Important>
The `accesskey` and `secretkey` values must be **base64-encoded**. Do not enter the raw keys directly. Use a command-line tool to generate the base64 strings.
**Example (AWS S3):**
``` yaml
apiVersion: v1
kind: Secret
metadata:
name: my-s3-credentials
type: Opaque
data:
accesskey: QUNDRVNTX0tFWQo=
secretkey: U1VQRVJfU0VDUkVUX0tFWQo=
```
Replace both values with your own base64-encoded keys.
</Important>
### Step 5: Configure the Mattermost Installation Manifest
1. Modify the `mattermost-installation.yaml` file (created in step 2) to connect Mattermost to your external database and object storage. Refer to the supported fields for guidance on where to add these configurations within the YAML structure.
2. Connect to the database:
1. Add the following to the `spec` section of your manifest:
``` yaml
spec:
database:
external:
secret: <database-secret-name>
```
Replace `<database-secret-name>` with the name of the database secret you created (e.g., `my-postgres-connection`).
2. **(Recommended)** Configure the database-readiness init container to use the in-image `mattermost db ping` command instead of the legacy `postgres:13` + `pg_isready` flow. This avoids the need to pull a separate `postgres:13` image (the primary motivation for air-gapped clusters that can't mirror it) and keeps your readiness check in sync with the Mattermost release you're running.
``` yaml
spec:
database:
external:
secret: <database-secret-name>
readinessCheck:
mode: builtin
timeout: 5m
```
`timeout` is optional and defaults to `5m`.
Using `builtin` mode requires a Mattermost release that ships the `mattermost db ping` command (see the [Mattermost server pull request](https://github.com/mattermost/mattermost/pull/36406) for availability).
Omitting `readinessCheck` (or setting `mode: external`) preserves the legacy `postgres:13` + `pg_isready` behavior. The legacy mode is the current default for backward compatibility and will be deprecated in a future operator release. See the [Mattermost CRD reference](https://github.com/mattermost/mattermost-operator/blob/master/docs/mattermost_v1beta1_crd.md) for the full `readinessCheck` field schema.
3. Connect to Object Storage:
1. Add the following to the `spec` section of your manifest:
``` yaml
spec:
fileStore:
external:
url: <storage-service-url>
bucket: <bucket-name>
secret: <filestore-secret-name>
```
Replace `<storage-service-url>` with the URL of your storage service (e.g., `s3.amazonaws.com`), `<bucket-name>` with the name of your storage bucket, and `<filestore-secret-name>` with the name of the filestore secret you created (e.g., `my-s3-credentials`).
4. If you are using Amazon S3, it's recommended to enable server-side encryption (SSE) and SSL. Add the following environment variables to the `mattermostEnv` section:
``` yaml
spec:
mattermostEnv:
MM_FILESETTINGS_AMAZONS3SSL: true
MM_FILESETTINGS_AMAZONS3SSE: true
```
## Review Mattermost Resource Status
After a Mattermost installation has been created with the Operator, you can review its status with the following:
``` sh
kubectl -n [namespace] get mattermost
```
The `kubectl describe` command can be used to obtain more information about the Mattermost server pods:
``` sh
kubectl -n [namespace] describe pod
```
**Follow logs**
The following command can be used to follow logs on any kubernetes pod:
``` sh
kubectl -n [namespace] logs -f [pod name]
```
If the `-n [namespace]` is omitted, then the default namespace of the current context is used. We recommend specifying the namespace based on your deployment.
This command can be used to review the Mattermost Operator or Mattermost server logs as needed.
<Note>
- If you're new to Kubernetes or prefer a managed solution, consider using a service like [Amazon EKS](https://aws.amazon.com/eks/), [Azure Kubernetes Service](https://azure.microsoft.com/en-ca/products/kubernetes-service/), [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/), or [DigitalOcean Kubernetes](https://www.digitalocean.com/products/kubernetes/). While this guidance focuses on using external, managed services for your database and file storage, the Mattermost Operator *does* offer the flexibility to use other solutions. For example, you could choose to deploy a PostgreSQL database within your Kubernetes cluster using the CloudNative PG operator (or externally however you wish), or use any self-hosted S3-compatible storage service.
- While using managed cloud services is generally simpler to maintain and our recommended approach for production deployments, using self-managed S3-compatible storage services and CloudNative PG for PostgreSQL are also valid options if you have the expertise to manage them.
- If you choose to use self-managed components, you'll need to adapt the instructions accordingly, pointing to your internal services instead.
- To customize your production deployment, refer to the [configuration settings documentation](/administration-guide/configure/configuration-settings).
- If you encounter issues during deployment, consult the [deployment troubleshooting guide](/deployment-guide/server/troubleshooting).
</Note>
## Frequently Asked Questions
### What is the Operator's version compatibility with Mattermost Server?
While generally speaking, the Operator should be compatible with most, or all versions of Mattermost Server, we recommend always using the latest version of the Operator in conjunction with a [supported version](/product-overview/release-policy) of Mattermost Server.

View File

@@ -0,0 +1,144 @@
---
title: "Deploy Mattermost on Azure Native (VM)"
sidebar_label: "Azure Native VM"
---
<EditionAvailability tiers="enterprise,enterprise-advanced" />
Mattermost is published as an **Azure Marketplace** solution that provisions a production-ready Mattermost stack in your own subscription using Azure-managed services for compute, database, shared file storage, and load balancing. This option is intended for organizations that want a resilient Mattermost deployment they can scale and operate within their existing Azure tenant.
## Prerequisites
- An active **Azure subscription** with the **Owner** or **Contributor** role on the subscription (required to purchase and deploy Azure Marketplace solutions), permission to create resource groups, and permission to accept **Azure Marketplace** billing terms for the offer.
- Familiarity with the **Azure portal** (resource groups, networking, virtual machines, and Application Gateway).
- For multi-node deployments (more than one application instance), a valid **Mattermost Enterprise license** file. The license is optional for single-node deployments.
- If you plan to enable **HTTPS** at deployment time:
- A **PFX (PKCS#12)** certificate bundle and its password.
- A **custom domain (FQDN)** that you will point to the Application Gateway after deployment.
## What gets deployed
The template provisions a self-contained, production-ready stack in the resource group you select, including:
1. **Virtual Machine Scale Set (Linux):** Runs Mattermost on Ubuntu Pro 24.04 LTS images published by Mattermost. Instance count and VM size are driven by the scaling tier you choose.
2. **Application Gateway with public IP:** Acts as the entry point for Mattermost traffic, with optional **HTTPS listener** (using your PFX certificate) and HTTP-to-HTTPS redirection when HTTPS is enabled.
3. **Azure Database for PostgreSQL Flexible Server:** Managed PostgreSQL service that stores Mattermost data, with optional **same-zone** or **zone-redundant** high availability, backup retention and geo-redundancy.
4. **Azure Files (NFS) with private endpoint:** Shared storage for Mattermost data (uploads, plugins, and other shared files), reachable only from inside the virtual network.
5. **Virtual network and subnets:** A dedicated VNet for the deployment, with separate subnets for the Application Gateway, the Mattermost application instances, the database, and the storage private endpoint.
6. **NAT gateway:** Provides controlled outbound internet access for the application instances (for example, to fetch packages and the Mattermost configuration scripts).
7. **Private DNS zones:** Used to resolve the PostgreSQL Flexible Server and Azure Files private endpoint from inside the VNet.
## Step 1: Select a plan and start creation
Open the [Mattermost - Azure-Native (VM-based)](https://marketplace.microsoft.com/en-us/product/azure-application/mattermost.mattermost-app-vm) offer in the Azure Marketplace, click **Get it now**, select the plan, and then click **Create** to open the deployment wizard.
## Step 2: Basics
On the **Basics** tab, configure the following:
1. **Subscription:** Choose the Azure subscription where the deployment will live.
2. **Resource group:** Select an existing resource group or create a new one. A **new** resource group keeps the production stack easy to manage and clean up.
3. **Region:** Select the deployment region. Choose a region that supports the PostgreSQL Flexible Server SKUs you plan to use, and that has the **availability zones** you need if you intend to enable PostgreSQL high availability.
4. **Resource name prefix:** Short prefix (2–12 lowercase letters, digits, or hyphens) used to name the Azure resources created by the template (for example, `mm-prod`).
![An example of the Azure Native Basics setup screen.](/images/azure/azure-native-basics.png)
## Step 3: Application
On the **Application** tab, configure how the Mattermost application is sized and how administrators access the VMs.
1. **Scaling tier:** Pick the user scale you are planning for. The wizard uses this to suggest sensible defaults for the **VMSS instance count**, **VM size**, and **PostgreSQL SKU**, and to determine whether **read replicas** are created for the database. The dropdown shows the recommended node count and VM SKU for each tier. For the underlying sizing rationale, see [available reference architectures](/deployment-guide/scale/scaling-for-enterprise#available-reference-architectures).
2. **VMSS instance count:** Number of Mattermost application nodes (1–5). Defaults to the suggested value for your scaling tier; adjust if needed.
3. **Enterprise license file:** Required when the instance count is greater than 1 (multi-node high-availability clustering). Upload your Mattermost Enterprise license file. The license is optional for single-node deployments.
4. **VM SKU:** Size of each VMSS instance. The wizard surfaces recommended Linux sizes first; you can select any supported Linux size available in your region.
5. **Admin username:** Linux administrator account used to sign in to the VM instances.
6. **Authentication type:** Choose **Password** or **SSH public key** for Linux sign-in. **SSH public key** is recommended for production deployments.
7. **Mattermost version:** The Mattermost version to install (for example, `11.6.2`). See the [Mattermost release policy](/product-overview/release-policy) for supported versions.
![An example of the Azure Native Application setup screen.](/images/azure/azure-native-application.png)
## Step 4: Database
On the **Database** tab, configure the managed PostgreSQL service and the shared NFS file share.
1. **PostgreSQL compute SKU:** Memory-optimized Flexible Server SKU. Defaults to the SKU recommended for your scaling tier; pick a SKU that is supported in your region. Available choices are `Standard_E2ds_v5`, `Standard_E4ds_v5`, and `Standard_E8ds_v5`.
2. **PostgreSQL high availability:** Choose how PostgreSQL is made resilient:
- **Disabled:** Single primary instance. Suitable for small deployments.
- **Same zone:** Primary and standby in the same availability zone.
- **Zone redundant:** Primary and standby in different availability zones.
For regional support of Flexible Server SKUs and HA modes, see [Azure regions for PostgreSQL Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/overview#azure-regions).
3. **Primary availability zone** and **standby availability zone:** Shown when HA is enabled. For zone-redundant HA, the primary and standby zones must be different. Pick zones supported in your region for the PostgreSQL SKU you chose.
4. **PostgreSQL admin username and password:** Administrator credentials for the Flexible Server. Avoid reserved names such as `azure_superuser`. The password must meet [Azure Flexible Server password complexity requirements](https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-security#password).
5. **Mattermost database user password:** In the **Mattermost database connection** section, set the password for the dedicated Mattermost database user that the application nodes use to connect to PostgreSQL. This is separate from the PostgreSQL administrator credentials. The password must meet the same complexity rules as the admin password.
6. **Geo-redundant backup:** Replicates PostgreSQL backups to Azure's paired region for cross-region disaster recovery. **This setting cannot be changed after deployment.**
7. **NFS share size (GiB):** Size of the Azure Files (NFS) share used by Mattermost for shared application data. Minimum 100 GiB.
:::note
Backup retention for PostgreSQL is set to 35 days at deployment time. You can change retention from the Azure portal after the deployment completes.
:::
![An example of the Azure Native Database setup screen.](/images/azure/azure-native-database.png)
## Step 5: Networking
On the **Networking** tab, configure the virtual network and how Mattermost is exposed to users.
1. **VNet address space (CIDR):** The address space for the virtual network created by the template. Defaults to `10.0.0.0/22`. Pick a range that does not overlap with other VNets you plan to peer with.
2. **Public IP DNS label:** You must set a **DNS prefix** (label) that is **globally unique** across Azure public cloud; it forms part of your URL and allows public access to your workspace. If the label is already taken, deployment will fail.
3. **Enable HTTPS on Application Gateway:** When enabled, the Application Gateway terminates TLS using your PFX certificate and HTTP traffic is redirected to HTTPS. When disabled, Mattermost is served over HTTP on the Azure-assigned hostname (suitable for testing, **not recommended for production**).
4. **PFX certificate** and **PFX password:** Shown when HTTPS is enabled. Upload your PKCS#12 bundle and provide the password used to protect it.
5. **Custom domain (FQDN):** Shown when HTTPS is enabled. The public hostname Mattermost will use (for example, `mattermost.example.com`). After deployment, point this hostname to the Azure-assigned DNS name of the Application Gateway public IP (typically using a **CNAME** record for subdomains).
![An example of the Azure Native Networking setup screen.](/images/azure/azure-native-networking.png)
## Step 6: Review and create
Review your settings, accept any **Marketplace** terms if prompted, then select **Create**. Provisioning typically takes 20–50 minutes, depending on your PostgreSQL configuration. Allow a few additional minutes after Azure reports the deployment as Succeeded before the application is reachable.
**After deployment completes:**
- In the Azure portal, open the **resource group** you used.
- Open the **public IP resource attached to your Application Gateway** (often named `<prefix>-ag-pip`). Under **Essentials**, note the **DNS name** (Azure-assigned FQDN).
- If you deployed **without HTTPS**, your site URL is:
`http://<dns-label>.<region>.cloudapp.azure.com`
- If you deployed **with HTTPS**, create a DNS record that points your **custom domain** to the Azure-assigned DNS name of the Application Gateway public IP (typically **CNAME** for subdomains; use your provider's apex-compatible record type if using a root domain). Once DNS propagates, your site URL is:
`https://<your-custom-domain>`
Congratulations! You've successfully deployed a production-ready Mattermost stack on Azure.
## Next steps
- For sizing guidance and reference architectures, see [high-availability-cluster-based-deployment](/deployment-guide/server/high-availability-cluster-based-deployment) and [server architecture](/deployment-guide/scale/server-architecture).
- For ongoing operations (upgrades, backups, monitoring), follow the standard Mattermost server administration documentation.
## Runbooks
### Upgrade Mattermost server
The VM scale set runs a Mattermost **Marketplace VM image** matching the version you selected in Step 3. Mattermost publishes new image versions for each supported release. To upgrade, point the VMSS at a newer image version in your deployment region. Application data stays in **PostgreSQL** and on the **Azure Files** share; the upgrade rolls application instances to VMs built from the updated image.
#### Before you upgrade
- Review the [important upgrade notes](/administration-guide/upgrade/important-upgrade-notes), and [prepare to upgrade](/administration-guide/upgrade/prepare-to-upgrade-mattermost) for the target version.
- Confirm **PostgreSQL** backups are current and that you can restore if needed.
- Pick a target version from the [Mattermost release policy](/product-overview/release-policy).
#### Upgrade steps
1. **Update the VMSS** to the new image version:
```sh
az vmss update \
--resource-group <resource-group> \
--name <resource-name-prefix>-vmss \
--set virtualMachineProfile.storageProfile.imageReference.version=<new-version>
```
The VMSS uses a **rolling** upgrade policy and an application health probe on `/api/v4/system/ping`, so instances are replaced in batches while the Application Gateway keeps serving traffic to healthy nodes.
2. **Monitor the rollout** in the Azure portal: open your VMSS → **Instances** (or **Rolling upgrades**) and wait until all instances are healthy and running the new model.
3. **Verify Mattermost**: Verify Mattermost uses the new version via **System Console → About**.

View File

@@ -0,0 +1,356 @@
---
title: "Deploy Mattermost on Red Hat Enterprise Linux"
sidebar_label: "Red Hat (RHEL)"
---
<EditionAvailability tiers="free,professional,enterprise,enterprise-advanced" />
<DeploymentAvailability modes="self-hosted" />
Install Mattermost Server on Red Hat Enterprise Linux (RHEL), Rocky Linux, AlmaLinux, Oracle Linux 7+, or CentOS Stream. RHEL doesn't have a signed APT-style repository, so this guide installs from the release tarball with manual systemd setup, then walks through the security configuration RHEL deployments typically need (SELinux contexts, firewalld rules, fapolicyd allow rules).
<Note title="Minimum requirements">
- **Operating system**: RHEL 7+, Rocky / Alma 8+, Oracle Linux 7+, CentOS Stream 8+.
- **Hardware**: 1 vCPU and 2 GB RAM (supports up to ~1,000 users).
- **Database**: [PostgreSQL 14+](/administration-guide/manage/admin/postgres-migration).
- **Network**: TCP 80/443 inbound (TLS), 8065 inbound (System Console), 10025 outbound (SMTP relay if used).
</Note>
## Step 1: Get a PostgreSQL database
Choose one of:
- **Install PostgreSQL locally** on the same host. See the [PostgreSQL installation documentation](https://www.postgresql.org/download/).
- **Use an external PostgreSQL server** and collect connection credentials before Step 2.
- **Use a managed database service** (AWS RDS, Azure Database for PostgreSQL, etc.).
## Step 2: Prepare the database
Follow the [database preparation](/deployment-guide/server/prepare-database) instructions to create the Mattermost database, user, and grants.
## Step 3: Download the Mattermost Server tarball
SSH onto the target host and download the release. Replace `amd64` with `arm64` for ARM-based hardware.
<Tabs>
<TabItem value="latest" label="Latest release" default>
```sh
wget https://releases.mattermost.com/11.10.2/mattermost-11.10.2-linux-amd64.tar.gz
```
</TabItem>
<TabItem value="esr" label="Current ESR">
```sh
wget https://releases.mattermost.com/11.7.11/mattermost-11.7.11-linux-amd64.tar.gz
```
</TabItem>
<TabItem value="archive" label="Older releases">
Enterprise and Team Edition releases are listed in the [version archive](/product-overview/version-archive).
</TabItem>
</Tabs>
## Step 4: Install Mattermost Server
Update existing system packages first:
```sh
sudo dnf update
sudo dnf upgrade
```
Extract the tarball, move it into place, and set ownership:
```sh
tar -xvzf mattermost*.gz
sudo mv mattermost /opt
sudo mkdir /opt/mattermost/data
sudo useradd --system --user-group mattermost
sudo chown -R mattermost:mattermost /opt/mattermost
sudo chmod -R g+w /opt/mattermost
```
<Note title="Custom paths and users">
If you use a path other than `/opt/mattermost` or a user/group name other than `mattermost`, use that name in every step that follows.
</Note>
Create the systemd unit file at `/etc/systemd/system/mattermost.service`:
<Note>
Earlier versions of this guide had you create the unit file under `/lib/systemd/system/`, which is reserved for unit files installed and owned by a package manager.
</Note>
```ini
[Unit]
Description=Mattermost
After=network.target
[Service]
Type=notify
ExecStart=/opt/mattermost/bin/mattermost
TimeoutStartSec=3600
KillMode=mixed
Restart=always
RestartSec=10
WorkingDirectory=/opt/mattermost
User=mattermost
Group=mattermost
LimitNOFILE=49152
[Install]
WantedBy=multi-user.target
```
Reload systemd:
```sh
sudo systemctl daemon-reload
```
## Step 5: Configure and start the server
Back up the default config before editing:
```sh
sudo cp /opt/mattermost/config/config.json /opt/mattermost/config/config.defaults.json
```
Edit `/opt/mattermost/config/config.json` and set:
- `SqlSettings.DriverName`: `"postgres"`
- `SqlSettings.DataSource`: `"postgres://mmuser:<mmuser-password>@<host>:5432/mattermost?sslmode=disable&connect_timeout=10"` — replace each placeholder.
- `ServiceSettings.SiteURL`: the public URL of your deployment (e.g., `https://mattermost.example.com`).
- (Recommended) [`SupportSettings.SupportEmail`](/administration-guide/configure/site-configuration-settings#support-email-address): the email address users contact for help.
Start the server:
```sh
sudo systemctl start mattermost
curl http://localhost:8065
```
You should see the Mattermost HTML response. Enable on boot:
```sh
sudo systemctl enable mattermost.service
```
If start fails on a hardened RHEL system, continue to the [Hardened RHEL configuration](#hardened-rhel-configuration) section below before troubleshooting elsewhere — it's almost always SELinux, firewalld, or fapolicyd.
## Step 6: Update the server
Tarball-based installs are upgraded manually. See [Upgrading Mattermost Server](/administration-guide/upgrade/upgrading-mattermost-server).
## Hardened RHEL configuration
Hardened RHEL installs typically require additional configuration for SELinux, firewalld, and fapolicyd. Each is covered below.
<Tabs>
<TabItem value="selinux" label="SELinux" default>
RHEL 9 ships with SELinux in enforcing mode. Verify with `sestatus`. If it's enforcing, set the appropriate contexts before starting Mattermost.
**Set the binary context** for `/opt/mattermost/bin`:
```sh
sudo semanage fcontext -a -t bin_t "/opt/mattermost/bin(/.*)?"
sudo restorecon -RF /opt/mattermost/bin
```
**Set the directory context** for `/opt/mattermost`. Check current context:
```sh
ls -Z /opt/mattermost
```
If the type is `default_t`, set a web-application context:
```sh
sudo semanage fcontext -a -t httpd_sys_content_t "/opt/mattermost(/.*)?"
sudo restorecon -R /opt/mattermost
```
**Allow Mattermost to bind to port 8065** (or your configured port):
```sh
sudo semanage port -l | grep 8065
sudo semanage port -a -t http_port_t -p tcp 8065
```
**Generate a custom policy** if SELinux blocks something specific. Check denials:
```sh
sudo ausearch -m avc -ts recent
sudo cat /var/log/audit/audit.log | grep denied
```
Generate a policy module from those denials:
```sh
sudo yum install -y policycoreutils-python-utils
sudo grep mattermost /var/log/audit/audit.log | audit2allow -M mattermost_policy
sudo semodule -i mattermost_policy.pp
```
**Restart and verify**:
```sh
sudo systemctl restart mattermost
```
<Tip title="Testing-only fallback">
For debugging, you can temporarily switch SELinux to permissive mode with `sudo setenforce 0`. Re-enable enforcement with `sudo setenforce 1` once contexts are correct. Don't ship a production deployment in permissive mode.
</Tip>
**References**
- [SELinux User's and Administrator's Guide](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/index)
- [SELinux Project Wiki](https://github.com/SELinuxProject/selinux)
</TabItem>
<TabItem value="firewalld" label="firewalld">
firewalld is the default firewall on RHEL. Check status:
```sh
sudo systemctl status firewalld
```
**Open the Mattermost ports**:
```sh
sudo firewall-cmd --permanent --add-port=8065/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
```
The output should show `8065/tcp` and the `http` / `https` services.
**Mattermost Calls ports** (if you're running the Calls plugin or the standalone rtcd service):
```sh
# Integrated Calls plugin
sudo firewall-cmd --permanent --add-port=8443/udp
sudo firewall-cmd --permanent --add-port=8443/tcp
sudo firewall-cmd --reload
# Standalone rtcd (adds API port)
sudo firewall-cmd --permanent --add-port=8045/tcp
sudo firewall-cmd --reload
```
- Port 8443 (UDP/TCP) carries RTC media (audio, video, screen share).
- Port 8045 (TCP) is the rtcd API.
- TCP support for RTC requires Calls v0.17+ and rtcd v0.11+.
See the [Calls deployment guide](/deployment-guide/calls/calls-deployment-guide) for the full topology.
</TabItem>
<TabItem value="fapolicyd" label="fapolicyd">
fapolicyd (File Access Policy Daemon) blocks execution of untrusted binaries. In secure RHEL environments it commonly blocks Mattermost binaries and plugins — the symptom is "operation not permitted" errors in `mattermost.log`.
**Confirm fapolicyd is the cause** by temporarily stopping it:
```sh
sudo systemctl stop fapolicyd
sudo systemctl start mattermost
```
If Mattermost now works, restart fapolicyd and configure an allow rule.
**Identify the denial**:
```sh
sudo fapolicyd --debug
```
Look for a line like:
```text
rule=15 dec=deny_audit perm=execute auid=-1 pid=19735
exe=/opt/mattermost/bin/mattermost : path=/opt/mattermost/plugins/focalboard/server/dist/plugin-linux-amd64
ftype=application/x-executable trust=0
```
Note the rule number — your allow rule must be numbered lower so it's evaluated first.
**Create an allow rule** at `/etc/fapolicyd/rules.d/80-mattermost.rules`:
```text
allow perm=execute exe=/usr/bin/sudo trust=1 : dir=/opt/mattermost/ all trust=0
allow perm=execute exe=/opt/mattermost/bin/mattermost : dir=/opt/mattermost all trust=0
allow perm=execute exe=/usr/lib/systemd/systemd trust=1 : dir=/opt/mattermost/ all trust=0
```
**Validate and load**:
```sh
sudo fagenrules --check
sudo fagenrules --load
sudo systemctl restart fapolicyd
sudo systemctl restart mattermost
```
Verify:
```sh
curl http://localhost:8065
sudo systemctl status mattermost
```
**Rules for the standalone rtcd service** (if deployed): create `/etc/fapolicyd/rules.d/80-rtcd.rules`:
```text
allow perm=execute exe=/usr/bin/sudo trust=1 : dir=/opt/rtcd/ all trust=0
allow perm=execute exe=/opt/rtcd/bin/rtcd : dir=/opt/rtcd all trust=0
allow perm=execute exe=/usr/lib/systemd/systemd trust=1 : dir=/opt/rtcd/ all trust=0
```
Then reload fapolicyd as above. See [RTCD Setup and Configuration](/deployment-guide/calls/calls-rtcd-setup) for the full rtcd install path.
<Note title="Rule numbering">
fapolicyd rules are evaluated in order. Your allow rules must be numbered lower than the deny rule that's blocking Mattermost — `80-` is usually safe with a stock configuration. If denials persist, re-check the rule number from `fapolicyd --debug` and renumber accordingly.
</Note>
**Reference**: [Mattermost and fapolicyd](https://support.mattermost.com/hc/en-us/articles/12167526545172-Mattermost-and-fapolicyd) support article.
</TabItem>
</Tabs>
## Remove Mattermost
Stop the server, back up any data you need, then remove the install directory:
```sh
sudo systemctl stop mattermost
sudo rm -rf /opt/mattermost
sudo rm /lib/systemd/system/mattermost.service
sudo userdel mattermost
```
<Important title="Back up before removing">
`/opt/mattermost` contains `config/`, `logs/`, `plugins/`, `client/plugins/`, and `data/`. Back these up before running `rm -rf` if you may need to restore.
</Important>
## Next steps
- [Set up an NGINX reverse proxy](/deployment-guide/server/setup-nginx-proxy)
- [Set up TLS](/deployment-guide/server/setup-tls)

View File

@@ -0,0 +1,200 @@
---
title: "Deploy Mattermost manually from the tarball"
sidebar_label: "Manual (tarball)"
---
<EditionAvailability tiers="free,professional,enterprise,enterprise-advanced" />
<DeploymentAvailability modes="self-hosted,air-gapped" />
Install Mattermost Server on any 64-bit Linux distribution directly from the release tarball. This is the most flexible install method and usually the choice for:
- Distributions Mattermost doesn't package directly (Arch, SUSE, Gentoo, Alpine, …)
- Air-gapped environments where tarballs are staged on an internal mirror
- Custom paths, users, or systemd unit configurations
- Environments where you control every version pin and don't want a package manager auto-upgrade
<Tip title="Use a packaged install if it fits">
If you're on **Ubuntu / Debian**, use the [APT-based install](./deploy-ubuntu) for automatic security updates. If you're on **RHEL / Rocky / Alma / Oracle**, use the [RHEL install](./deploy-rhel) — it covers SELinux, firewalld, and fapolicyd configuration too.
</Tip>
<Note title="Minimum requirements">
- **Operating system**: any 64-bit Linux distribution with `systemd` (or a comparable service manager).
- **Hardware**: 1 vCPU and 2 GB RAM (supports up to ~1,000 users).
- **Database**: [PostgreSQL 14+](/administration-guide/manage/admin/postgres-migration).
- **Network**: TCP 80/443 inbound (TLS), 8065 inbound (System Console), 10025 outbound (SMTP relay if used).
</Note>
## Step 1: Get a PostgreSQL database
Choose one of:
- **Install PostgreSQL locally** on the same host. See the [PostgreSQL installation documentation](https://www.postgresql.org/download/).
- **Use an external PostgreSQL server** and collect connection credentials before Step 2.
- **Use a managed database service** (AWS RDS, Azure Database for PostgreSQL, etc.).
## Step 2: Prepare the database
Follow the [database preparation](/deployment-guide/server/prepare-database) instructions to create the Mattermost database, user, and grants.
## Step 3: Download the Mattermost Server tarball
SSH onto the target host and download the release. Replace `amd64` with `arm64` for ARM-based hardware.
<Tabs>
<TabItem value="latest" label="Latest release" default>
```sh
wget https://releases.mattermost.com/11.10.2/mattermost-11.10.2-linux-amd64.tar.gz
```
</TabItem>
<TabItem value="esr" label="Current ESR">
```sh
wget https://releases.mattermost.com/11.7.11/mattermost-11.7.11-linux-amd64.tar.gz
```
</TabItem>
<TabItem value="archive" label="Older releases">
Enterprise and Team Edition releases are listed in the [version archive](/product-overview/version-archive).
</TabItem>
</Tabs>
<Note title="Air-gapped installs">
In an air-gapped environment, stage the tarball on your operator workstation, verify the SHA-256 and PGP signature, then transfer it across the boundary. See the [air-gapped deployment runbook](/deployment-guide/air-gapped-operations/quick-start-runbook) for the full procedure.
</Note>
## Step 4: Install Mattermost Server
Extract the tarball, move it into place, and set ownership.
```sh
tar -xvzf mattermost*.gz
sudo mv mattermost /opt
sudo mkdir /opt/mattermost/data
sudo useradd --system --user-group mattermost
sudo chown -R mattermost:mattermost /opt/mattermost
sudo chmod -R g+w /opt/mattermost
```
<Note title="Custom paths and users">
If you use a path other than `/opt/mattermost` or a user/group name other than `mattermost`, use that name in every step that follows.
</Note>
Create the systemd unit file at `/etc/systemd/system/mattermost.service`:
<Note>
Earlier versions of this guide had you create the unit file under `/lib/systemd/system/`, which is reserved for unit files installed and owned by a package manager.
</Note>
```ini
[Unit]
Description=Mattermost
After=network.target
[Service]
Type=notify
ExecStart=/opt/mattermost/bin/mattermost
TimeoutStartSec=3600
KillMode=mixed
Restart=always
RestartSec=10
WorkingDirectory=/opt/mattermost
User=mattermost
Group=mattermost
LimitNOFILE=49152
[Install]
WantedBy=multi-user.target
```
<Note title="Local database">
If PostgreSQL is on the same host, add to the `[Unit]` section so Mattermost won't start before the database is ready:
```ini
After=postgresql.service
BindsTo=postgresql.service
```
</Note>
Reload systemd:
```sh
sudo systemctl daemon-reload
```
## Step 5: Configure and start the server
Back up the default config before editing:
```sh
sudo cp /opt/mattermost/config/config.json /opt/mattermost/config/config.defaults.json
```
Edit `/opt/mattermost/config/config.json` and set:
- `SqlSettings.DriverName`: `"postgres"`
- `SqlSettings.DataSource`: `"postgres://mmuser:<mmuser-password>@<host>:5432/mattermost?sslmode=disable&connect_timeout=10"` — replace each placeholder.
- `ServiceSettings.SiteURL`: the public URL of your deployment (e.g., `https://mattermost.example.com`).
- (Recommended) [`SupportSettings.SupportEmail`](/administration-guide/configure/site-configuration-settings#support-email-address): the email address users contact for help.
Start the server:
```sh
sudo systemctl start mattermost
curl http://localhost:8065
```
You should see the Mattermost HTML response. Enable on boot:
```sh
sudo systemctl enable mattermost.service
```
## Step 6: Update the server
Tarball installs are upgraded manually — there's no package manager to pull the new version. See [Upgrading Mattermost Server](/administration-guide/upgrade/upgrading-mattermost-server) for the step-by-step procedure. The summary:
1. Stop the running server (`sudo systemctl stop mattermost`).
2. Back up `config/`, `data/`, `plugins/`, and your PostgreSQL database.
3. Download the new tarball.
4. Extract over the install directory (preserving `config/`, `data/`, `plugins/`).
5. Reset ownership and permissions.
6. Start the server.
## Remove Mattermost
Stop the server, back up data you need to keep, then remove the install:
```sh
sudo systemctl stop mattermost
sudo rm -rf /opt/mattermost
sudo rm /lib/systemd/system/mattermost.service
sudo userdel mattermost
```
<Important title="Back up before removing">
`/opt/mattermost` contains `config/`, `logs/`, `plugins/`, `client/plugins/`, and `data/`. Back these up before running `rm -rf` if you may need to restore.
</Important>
## Next steps
- [Set up an NGINX reverse proxy](/deployment-guide/server/setup-nginx-proxy)
- [Set up TLS](/deployment-guide/server/setup-tls)
- For air-gapped deployments: [Air-gapped deployment runbook](/deployment-guide/air-gapped-operations/quick-start-runbook), [Configure for Air-Gapped Operation](/deployment-guide/air-gapped-operations/disable-phone-home-features)

View File

@@ -0,0 +1,144 @@
---
title: "Deploy Mattermost on Ubuntu or Debian"
sidebar_label: "Ubuntu / Debian"
---
<EditionAvailability tiers="free,professional,enterprise,enterprise-advanced" />
<DeploymentAvailability modes="self-hosted" />
Install Mattermost Server on Ubuntu or Debian from the signed Mattermost APT repository. The same `.deb` packages cover single-host installs and clustered deployments via tools like Packer.
:::info[Minimum requirements]
- **Operating system**: Ubuntu 20.04 / 22.04 / 24.04 LTS, or Debian (current stable). Other Debian-family distributions usually work but aren't tested by Mattermost.
- **Hardware**: 1 vCPU and 2 GB RAM (supports up to ~1,000 users).
- **Database**: [PostgreSQL 14+](/administration-guide/manage/admin/postgres-migration).
- **Network**: TCP 80/443 inbound (TLS), 8065 inbound (System Console), 10025 outbound (SMTP relay if used).
:::
## Step 1: Get a PostgreSQL database
Mattermost requires PostgreSQL. Choose one of:
- **Install PostgreSQL locally** on the same host. Follow the [PostgreSQL installation documentation](https://www.postgresql.org/download/).
- **Use an external PostgreSQL server**. Collect the connection credentials (hostname, port, database, username, password) before starting Step 2.
- **Use a managed database service** (AWS RDS, Azure Database for PostgreSQL, etc.).
## Step 2: Prepare the database
Follow the [database preparation](/deployment-guide/server/prepare-database) instructions to create the Mattermost database, user, and grants.
## Step 3: Add the Mattermost APT repository
:::important[GPG key change]
The GPG public key has changed. Either [import the new public key](https://deb.packages.mattermost.com/pubkey.gpg) or run the repository setup script in the next step (recommended). Existing installations should remove the old key before adding the new one:
For Ubuntu 22.04 LTS and 24.04 LTS:
```sh
sudo rm /usr/share/keyrings/mattermost-archive-keyring.gpg
curl -sL -o- https://deb.packages.mattermost.com/pubkey.gpg \
| gpg --dearmor \
| sudo tee /usr/share/keyrings/mattermost-archive-keyring.gpg > /dev/null
```
:::
Run the repository setup script:
```sh
curl -o- https://deb.packages.mattermost.com/repo-setup.sh | sudo bash -s mattermost
```
This configures the Mattermost APT repository, a PostgreSQL repository, an NGINX web server (used as a reverse proxy), and certbot for issuing and renewing SSL certificates.
## Step 4: Install Mattermost Server
Update your APT cache and any pending system packages:
```sh
sudo apt update
```
Install the latest Mattermost Server:
```sh
sudo apt install mattermost -y
```
Mattermost installs to `/opt/mattermost`. The package creates a `mattermost` user and group and a systemd unit file. The service is **not** enabled or started at this point.
:::note[systemd dependencies]
The Mattermost package doesn't declare a database dependency in its systemd unit (the package is used for both single-host and external-database installs). If you installed PostgreSQL on the same host, add the following to the `[Unit]` section of `/lib/systemd/system/mattermost.service`:
```ini
After=postgresql.service
BindsTo=postgresql.service
```
:::
## Step 5: Configure the server
Copy the default configuration to the active config file with the right ownership and permissions:
```sh
sudo install -C -m 600 -o mattermost -g mattermost \
/opt/mattermost/config/config.defaults.json \
/opt/mattermost/config/config.json
```
Edit `/opt/mattermost/config/config.json` and set:
- `SqlSettings.DriverName`: `"postgres"`
- `SqlSettings.DataSource`: `"postgres://mmuser:<mmuser-password>@<host>:5432/mattermost?sslmode=disable&connect_timeout=10"` — replace each placeholder.
- `ServiceSettings.SiteURL`: the public URL of your deployment (e.g., `https://mattermost.example.com`).
- (Recommended) [`SupportSettings.SupportEmail`](/administration-guide/configure/site-configuration-settings#support-email-address): the email address users contact for help.
:::note[TLS mode for `DataSource`]
The `sslmode` value depends on your database environment. The two relevant options are `disable` and `require`. Managed services such as AWS Lightsail require `sslmode=require`. Check your provider's documentation.
:::
Start the server:
```sh
sudo systemctl start mattermost
```
Verify it's running:
```sh
curl http://localhost:8065
```
You should see the Mattermost HTML response. Enable the service on boot:
```sh
sudo systemctl enable mattermost.service
```
## Step 6: Update Mattermost
When a new release is published, update through APT:
```sh
sudo systemctl stop mattermost
sudo apt update && sudo apt upgrade
sudo systemctl start mattermost
```
:::important[Stop the server before upgrading]
`apt upgrade` will replace the Mattermost binary while it's running. Stop the systemd service first to avoid corrupt state.
:::
## Remove Mattermost
```sh
sudo systemctl stop mattermost
sudo apt remove --purge mattermost
```
This removes the package but leaves `/opt/mattermost/data`, `/opt/mattermost/logs`, `/opt/mattermost/plugins`, and `/opt/mattermost/config` in place. Back these up before deleting if you may need to restore.
## Next steps
- [Set up an NGINX reverse proxy](/deployment-guide/server/setup-nginx-proxy)
- [Set up TLS](/deployment-guide/server/setup-tls)
- [Configure Mattermost](/administration-guide/configure/configure-index) and [onboard your users](/administration-guide/onboard/onboard-index)

View File

@@ -0,0 +1,157 @@
---
title: "Pre-authentication secrets"
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<PlanAvailability slug="ent-adv" />
From Mattermost server v10.12 and mobile v2.32, Mattermost deployments can use a reverse proxy to validate authentication secrets before allowing desktop and mobile requests to reach the Mattermost server. This adds an additional security layer by checking for the `X-Mattermost-Preauth-Secret` header.
Authentication secrets are only supported for mobile and desktop applications. When a secret is required, desktop prompts users directly while mobile displays the secret field in Advanced Options. Web browser clients don't support this feature.
When authentication secret validation fails, the reverse proxy must return the `X-Reject-Reason: pre-auth` header along with the 403 status code. This header allows mobile and desktop applications to specifically identify authentication failures and provide appropriate error messaging to users.
<Important>
We recommend whitelisting certain endpoints where the authentication header may not be available. The specific endpoints depend on your authentication configuration:
- `/api/v4/notifications/ack` - Required for proper notification acknowledgement functionality
- `/static/*`, `/api/v4/config/client` and `/login/desktop` - Required for authentication flows that redirect to the browser, such as SAML, OAuth and OpenID
**Additional endpoints based on your authentication setup:**
- SAML: `/login/sso/saml`
- OpenID: `/oauth/&#123;service:[A-Za-z0-9]+&#125;/complete`, `/oauth/&#123;service:[A-Za-z0-9]+&#125;/login`, `/oauth/&#123;service:[A-Za-z0-9]+&#125;/mobile_login`, `/oauth/&#123;service:[A-Za-z0-9]+&#125;/signup`
- OAuth: `/api/v3/oauth/&#123;service:[A-Za-z0-9]+&#125;/complete`, `/signup/&#123;service:[A-Za-z0-9]+&#125;/complete`, `/login/&#123;service:[A-Za-z0-9]+&#125;/complete`
These endpoints are whitelisted because they're accessed during authentication flows where the authentication header can't be provided, such as OAuth redirects through external identity providers.
</Important>
## NGINX configuration example
Here's an example partial NGINX configuration that validates the authentication secret header:
``` text
server {
# ...
# Define the expected auth secret
set $expected_secret "your-secure-auth-secret-here";
# Whitelist endpoints where auth secret may not be available
location = /api/v4/notifications/ack {
# Pass through without verifying auth secret validation
# ...
}
location = /api/v4/config/client {
# Pass through without verifying auth secret validation
# ...
}
location = /login/desktop {
# Pass through without verifying auth secret validation
# ...
}
location ^~ /static/ {
# Pass through without verifying auth secret validation
# ...
}
# Additional whitelisted endpoints based on authentication configuration
# Uncomment and configure as needed for your setup:
# Note: Replace {service:[A-Za-z0-9]+} with your specific service names
# (e.g., google, gitlab, openid, office365) or use the regex pattern for multiple services
# SAML
# location = /login/sso/saml {
# # ...
# }
# OpenID/OAuth patterns (use regex for multiple services)
# location ~ ^/oauth/[A-Za-z0-9]+/(complete|login|mobile_login|signup)$ {
# # ...
# }
# Or for specific services:
# location ~ ^/oauth/(google|gitlab|office365)/(complete|login|mobile_login|signup)$ {
# # ...
# }
# location ~ ^/api/v3/oauth/[A-Za-z0-9]+/complete$ {
# # ...
# }
# location ~ ^/(signup|login)/[A-Za-z0-9]+/complete$ {
# # ...
# }
location / {
# Check if X-Mattermost-Preauth-Secret header matches expected value
if ($http_x_mattermost_preauth_secret != $expected_secret) {
add_header X-Reject-Reason pre-auth always;
add_header Cache-Control "no-store" always;
return 403 "Forbidden: Invalid pre-authentication secret";
}
# ...
}
}
```
Replace `your-secure-auth-secret-here` with a strong, unique secret that will be configured in your mobile and desktop applications. Store this secret securely and rotate it regularly as part of your security practices.
For Apache2 configuration guidance, see [Configuring Apache2 as a proxy for Mattermost Server](https://support.mattermost.com/hc/en-us/articles/41170740463764-Configuring-Apache2-as-a-proxy-for-Mattermost-Server-Unofficial).
## Rotate secrets
To rotate an authentication secret:
1. Generate a new secret: `openssl rand -base64 32`.
2. Update your reverse proxy configuration with the new secret.
3. Reload the reverse proxy.
4. Notify users:
> - **Desktop users**: No action needed. They'll be automatically prompted for the new secret on their next connection attempt.
> - **Mobile users**: Manually update the secret by editing the server in the app by tapping **Servers**, swiping left, tapping **Edit \> Advanced Options** and updating the **Authentication secret**.
## Security considerations
<Tabs>
<TabItem value="desktop" label="Desktop">
The Mattermost desktop application stores authentication secrets using Electron's `safeStorage` API, which integrates with the operating system's secure credential storage:
- **Windows**: Windows Credential Manager
- **macOS**: Keychain Access
- **Linux**: Secret Service API (requires kwallet, gnome-libsecret, or compatible backend)
For more information about Electron's secure storage behavior, see the [Electron safeStorage documentation](https://www.electronjs.org/docs/latest/api/safe-storage).
<Warning>
On Linux systems where no secure credential storage is available, the authentication secret may be stored in **plain text**. This occurs when:
- No secret store backend is available (kwallet, gnome-libsecret, etc.)
- The desktop environment is not recognized
- The system falls back to Electron's `basic_text` storage
The file is stored with permissions to prevent unauthorized access by other users, though the secret remains unencrypted. Consider the security implications before deploying authentication secrets in your environment.
</Warning>
</TabItem>
<TabItem value="mobile" label="Mobile">
The Mattermost mobile application stores authentication secrets using platform-native secure storage:
- **iOS**: iOS Keychain
- **Android**: Android Keystore system
Mobile authentication secrets are always encrypted. Unlike desktop Linux systems, there is no plaintext fallback on mobile platforms.
The authentication secret is included in all network requests, including REST API calls, WebSocket connections, and requests from share extensions and notification handlers.
</TabItem>
</Tabs>

View File

@@ -0,0 +1,45 @@
---
title: "Prepare your Mattermost Server environment"
---
Everything in this section has to exist before you run the installer. The database, file storage, and network access are hard prerequisites, because the install fails or the server won't start without them. The reverse proxy and TLS are prerequisites for a production deployment specifically: don't expose Mattermost to users without them.
Work through the pages in order. If you haven't sized the deployment yet, start with [Plan](/deployment-guide/server/server-deployment-planning) and confirm your hosts against the [software and hardware requirements](/deployment-guide/software-hardware-requirements) first.
<CardGrid columns={3} cards={[
{
title: 'Set up the database',
description: 'Create the PostgreSQL database, user, and grants, and allow remote connections if the database runs on its own host. PostgreSQL v14+ is required.',
to: '/deployment-guide/server/prepare-database',
},
{
title: 'Set up file storage',
description: 'Choose S3-compatible object storage, network file storage, or local storage for user files and attachments, and provision it.',
to: '/deployment-guide/server/prepare-file-storage',
},
{
title: 'Prepare your network',
description: 'The ports and protocols Mattermost needs in each direction, and how to route outbound traffic through a proxy.',
to: '/deployment-guide/server/prepare-network',
},
]} />
## Prepare for production
The pages above get a server running. These make it safe to put in front of users:
- [Set up an NGINX proxy](/deployment-guide/server/setup-nginx-proxy) - Configure NGINX as a reverse proxy for enhanced security and performance. Recommended for all production deployments.
- [Set up TLS](/deployment-guide/server/setup-tls) - Enable secure communication with SSL/TLS encryption, terminated at the proxy.
- [Use an image proxy](/deployment-guide/server/image-proxy) - Load external images through a proxy so third-party servers can't track who viewed them.
- [Set pre-authentication secrets](/deployment-guide/server/pre-authentication-secrets) - Require a shared secret before clients can reach the server.
Running an existing MySQL deployment? See [Set up the Mattermost MySQL database](/deployment-guide/server/prepare-mattermost-mysql-database). MySQL support is being removed in Mattermost v11, so new deployments must use PostgreSQL.
## Next steps
Once the prerequisites are in place, choose your install method:
- [Deploy with Kubernetes](/deployment-guide/server/deploy-kubernetes)
- [Deploy on Linux](/deployment-guide/server/deploy-linux)
- [Deploy with Containers](/deployment-guide/server/deploy-containers)
The trade-offs between the three are compared in [Deploy the Mattermost server](/deployment-guide/server/deploy-server#deployment-options).

View File

@@ -0,0 +1,146 @@
---
title: "Set up the Mattermost PostgreSQL database"
sidebar_label: "Set up the database"
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
PostgreSQL v14+ is required for Mattermost server installations. Create the database, user, and grants before you install Mattermost Server, so the installer has something to connect to.
You can run PostgreSQL on the same host as Mattermost, on a separate server, or as a managed service such as Amazon RDS or Azure Database for PostgreSQL. See the [database software](/deployment-guide/software-hardware-requirements#database-software) documentation for the supported versions and the minimum version policy.
<Note>
[MySQL database support](/deployment-guide/server/prepare-mattermost-mysql-database) is being deprecated starting with Mattermost v11. See the [PostgreSQL migration](/administration-guide/manage/admin/postgres-migration) documentation for guidance on migrating from MySQL to PostgreSQL.
</Note>
## Create the database and user
1. Create an PostgreSQL server instance. See the [PostgreSQL documentation](https://www.postgresql.org/download/) for details. When the installation is complete, the PostgreSQL server is running, and a Linux user account called postgres has been created.
2. Create the Mattermost database and user:
1. Access PostgreSQL by running:
``` sh
sudo -u postgres psql
```
2. Create the database:
``` sql
CREATE DATABASE mattermost WITH ENCODING 'UTF8' LC_COLLATE='en_US.UTF-8' LC_CTYPE='en_US.UTF-8' TEMPLATE=template0;
```
If this steps fails with an error message like `invalid LC_COLLATE locale name: "en_US.UTF-8"`, you need to generate the locale first using `locale-gen en_US.UTF-8`.
3. Create the Mattermost user with a secure password:
``` sql
CREATE USER mmuser WITH PASSWORD 'mmuser-password';
```
4. Grant database access to the user:
``` sql
GRANT ALL PRIVILEGES ON DATABASE mattermost to mmuser;
```
5. If using PostgreSQL v15.x or later, additional grants are required:
``` text
ALTER DATABASE mattermost OWNER TO mmuser;
-- Connect to the mattermost database so the schema grants below apply to the right schema
\c mattermost
ALTER SCHEMA public OWNER TO mmuser;
GRANT USAGE, CREATE ON SCHEMA public TO mmuser;
```
## Allow remote connections
Complete this section only if the database runs on a different host from Mattermost Server. A database local to the application host needs no additional configuration.
1. Edit `postgresql.conf` to allow remote connections:
<Tabs>
<TabItem value="ubuntu-debian" label="Ubuntu/Debian">
Edit `/etc/postgresql/&#123;version&#125;/main/postgresql.conf`:
``` text
listen_addresses = '*'
```
</TabItem>
<TabItem value="rhel-centos" label="RHEL/CentOS">
Edit `/var/lib/pgsql/&#123;version&#125;/data/postgresql.conf`:
``` text
listen_addresses = '*'
```
</TabItem>
</Tabs>
2. Configure client authentication by editing `pg_hba.conf`.
Add the following line, replacing `&#123;mattermost-server-IP&#125;`:
``` text
host all all {mattermost-server-IP}/32 md5
```
Restrict the source to the Mattermost server's address rather than a wider range, so the database only accepts connections from the application layer.
3. Restart the PostgreSQL service to apply the configuration changes:
``` sh
sudo systemctl restart postgresql
```
<Important>
If you are upgrading a major version of PostgreSQL, see [Upgrade PostgreSQL](/administration-guide/upgrade/upgrading-postgres) for the full upgrade procedure and post-upgrade steps.
</Important>
## Troubleshooting
### Mattermost can't use a fresh PostgreSQL v15 installation
PostgreSQL v15 introduces changes that may affect compatibility with previous releases. If you're deploying a fresh installation of PostgreSQL v15 and Mattermost can't create its schema, run this command to ensure that you can use Mattermost:
``` sql
GRANT CREATE ON SCHEMA public TO PUBLIC;
```
### Full-text search doesn't use indexes with a non-English `default_text_search_config`
Mattermost uses `default_text_search_config` for full-text search in PostgreSQL databases, as opposed to a hardcoded text search config. However, indexes are still created with a hardcoded text search config (english) and as a result, full-text search may never use the indexes.
Some of the tables in Mattermost, like `Posts` or `Users`, contain GIN indexes to improve the database full-text search feature in PostgreSQL.
These indexes need to be built against a specific language, and when they're created they're hard-coded to English. Full-text search queries are always performed using the `default_text_search_config` database setting. In order for the full-text search feature to leverage the indexes, the language specified in the query needs to match the language specified in the index.
If the `default_text_search_config` is not set to `english`, the GIN indexes will not be used. Database administrators can work around this by dropping the specific GIN index they're interested in and rebuilding it with the value of `default_text_search_config`.
For example, if the default language of your server is Spanish:
``` sql
-- Create the new index with a new name before dropping the old one
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_message_txt_spanish ON posts USING gin(to_tsvector('spanish', message));
-- Check that the new index does work. If it does, drop the old one and rename the new one:
DROP INDEX CONCURRENTLY IF EXISTS idx_posts_message_txt;
ALTER INDEX idx_posts_message_txt_spanish RENAME TO idx_posts_message_txt;
```
### Change the PostgreSQL username and password
We recommend changing the PostgreSQL username and password in the `.env` file.
## Next steps
Once the database is ready, continue with the rest of the [preparation checklist](/deployment-guide/server/preparations), or go straight to your install method: [Kubernetes](/deployment-guide/server/deploy-kubernetes), [Linux](/deployment-guide/server/deploy-linux), or [containers](/deployment-guide/server/deploy-containers).

View File

@@ -0,0 +1,61 @@
---
title: "Set up file storage"
sidebar_label: "Set up file storage"
---
Mattermost requires a file storage system for storing user files, images, and attachments. Choose one of the following before you install, because moving between them later means migrating existing files:
- S3-compatible object storage (recommended)
- Network file storage
- Local file storage
For guidance on how much storage to provision, see [backing storage benchmarks](/deployment-guide/scale/backing-storage-benchmarks).
## S3-compatible object storage (Recommended)
For production environments, we recommend using S3-compatible object storage such as:
- Amazon S3
- Digital Ocean Spaces
- Other S3-compatible services
When using S3 storage, you'll need:
1. A bucket created specifically for Mattermost
2. Access credentials (Access Key and Secret Key)
3. Appropriate bucket policies configured
4. The following information for configuration:
- Bucket name
- Region (if applicable)
- Access Key
- Secret Key
- Endpoint URL (for non-AWS S3 services)
You configure these values in **System Console > Environment > File Storage**. See the [file storage configuration settings](/administration-guide/configure/environment-configuration-settings#file-storage) documentation for details.
## Network file storage
For production environments that cannot use S3-compatible object storage, we recommend using a Network Addressable Storage (NAS) solution with Network File System (NFS).
You'll need to prepare an NFS server with a dedicated share for Mattermost (e.g. <code>/mnt/mattermost_data</code>) and mount it on all servers that will be running Mattermost.
## Local file storage
For simple deployments, you can use local file storage. However, we don't recommend this for production environments or multi-node deployments, because the files aren't shared between application servers and aren't covered by a separate backup target.
1. Create a directory for file storage:
``` sh
sudo mkdir -p /opt/mattermost/data
```
2. Set appropriate permissions:
``` sh
sudo chown -R mattermost:mattermost /opt/mattermost/data
```
## Next steps
- [Use an image proxy](/deployment-guide/server/image-proxy) to keep clients from contacting third-party servers directly when they load external images.
- Set your [encryption at rest](/deployment-guide/encryption-options) approach for whichever storage system you chose.
- Return to the [preparation checklist](/deployment-guide/server/preparations).

View File

@@ -0,0 +1,304 @@
---
title: "Set up the Mattermost MySQL database"
unlisted: true
---
import useBaseUrl from '@docusaurus/useBaseUrl';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
------------------------------------------------------------------------------------------------------------------------
<PlanAvailability slug="ent-plus" />
<Important>
- From Mattermost v11, Mattermost completely stops support MySQL as a database driver. MySQL support has been completely removed from the codebase, and the product will throw an invalid configuration error.
- PostgreSQL is our preferred database of choice. See the [database software](/deployment-guide/software-hardware-requirements#database-software) documentation for details on database version support, and see the [Migrate from MySQL to PostgreSQL](/administration-guide/manage/admin/postgres-migration) documentation for details on migrating from MySQL to PostgreSQL.
- MySQL 8.0.22 contains an [issue with JSON column types](https://bugs.mysql.com/bug.php?id=101284) changing string values to integers which is preventing Mattermost from working properly. Users are advised to avoid this database version.
</Important>
To set up a MySQL database for use by the Mattermost server:
1. Log into the server that will host the database, ands install MySQL.
2. Log in to MySQL as *root* by running `sudo mysql`.
3. Create the Mattermost user *mmuser* by running `mysql> create user 'mmuser'@'%' identified by 'mmuser-password';`.
> - Use a password that is more secure than `mmuser-password`.
> - The `%` means that `mmuser` can connect from any machine on the network. However, it's more secure to use the IP address of the machine that hosts Mattermost. For example, if you install Mattermost on the machine with IP address `10.10.10.2`, then use the following command: `mysql> create user 'mmuser'@'10.10.10.2' identified by 'mmuser-password';`
4. Create the Mattermost database by running `mysql> create database mattermost;`.
5. Grant access privileges to the user `mmuser` by running `mysql> grant all privileges on mattermost.* to 'mmuser'@'%';`.
> <div class="note">
>
> <div class="title">
>
> Note
>
> </div>
>
> This query grants the MySQL user we just created all privileges on the database for convenience. If you need more security, use the following query to grant the user only the privileges necessary to run Mattermost: `mysql> GRANT ALTER, CREATE, DELETE, DROP, INDEX, INSERT, SELECT, UPDATE, REFERENCES ON mattermost.* TO 'mmuser'@'%';`
>
> </div>
6. Log out of MySQL by running `mysql> exit`. Once the database is installed and the initial setup is complete, you can install the Mattermost server.
<Note>
If you have installed MySQL on its own server, edit the `/etc/mysql/mysql.conf.d/mysqld.cnf` file and comment out the `bind-address = 127.0.0.1` using the `#` symbol, then restart your database server.
</Note>
# Back up the database
Back up your Mattermost database using standard procedures depending on your database version. MySQL backup documentation \[https://dev.mysql.com/doc/refman/8.4/en/backup-types.html\](https://dev.mysql.com/doc/refman/8.4/en/backup-types.html\)\`\_ is available online. Use the selector on the page to choose your MySQL version.
# Upgrade Mattermost
<Tabs>
<TabItem value="upgrade-to-v7-1" label="Upgrade to v7.1">
Mattermost v7.1 introduces schema changes in the form of a new column and its index. Our test results for the schema changes include: 12M Posts, 2.5M Reactions - ~1min 34s (instance: PC with 8 cores, 16GB RAM).
You can run the following SQL queries before the upgrade that obtains a lock on `Reactions` table.
`ALTER TABLE Reactions ADD COLUMN ChannelId varchar(26) NOT NULL DEFAULT "";`
`UPDATE Reactions SET ChannelId = COALESCE((select ChannelId from Posts where Posts.Id = Reactions.PostId), '') WHERE ChannelId="";`
`CREATE INDEX idx_reactions_channel_id ON Reactions(ChannelId) LOCK=NONE;`
Users' reactions posted during this time won't be reflected in the database until the migrations are complete. This is fully backwards-compatible.
If your connection collation and table collations are different, this can result in the error <code>Illegal mix of collations</code>. To resolve this error, set the same collation for both the connection and the table. There are different collations at different levels - connection, database, table, column, and database administrators may choose to set different collation levels for different objects.
</TabItem>
<TabItem value="upgrade-to-v7-0" label="Upgrade to v7.0">
Self-hosted Mattermost customers using MySQL databases may notice the migration to release v7.0 taking longer than usual when there are a large number of rows in the `FileInfo` table. See the [important upgrade notes](/administration-guide/upgrade/important-upgrade-notes) documentation for details.
</TabItem>
<TabItem value="upgrade-to-v6-7" label="Upgrade to v6.7">
Mattermost v6.7 introduces schema changes in the form of a new index. The following notes our test results for the schema changes:
- 7M Posts - ~17s (instance: db.r5.xlarge)
- 9M Posts - 2min 12s (instance: db.r5.large)
If you want a zero downtime upgrade, you can apply this index prior to doing the upgrade:
`CREATE INDEX idx_posts_create_at_id on Posts(CreateAt, Id) LOCK=NONE;`
This is fully backwards-compatible and will not acquire any table lock or affect any existing operations on the table.
</TabItem>
<TabItem value="v6-0-database-schema-migrations" label="v6.0 database schema migrations">
The release of v6.0 introduces database schema changes and longer migration times should be expected, especially on MySQL installations.
Mattermost v6.0 introduces several database schema changes to improve both database and application performance. The upgrade will run significant database schema changes that can cause an extended startup time depending on the dataset size. We've conducted extensive tests on supported MySQL database drivers, using realistic datasets of more than 10 million posts and more than 72 million posts.
A migration to v6.0 of 10+ million posts will take approximately 1 hour and 22 minutes to complete for a MySQL database.
A large migration from v5.39 to v6.0 of 72+ million posts will take approximately 3 hours and 40 minutes to complete for a MySQL database. See the [Migration results analysis](https://gist.github.com/streamer45/868c451164f6e8069d8b398685a31b6e) documentation for test specifications, data sizes, and test results.
The following queries, executed during the migration process on an environment with 10+ million posts, will have a significant impact on database CPU usage and write operation restrictions for the duration of the query:
`ALTER TABLE Posts MODIFY Props JSON;` (~26 minutes)
`ALTER TABLE Posts DROP COLUMN ParentId;` (~26 minutes)
`ALTER TABLE Posts MODIFY COLUMN FileIds text;` (~26 minutes)
See the [Mattermost v6.0 DB schema migrations analysis](https://gist.github.com/streamer45/59b3582118913d4fc5e8ff81ea78b055) documentation for test specifications, data sizes, test results, and a complete breakdown of MySQL queries, as well as their impact and duration.
# MySQL Mitigation Strategies
Run combined queries prior to the upgrade. The previous queries can be combined when run prior to the upgrade as follows:
`ALTER TABLE Posts MODIFY COLUMN FileIds text, MODIFY COLUMN Props JSON;`
This limits the time taken to that of a single query of that type.
**Online migration**: An online migration that avoids locking can be attempted on MySQL installations, especially for particularly heavy queries or very big datasets (tens of millions of posts or more). This can be done through an external tool like [pt-online-schema-change](https://docs.percona.com/percona-toolkit/pt-online-schema-change.html). However, the online migration process can cause a significant spike in CPU usage on the database instance it runs.
See the [Mattermost v6.0 DB schema migrations analysis](https://gist.github.com/streamer45/59b3582118913d4fc5e8ff81ea78b055#online-migration-mysql) documentation for a sample execution and additional caveats.
</TabItem>
</Tabs>
# High availabiilty configuration setting recommendations
For MySQL, we recommend the following configuration options for high performance:
- `innodb_buffer_pool_size`: Set to ~70% of your total RAM.
- `innodb_log_file_size`: Set to 256 MB. Increasing this helps in write intensive operations. Recovery times will be longer.
- `innodb_flush_log_at_trx_commit`: 2. This can potentially cause up to one second of loss of transaction data.
- `max_heap_table_size`: 64 MB.
- `tmp_table_size`: 64 MB.
# Encryption-at-rest
Encryption-at-rest is available for messages via hardware and software disk encryption solutions applied to the Mattermost database, which resides on its own server within your infrastructure. See the [MySQL](https://www.percona.com/blog/mysql-data-at-rest-encryption/) database documentation for details on encryption options at the disk level.
# Use sockets for the database
``` sh
mysql -u root -p
```
``` sql
CREATE DATABASE mattermostdb;
CREATE USER mmuser IDENTIFIED BY 'mmuser_password';
GRANT ALL ON mattermostdb.* TO mmuser;
```
Mattermost is configured in `/etc/webapps/mattermost/config.json`, and strings need to be quoted.
- set `DriverName` to `mysql`.
- set `DataSource` to `mmuser:mmuser_password@unix(/run/mysqld/mysqld.sock)/mattermostdb?charset=utf8mb4,utf8`.
# Mattermost configuration in the database
You can use the database as the single source of truth for the active configuration of your Mattermost installation. This changes the Mattermost binary from reading the default `config.json` file to reading the configuration settings stored within a configuration table in the database.
``` text
mysql://mmuser:really_secure_password@tcp(127.0.0.1:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s
```
## Create an environment file
<Note>
If you're running Mattermost in a High Availability cluster-based deployment, this step must be done on all servers in the cluster.
</Note>
Create the file `/opt/mattermost/config/mattermost.environment` to set the `MM_CONFIG` environment variable to the database connection string. For example:
``` text
MM_CONFIG='mysql://mmuser:mostest_password@tcp(127.0.0.1:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s'
```
<Note>
Be sure to escape any single quotes in the database connection string by placing a `\` in front of them like this `\'`. For example: `MM_CONFIG='mysql://mmuser:it\'s-a-password!@tcp(127.0.0.1:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s'`
</Note>
``` text
MM_CONFIG='mysql://mmuser:it\'s-a-password!@tcp(127.0.0.1:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s'
```
Finally, run this command to verify the permissions on your Mattermost directory:
``` sh
sudo chown -R mattermost:mattermost /opt/mattermost
```
## Modify the Mattermost `systemd` file
First, find the `mattermost.service` file using:
``` sh
sudo systemctl status mattermost.service
```
The second line of output will have the location of the running `mattermost.service`.
``` text
Loaded: loaded (/etc/systemd/system/mattermost.service; enabled; vendor preset: enabled)
```
Edit this file as *root* to add the below text just above the line that begins with `ExecStart`:
``` text
EnvironmentFile=/opt/mattermost/config/mattermost.environment
```
Here's a complete `mattermost.service` file with the `EnvironmentFile` line added:
``` text
[Unit]
Description=Mattermost
After=network.target
After=mysql.service
Requires=mysql.service
[Service]
Type=notify
EnvironmentFile=/opt/mattermost/config/mattermost.environment
ExecStart=/opt/mattermost/bin/mattermost
TimeoutStartSec=3600
KillMode=mixed
Restart=always
RestartSec=10
WorkingDirectory=/opt/mattermost
User=mattermost
Group=mattermost
LimitNOFILE=49152
[Install]
WantedBy=mysql.service
```
# Technical notes about searching
By default, Mattermost uses full text search support included in MySQL. Select the **product menu** <img src={useBaseUrl('/img/ui/products_E82F.svg')} alt="Navigate between Channels, collaborative playbooks, and boards using the product menu icon." className="theme-icon" /> then select **About Mattermost** to see which database you’re using.
- Stop words are filtered out of search results. See [MySQL](https://dev.mysql.com/doc/refman/5.7/en/fulltext-stopwords.html) database documentation for a full list of applicable stop words.
- Hashtags or recent mentions of usernames containing a dot don't return results.
- Avoid using underline `_` symbol to [perform a wildcard search](#wildcards). Use the asterisk `*` symbol instead.
- Stop words that are excluded from search in MySQL include: `"a", "about", "an", "are", "as", "at", "be", "by", "com", "de", "en", "for", "from", "how", "i", "in", "is", "it", "la", "of", "on", "or", "that", "the", "this", "to", "was", "what", "when", "where", "who", "will", "with", "und", "the", "www"`.
## Perform searches in Chinese, Korean, and Japanese
The best experience for searching in Chinese, Korean, and Japanese is to use MySQL 5.7.6 or later with special configuration. See the [Chinese, Japanese and Korean Search documentation](/administration-guide/configure/enabling-chinese-japanese-korean-search) for details.
You can perform searches without this configuration by adding wildcards `*` to the end of search terms.
# Migrate from Bitnami to a self-hosted Mattermost deployment
If you're planning a migration from Bitnami to a self-hosted Mattermost installation with a MySQL database, read these notes in our migration guide: [Migrating from Bitnami](/administration-guide/onboard/migrating-to-mattermost#move-from-bitnami).
# Downgrade Mattermost v6.0 to v5.38
``` sh
INSERT INTO Systems (Name,Value) VALUES ('Version','5.38.0') ON DUPLICATE KEY UPDATE Value = '5.38.0';
CREATE INDEX idx_status_status ON Status (Status);
DROP INDEX idx_status_status_dndendtime ON Status;
CREATE INDEX idx_channelmembers_user_id ON ChannelMembers (UserId);
DROP INDEX idx_channelmembers_channel_id_scheme_guest_user_id ON ChannelMembers;
DROP INDEX idx_channelmembers_user_id_channel_id_last_viewed_at ON ChannelMembers;
CREATE INDEX idx_threads_channel_id ON Threads (ChannelId);
DROP INDEX idx_threads_channel_id_last_reply_at ON Threads;
CREATE INDEX idx_channels_team_id ON Channels (TeamId);
DROP INDEX idx_channels_team_id_type ON Channels;
DROP INDEX idx_channels_team_id_display_name ON Channels;
CREATE INDEX idx_posts_root_id ON Posts (RootId);
DROP INDEX idx_posts_root_id_delete_at ON Posts;
ALTER TABLE CommandWebhooks ADD COLUMN ParentId varchar(26);
UPDATE CommandWebhooks SET ParentId = '';
ALTER TABLE Posts ADD COLUMN ParentId varchar(26);
UPDATE Posts SET ParentId = '';
ALTER TABLE Users MODIFY Timezone text;
ALTER TABLE Users MODIFY NotifyProps text;
ALTER TABLE Users MODIFY Props text;
ALTER TABLE Threads MODIFY Participants longtext;
ALTER TABLE Sessions MODIFY Props text;
ALTER TABLE Posts MODIFY Props text;
ALTER TABLE Jobs MODIFY Data text;
ALTER TABLE LinkMetadata MODIFY Data text;
ALTER TABLE ChannelMembers MODIFY NotifyProps text;
```
<Note>
The inverse of [the final v6.0 upgrade query](https://gist.github.com/streamer45/59b3582118913d4fc5e8ff81ea78b055#mysql-1) is intentionally omitted from these downgrade queries because its result is backwards compatible, and running the query would unnecessarily delay the downgrade process.
</Note>

View File

@@ -0,0 +1,147 @@
---
title: "Network ports and outbound proxy"
sidebar_label: "Prepare your network"
---
Open the ports Mattermost needs before you install, and note the outbound destinations your deployment will reach. If your environment blocks direct outbound access, configure an outbound proxy at the same time.
## Network ports
The following table outlines the network ports and protocols required for Mattermost server:
<table style={{width: '98%'}}>
<colgroup>
<col style={{width: '26%'}} />
<col style={{width: '17%'}} />
<col style={{width: '15%'}} />
<col style={{width: '5%'}} />
<col style={{width: '5%'}} />
<col style={{width: '27%'}} />
</colgroup>
<thead>
<tr>
<th>Service Name</th>
<th>Config Setting</th>
<th>Port (default)</th>
<th>Protocol</th>
<th>Direction</th>
<th>Info</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTTP/Websocket</td>
<td>ServiceSettings.ListenAddress</td>
<td>8065/80/443 (TLS)</td>
<td>TCP</td>
<td>Inbound</td>
<td>External (no proxy) / Internal (with proxy) Usually this requires port 80 and 443 when running HTTPS.</td>
</tr>
<tr>
<td>Cluster</td>
<td>ClusterSettings.GossipPort</td>
<td>8074</td>
<td>TCP/UDP</td>
<td>Inbound</td>
<td>Internal</td>
</tr>
<tr>
<td>Metrics</td>
<td>MetricsSettings.ListenAddress</td>
<td>8067</td>
<td>TCP</td>
<td>Inbound</td>
<td>External (no proxy) / Internal (with proxy)</td>
</tr>
<tr>
<td>Database</td>
<td>SqlSettings.DataSource</td>
<td>5432 (PostgreSQL) / 3306 (MySQL)</td>
<td>TCP</td>
<td>Outbound</td>
<td>Usually internal (recommended)</td>
</tr>
<tr>
<td>LDAP</td>
<td>LdapSettings.LdapPort</td>
<td>389</td>
<td>TCP/UDP</td>
<td>Outbound</td>
<td></td>
</tr>
<tr>
<td>S3 Storage</td>
<td>FileSettings.AmazonS3Endpoint</td>
<td>443 (TLS)</td>
<td>TCP</td>
<td>Outbound</td>
<td></td>
</tr>
<tr>
<td>SMTP</td>
<td>EmailSettings.SMTPPort</td>
<td>10025</td>
<td>TCP/UDP</td>
<td>Outbound</td>
<td></td>
</tr>
<tr>
<td>Push Notifications</td>
<td>EmailSettings.PushNotificationServer</td>
<td>443 (TLS)</td>
<td>TCP</td>
<td>Outbound</td>
<td></td>
</tr>
</tbody>
</table>
<Note>
- All outbound ports may vary based on your specific configuration
- Mattermost can be configured to use an outbound proxy for any HTTP/HTTPS traffic (see below)
- Calls service may require additional ports. See the [Calls deployment guide](/deployment-guide/calls/calls-deployment-guide) for details.
</Note>
Only the inbound ports your readers actually reach need to be exposed externally. When Mattermost runs behind [an NGINX reverse proxy](/deployment-guide/server/setup-nginx-proxy), expose 80 and 443 at the proxy and keep 8065, 8067, and 8074 internal.
## Outbound proxy configuration
If your deployment requires using an outbound proxy, you can configure Mattermost using environment variables:
1. Configure the proxy settings in your service configuration:
``` text
Environment=HTTP_PROXY=http://proxy.example.com:3128
Environment=HTTPS_PROXY=https://proxy.example.com:3128
Environment=NO_PROXY=localhost,127.0.0.1,.internal.example.com
```
These lines go in the `[Service]` section of the `mattermost.service` systemd unit. See your install method's page for the complete unit file: [Ubuntu/Debian](/deployment-guide/server/linux/deploy-ubuntu), [RHEL](/deployment-guide/server/linux/deploy-rhel), or [manual tarball](/deployment-guide/server/linux/deploy-tar).
2. For authenticated proxies, include credentials in the URL:
``` text
Environment=HTTP_PROXY=http://username:password@proxy.example.com:3128
Environment=HTTPS_PROXY=https://username:password@proxy.example.com:3128
```
Anyone who can read the unit file can read these credentials. Restrict the file's permissions, or supply the values through a separate `EnvironmentFile` that only root can read.
3. The `NO_PROXY` variable can include:
- IP addresses (e.g., `1.2.3.4`)
- CIDR ranges (e.g., `1.2.3.4/8`)
- Domain names (e.g., `example.com`)
- Subdomains (e.g., `.example.com`)
<Note>
When using an HTTPS proxy, ensure your Mattermost server has the proxy's root certificate configured to avoid connection issues.
</Note>
## Next steps
- [Set up an NGINX proxy](/deployment-guide/server/setup-nginx-proxy) and [set up TLS](/deployment-guide/server/setup-tls) so users connect over HTTPS.
- Return to the [preparation checklist](/deployment-guide/server/preparations).

View File

@@ -0,0 +1,35 @@
---
title: "Plan your deployment"
---
Everything in this section is a decision you make before touching a server: what the components are, how big each one needs to be, and what the requirements are for the versions you'll run. Work through the pages in order.
<CardGrid columns={3} cards={[
{
title: 'Application architecture',
description: 'The components of a Mattermost deployment and how they fit together: access layer, application layer, and the database, file storage, search, and cache behind them.',
to: '/deployment-guide/application-architecture',
},
{
title: 'Size your deployment',
description: 'Pick a scale tier, deployment type, and hosting provider to get a target architecture diagram and a bill of materials sized to those choices.',
to: '/deployment-guide/deployment-architecture',
},
{
title: 'Software and hardware requirements',
description: 'Minimum client, server, database, and hardware requirements, including the minimum PostgreSQL version policy.',
to: '/deployment-guide/software-hardware-requirements',
},
]} />
## What to decide here
Sizing depends on more than user count. Before you move on to [Prepare](/deployment-guide/server/preparations), settle:
- **Expected user count and growth.** Sizing is driven by concurrent users, not registered users. [Size your deployment](/deployment-guide/deployment-architecture) maps a scale tier to a bill of materials.
- **Whether you need high availability.** HA changes the topology, the licensing, and the deployment method. See [High availability cluster-based deployment](/deployment-guide/server/high-availability-cluster-based-deployment).
- **Your backup and disaster recovery requirements.** These are deployment-time architecture decisions, not day-2 tasks. See [Back up and recover](/deployment-guide/backup-disaster-recovery).
- **Which deployment method fits your environment.** Kubernetes, Linux, or containers. The trade-offs are compared in [Deploy the Mattermost server](/deployment-guide/server/deploy-server#deployment-options).
- **Security and compliance constraints.** If you're deploying air-gapped, into a coalition network, or under a compliance framework, start from [Deployment Scenarios](/deployment-guide/deployment-scenarios/deployment-scenarios-index), because those constraints shape every decision that follows.
- **Integrations with existing systems.** Identity provider, SMTP relay, push notification service, and search infrastructure all need to exist before you cut over users.
Not deploying it yourself? [Deployment Solution Programs](/get-help/deployment-solution-programs) covers the third-party and community-maintained solutions that deploy Mattermost for you, and the standards each recognition tier commits to.

View File

@@ -0,0 +1,709 @@
---
title: "(Recommended) Set up an NGINX proxy"
---
A proxy server is a server (a computer system or an application) that acts as an intermediary for requests from clients seeking resources from other servers. Mattermost recommends using a proxy in front of Mattermost to increase security, performance and the ability to monitor and shape traffic connecting to Mattermost:
- **Security:** A proxy server can manage Secure Socket Layer (TLS/SSL) encryption and set policy on how network traffic will be routed to the Mattermost server.
- **Performance:** In a High Availability configuration, the proxy server balances the network load across multiple Mattermost servers for optimized performance. A hardware proxy with dedicated devices for processing SSL encryption and decryption can also be used to increase performance.
- **Monitoring**: A proxy server can monitor connection traffic and record traffic in standard audit logs that common monitoring tools like Kibana and Splunk can consume and report on. Some of the events that can be captured include file uploads and downloads, which are not tracked by the Mattermost server logging process.
Mattermost supports the [NGINX proxy](https://www.f5.com/go/product/welcome-to-nginx)
![Mattermost architecture with NGINX proxy](/images/architecture_with_proxy.png)
## Install NGINX server
NGINX is a popular web server and is responsible for hosting some of the largest and highest-traffic sites on the internet. It's more resource-friendly than Apache in most cases, and can be used as a web server or reverse proxy.
In a production setting, we recommend using a proxy server for greater security and performance of Mattermost:
- SSL termination
- HTTP to HTTPS redirect
- Port mapping `:80` to `:8065`
- Standard request logs
### Install NGINX on Ubuntu Server
1. Log in to the server that will host the proxy and open a terminal window.
2. Install NGINX.
> Because NGINX is available in Ubuntu's default repositories, it's possible to install it from these repositories using the `apt` packaging system. First, update your local `apt` package index for access to the most recent package listings. Then, install `nginx`:
>
> ``` sh
> sudo apt update
> sudo apt install nginx
> ```
>
> After accepting the procedure, `apt` will install NGINX and any required dependencies to your server.
3. After installing it, you already have everything you need. You can point your browser to your server IP address. You should see the default NGINX landing page:
> ![Example of the default NGINX landing page.](/images/install_nginx_welcome.png)
>
> If you see this page, you've successfully installed NGINX on your web server. This page is included with NGINX to show you that the server is running correctly.
>
> Or you can also verify it by running `curl http://localhost`.
>
> If NGINX is running, you see the following output:
>
> ``` html
> &lt;!DOCTYPE html>
> <html>
> &lt;head&gt;
> <title>Welcome to nginx!</title>
> .
> .
> .
> <p><em>Thank you for using nginx.</em></p>
> </body>
> </html>
> ```
### Manage the NGINX process
Now that you have your web server up and running, let's review some basic management commands. These are all run in the command line interface.
To stop your web server, use: `sudo systemctl stop nginx`
To start the web server when it's stopped, use: `sudo systemctl start nginx`
To stop and then start the service again, use: `sudo systemctl restart nginx`
If you're simply making configuration changes, NGINX can often reload without dropping connections. To do this, use: `sudo systemctl reload nginx`
By default, NGINX is configured to start automatically when the server boots. If this isn't what you want, you can disable this behavior using: `sudo systemctl disable nginx`
To re-enable the service to start up at boot, use: `sudo systemctl enable nginx`
### What to do next
1. Map a fully qualified domain name (FQDN) such as `mattermost.example.com` on your DNS server/service, to point to the NGINX server.
2. Configure NGINX to proxy connections from the internet to the Mattermost server.
## Configure NGINX as a proxy for Mattermost server
NGINX is configured using a file in the `/etc/nginx/sites-available` directory. You need to create the file and then enable it. When creating the file, you need the IP address of your Mattermost server and the fully qualified domain name (FQDN) of your Mattermost website.
1. Log in to the server that hosts NGINX and open a terminal window.
2. Create a configuration file for Mattermost by running the following command:
> `sudo touch /etc/nginx/sites-available/mattermost` on Ubuntu
>
> `sudo touch /etc/nginx/conf.d/mattermost` on RHEL 8
3. Open the file `/etc/nginx/sites-available/mattermost` (Ubuntu) or `/etc/nginx/conf.d/mattermost` (RHEL 8) as *root* user in a text editor and replace its contents, if any, with the following lines. Make sure that you use your own values for the Mattermost server IP address and FQDN for *server_name*.
SSL and HTTP/2 are enabled in the provided configuration example.
<Note>
- If you're going to use Let's Encrypt to manage your SSL certificate, stop at step 3 and see the [NGINX HTTP/2 and SSL product documentation](/deployment-guide/server/setup-nginx-proxy#configure-nginx-with-ssl-and-http2) for details.
- You'll need valid SSL certificates in order for NGINX to pin the certificates properly. Additionally, your browser must have permissions to accept the certificate as a valid CA-signed certificate.
- Note that the IP address included in the examples in this documentation may not match your network configuration.
- If you're running NGINX on the same machine as Mattermost, and NGINX resolves `localhost` to more than one IP address (IPv4 or IPv6), we recommend using `127.0.0.1` instead of `localhost`.
``` text
upstream backend {
server 10.10.10.2:8065;
keepalive 32;
}
server {
listen 80 default_server;
server_name mattermost.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mattermost.example.com;
ssl_certificate /etc/letsencrypt/live/{domain-name}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{domain-name}/privkey.pem;
ssl_session_timeout 1d;
# Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
ssl_protocols TLSv1.2 TLSv1.3;
# Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
# prevent replay attacks.
#
# @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
ssl_early_data on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = six months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
add_header X-Early-Data $tls1_3_early_data;
location ~ /api/v[0-9]+/(users/)?websocket$ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 50M;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
client_body_timeout 60s;
send_timeout 300s;
lingering_timeout 5s;
proxy_connect_timeout 90s;
proxy_send_timeout 300s;
proxy_read_timeout 90s;
proxy_http_version 1.1;
proxy_pass http://backend;
}
location / {
client_max_body_size 100M;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
proxy_read_timeout 600s;
proxy_http_version 1.1;
proxy_pass http://backend;
}
}
# This block is useful for debugging TLS v1.3. Please feel free to remove this
# and use the `$ssl_early_data` variable exposed by NGINX directly should you
# wish to do so.
map $ssl_early_data $tls1_3_early_data {
"~." $ssl_early_data;
default "";
}
```
</Note>
4. Remove the existing default sites-enabled file by running `sudo rm /etc/nginx/sites-enabled/default` (Ubuntu) or `sudo rm /etc/nginx/conf.d/default` (RHEL 8)
5. Enable the mattermost configuration by running `sudo ln -s /etc/nginx/sites-available/mattermost /etc/nginx/sites-enabled/mattermost` (Ubuntu) or `sudo ln -s /etc/nginx/conf.d/mattermost /etc/nginx/conf.d/default.conf` (RHEL 8)
6. Restart NGINX by running `sudo systemctl restart nginx`.
7. Verify that you can see Mattermost through the proxy by running `curl https://localhost`. If everything is working, you will see the HTML for the Mattermost signup page.
8. Restrict access to port 8065.
> By default, the Mattermost server accepts connections on port 8065 from every machine on the network. Use your firewall to deny connections on port 8065 to all machines except the machine that hosts NGINX and the machine that you use to administer the Mattermost server. If you're installing on Amazon Web Services, you can use Security Groups to restrict access.
Now that NGINX is installed and running, you can configure it to use SSL, which allows you to use HTTPS connections and the HTTP/2 protocol.
## Configure NGINX with SSL and HTTP/2
NGINX is configured using a file in the `/etc/nginx/sites-available` directory. You need to create the file and then enable it. When creating the file, you need the IP address of your Mattermost server and the fully qualified domain name (FQDN) of your Mattermost website.
Using SSL gives greater security by ensuring that communications between Mattermost clients and the Mattermost server are encrypted. It also allows you to configure NGINX to use the HTTP/2 protocol.
Although you can configure HTTP/2 without SSL, both Firefox and Chrome browsers support HTTP/2 on secure connections only.
You can use any certificate that you want, but these instructions show you how to download and install certificates from [Let's Encrypt](https://letsencrypt.org/), a free certificate authority.
<Note>
If Let’s Encrypt is enabled, forward port 80 through a firewall, with [Forward80To443](/administration-guide/configure/environment-configuration-settings#forward-port-80-to-443) `config.json` setting set to `true` to complete the Let’s Encrypt certification. See the [Let's Encrypt/Certbot documentation](https://certbot.eff.org) for additional assistance.
</Note>
1. Log in to the server that hosts NGINX and open a terminal window.
2. Open the your Mattermost `nginx.conf` file as *root* in a text editor, then update the `&#123;ip&#125;` address in the `upstream backend` to point towards Mattermost (such as `127.0.0.1:8065`), and update the `server_name` to be your domain for Mattermost.
> <div class="note">
>
> <div class="title">
>
> Note
>
> </div>
>
> - On Ubuntu this file is located at `/etc/nginx/sites-available/`. If you don't have this file, run `sudo touch /etc/nginx/sites-available/mattermost`.
> - On CentOS/RHEL this file is located at `/etc/nginx/conf.d/`. If you don't have this file, run `sudo touch /etc/nginx/conf.d/mattermost`.
> - The IP address included in the examples in this documentation may not match your network configuration.
> - If you're running NGINX on the same machine as Mattermost, and NGINX resolves `localhost` to more than one IP address (IPv4 or IPv6), we recommend using `127.0.0.1` instead of `localhost`.
>
> </div>
>
> ``` text
> upstream backend &#123;
> server &#123;ip&#125;:8065;
> keepalive 32;
> &#125;
>
> server &#123;
> listen 80 default_server;
> server_name mattermost.example.com;
>
> location ~ /api/v[0-9]+/(users/)?websocket$ &#123;
> proxy_set_header Upgrade $http_upgrade;
> proxy_set_header Connection "upgrade";
> client_max_body_size 50M;
> proxy_set_header Host $http_host;
> proxy_set_header X-Real-IP $remote_addr;
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> proxy_set_header X-Forwarded-Proto $scheme;
> proxy_set_header X-Frame-Options SAMEORIGIN;
> proxy_buffers 256 16k;
> proxy_buffer_size 16k;
> client_body_timeout 60s;
> send_timeout 300s;
> lingering_timeout 5s;
> proxy_connect_timeout 90s;
> proxy_send_timeout 300s;
> proxy_read_timeout 90s;
> proxy_pass http://backend;
> &#125;
>
> location / &#123;
> client_max_body_size 50M;
> proxy_set_header Connection "";
> proxy_set_header Host $http_host;
> proxy_set_header X-Real-IP $remote_addr;
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> proxy_set_header X-Forwarded-Proto $scheme;
> proxy_set_header X-Frame-Options SAMEORIGIN;
> proxy_buffers 256 16k;
> proxy_buffer_size 16k;
> proxy_read_timeout 600s;
> proxy_http_version 1.1;
> proxy_pass http://backend;
> &#125;
> &#125;
> ```
3. Remove the existing default sites-enabled file by running `sudo rm /etc/nginx/sites-enabled/default` (Ubuntu) or `sudo rm /etc/nginx/conf.d/default` (RHEL 8).
4. Enable the Mattermost configuration by running `sudo ln -s /etc/nginx/sites-available/mattermost /etc/nginx/sites-enabled/mattermost` (Ubuntu) or `sudo ln -s /etc/nginx/conf.d/mattermost /etc/nginx/conf.d/default.conf` (RHEL 8).
5. Run `sudo nginx -t` to ensure your configuration is done properly. If you get an error, look into the NGINX config and make the needed changes to the file under `/etc/nginx/sites-available/mattermost`.
6. Restart NGINX by running `sudo systemctl start nginx`.
7. Verify that you can see Mattermost through the proxy by running `curl http://localhost`.
> If everything is working, you will see the HTML for the Mattermost signup page. You will see invalid certificate when accessing through the IP or localhost. Use the full FQDN domain to verify if the SSL certificate has pinned properly and is valid.
8. Install and update Snap by running `sudo snap install core; sudo snap refresh core`.
9. Install the Certbot package by running `sudo snap install --classic certbot`.
10. Add a symbolic link to ensure Certbot can run by running `sudo ln -s /snap/bin/certbot /usr/bin/certbot`.
11. Run the Let's Encrypt installer dry-run to ensure your DNS is configured properly by running `sudo certbot certonly --dry-run`.
> This will prompt you to enter your email, accept the TOS, share your email, and select the domain you're activating certbot for. This will validate that your DNS points to this server properly and you are able to successfully generate a certificate. If this finishes successfully, proceed to step 12.
12. Run the Let's Encrypt installer by running `sudo certbot`. This will run certbot and will automatically edit your NGINX config file for the site(s) selected.
13. Ensure your SSL is configured properly by running `curl https://&#123;your domain here&#125;`
14. Finally, we suggest editing your config file again to increase your SSL security settings above the default Let's Encrypt. This is the same file from Step 2 above. Edit it to look like the below:
> ``` text
> upstream backend &#123;
> server &#123;ip&#125;:8065;
> keepalive 32;
> &#125;
>
> proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
>
> server &#123;
> server_name mattermost.example.com;
>
> location ~ /api/v[0-9]+/(users/)?websocket$ &#123;
> proxy_set_header Upgrade $http_upgrade;
> proxy_set_header Connection "upgrade";
> client_max_body_size 50M;
> proxy_set_header Host $http_host;
> proxy_set_header X-Real-IP $remote_addr;
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> proxy_set_header X-Forwarded-Proto $scheme;
> proxy_set_header X-Frame-Options SAMEORIGIN;
> proxy_buffers 256 16k;
> proxy_buffer_size 16k;
> client_body_timeout 60s;
> send_timeout 300s;
> lingering_timeout 5s;
> proxy_connect_timeout 90s;
> proxy_send_timeout 300s;
> proxy_read_timeout 90s;
> proxy_http_version 1.1;
> proxy_pass http://backend;
> &#125;
>
> location / &#123;
> client_max_body_size 50M;
> proxy_set_header Connection "";
> proxy_set_header Host $http_host;
> proxy_set_header X-Real-IP $remote_addr;
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> proxy_set_header X-Forwarded-Proto $scheme;
> proxy_set_header X-Frame-Options SAMEORIGIN;
> proxy_buffers 256 16k;
> proxy_buffer_size 16k;
> proxy_read_timeout 600s;
> proxy_http_version 1.1;
> proxy_pass http://backend;
> &#125;
>
> listen 443 ssl http2; # managed by Certbot
> ssl_certificate /etc/letsencrypt/live/mattermost.example.com/fullchain.pem; # managed by Certbot
> ssl_certificate_key /etc/letsencrypt/live/mattermost.example.com/privkey.pem; # managed by Certbot
> # include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
> ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
>
> ssl_session_timeout 1d;
>
> # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
> ssl_protocols TLSv1.2 TLSv1.3;
>
> # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
> # prevent replay attacks.
> #
> # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
> ssl_early_data on;
>
> ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA;
> ssl_prefer_server_ciphers on;
> ssl_session_cache shared:SSL:50m;
> # HSTS (ngx_http_headers_module is required) (15768000 seconds = six months)
> add_header Strict-Transport-Security max-age=15768000;
> # OCSP Stapling ---
> # fetch OCSP records from URL in ssl_certificate and cache them
> ssl_stapling on;
> ssl_stapling_verify on;
> &#125;
>
>
> server &#123;
> if ($host = mattermost.example.com) &#123;
> return 301 https://$host$request_uri;
> &#125; # managed by Certbot
>
>
> listen 80 default_server;
> server_name mattermost.example.com;
> return 404; # managed by Certbot
>
> &#125;
> ```
15. Check that your SSL certificate is set up correctly.
> - Test the SSL certificate by visiting a site such as [https://www.ssllabs.com/ssltest/index.html](https://www.ssllabs.com/ssltest/index.html).
> - If there’s an error about the missing chain or certificate path, there is likely an intermediate certificate missing that needs to be included.
## High-performance scaling configuration
For high-scale deployments with multiple Mattermost servers and heavy traffic loads, additional NGINX optimizations are recommended. This configuration is based on performance testing with large-scale Mattermost deployments.
<Note>
These settings are designed for high-performance environments. For standard deployments, the basic configuration above should be sufficient.
</Note>
### NGINX main configuration optimizations
Update your main NGINX configuration file (`/etc/nginx/nginx.conf`) with the following performance optimizations:
``` text
user www-data;
worker_processes auto;
worker_rlimit_nofile 100000;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 20000;
use epoll;
}
http {
map $status $loggable {
~^[23] 0;
default 1;
}
sendfile on;
tcp_nopush on;
tcp_nodelay off;
keepalive_timeout 75s;
keepalive_requests 16384;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log combined if=$loggable;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/sites-enabled/*;
}
```
Key optimizations in this configuration:
- **worker_processes auto**: Automatically sets worker processes based on CPU cores
- **worker_rlimit_nofile 100000**: Increases file descriptor limit for high-concurrency
- **worker_connections 20000**: Allows each worker to handle more concurrent connections
- **use epoll**: Enables efficient connection handling on Linux
- **keepalive_timeout 75s** and **keepalive_requests 16384**: Optimizes connection reuse
- **Conditional logging**: Reduces log volume by only logging errors and non-2xx/3xx responses
### Multi-node backend configuration
For deployments with multiple Mattermost application servers, configure your site file (`/etc/nginx/sites-available/mattermost`) with load balancing:
``` text
upstream backend {
server 172.27.205.186:8065 max_fails=0;
server 172.27.213.167:8065 max_fails=0;
# Add additional Mattermost servers as needed
keepalive 256;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=60m use_temp_path=off;
server {
listen 80 reuseport;
server_name _;
location ~ /api/v[0-9]+/(users/)?websocket$ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
include /etc/nginx/snippets/proxy.conf;
}
location ~ /api/v[0-9]+/users/[a-z0-9]+/image$ {
proxy_set_header Connection "";
include /etc/nginx/snippets/proxy.conf;
include /etc/nginx/snippets/cache.conf;
proxy_ignore_headers Cache-Control Expires;
proxy_cache_valid 200 24h;
}
location / {
proxy_set_header Connection "";
include /etc/nginx/snippets/proxy.conf;
include /etc/nginx/snippets/cache.conf;
}
}
```
### NGINX proxy configuration snippets
Create optimized proxy configuration snippets for reuse across different locations.
Create `/etc/nginx/snippets/proxy.conf`:
``` text
client_max_body_size 50M;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
client_body_timeout 60s;
send_timeout 300s;
lingering_timeout 5s;
proxy_connect_timeout 30s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;
proxy_http_version 1.1;
proxy_pass http://backend;
```
Create `/etc/nginx/snippets/cache.conf`:
``` text
proxy_cache mattermost_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 2;
proxy_cache_use_stale timeout;
proxy_cache_lock on;
```
### Key performance optimizations
The high-performance configuration includes several critical optimizations:
**Load Balancing**:
- **max_fails=0**: Prevents servers from being marked as unavailable
- **keepalive 256**: Maintains persistent connections to backend servers
- **reuseport**: Allows multiple worker processes to bind to the same port
**Caching Strategy**:
- **User images cached for 24 hours**: Reduces load on application servers for static content
- **Cache revalidation**: Ensures fresh content while maintaining performance
- **Cache locking**: Prevents cache stampede scenarios
**Buffer and Timeout Optimization**:
- **proxy_buffers 256 16k**: Handles high-throughput data transfer efficiently
- **Optimized timeouts**: Balances responsiveness with resource usage
- **HTTP/1.1 keepalive**: Reduces connection overhead
**Resource Limits**:
- **50M client_max_body_size**: Accommodates large file uploads
- **Increased file descriptor limits**: Supports high-concurrency scenarios
### Implementation notes
1. **Replace IP addresses**: Update the backend server IPs (172.27.205.186, 172.27.213.167) with your actual Mattermost server addresses.
2. **Create cache directory**: Ensure the cache directory exists and has proper permissions:
``` sh
sudo mkdir -p /var/cache/nginx
sudo chown -R www-data:www-data /var/cache/nginx
```
3. **Test configuration**: Always test your configuration before applying:
``` sh
sudo nginx -t
```
4. **Monitor performance**: Use NGINX access logs and monitoring tools to verify the performance improvements.
5. **Scale incrementally**: Apply these optimizations gradually and monitor their impact on your specific deployment.
## NGINX configuration FAQ
### Why am I seeing the error "Too many redirects?"
You may see this error if you're setting Mattermost in a sub-path. To resolve this error, add the following block to the HEAD request:
``` text
location ~* ^/sub-path {
client_max_body_size 250M;
proxy_set_header Connection "";
if ($request_method = HEAD) {
return 200;
}
}
```
### Why are Websocket connections returning a 403 error?
This is likely due to a failing cross-origin check. A check is applied for WebSocket code to see if the `Origin` header is the same as the host header. If it's not, a 403 error is returned. Open the file `/etc/nginx/sites-available/mattermost` as *root* in a text editor and make sure that the host header being set in the proxy is dynamic:
``` text
location ~ /api/v[0-9]+/(users/)?websocket$ {
proxy_pass http://backend;
(...)
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
```
Then in `config.json` set the `AllowCorsFrom` setting to match the domain being used by clients. You may need to add variations of the host name that clients may send. Your NGINX log will be helpful in diagnosing the problem.
``` text
"EnableUserAccessTokens": false,
"AllowCorsFrom": "domain.com domain.com:443 im.domain.com",
"SessionLengthWebInDays": 30,
```
### How do I setup an NGINX proxy with the Mattermost Docker installation?
1. Find the name of the Mattermost network and connect it to the NGINX proxy.
``` sh
docker network ls
# Grep the name of your Mattermost network like "mymattermost_default".
docker network connect mymattermost_default nginx-proxy
```
2. Restart the Mattermost Docker containers.
``` sh
docker-compose stop app
docker-compose start app
```
<Tip>
You don't need to run the 'web' container, since NGINX proxy accepts incoming requests.
</Tip>
3. Update your `docker-compose.yml` file to include a new environment variable `VIRTUAL_HOST` and an `expose` directive.
``` text
environment:
# set same as db credentials and dbname
- MM_USERNAME=mmuser
- MM_PASSWORD=mmuser-password
- MM_DBNAME=mattermost
- VIRTUAL_HOST=mymattermost.tld
expose:
- "80"
- "443"
```
### Why does NGINX fail when installing GitLab CE with Mattermost on Azure?
You may need to update the Callback URLs for the Application entry of Mattermost inside your GitLab instance.
1. Log in to your GitLab instance as the admin.
2. Go to **Admin \> Applications**.
3. Select **Edit** on GitLab-Mattermost.
4. Update the callback URLs to your new domain/URL.
5. Save the changes.
6. Update the external URL for GitLab and Mattermost in the `/etc/gitlab/gitlab.rb` configuration file.
### Why does Certbot fail the http-01 challenge?
``` text
Requesting a certificate for yourdomain.com
Performing the following challenges:
http-01 challenge for yourdomain.com
Waiting for verification...
Challenge failed for domain yourdomain.com
http-01 challenge for yourdomain.com
Cleaning up challenges
Some challenges have failed.
```
If you see the above errors this is typically because Certbot wasn't able to access port 80. This can be due to a firewall or other DNS configuration. Make sure that your A/AAAA records are pointing to this server and your `server_name` within the NGINX config doesn't have a redirect.
<Note>
If you're using Cloudflare you'll need to disable `force traffic to https`.
</Note>
#### Certbot rate limiting
If you're running certbot as stand-alone you'll see this error:
``` text
Error: Could not issue a Let's Encrypt SSL/TLS certificate for example.com.
One of the Let's Encrypt rate limits has been exceeded for example.com.
See the related Knowledge Base article for details.
Details
Invalid response from https://acme-v02.api.letsencrypt.org/acme/new-order.
Details:
Type: urn:ietf:params:acme:error:rateLimited
Status: 429
Detail: Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/
```
If you're running Let's Encrypt within Mattermost you'll see this error:
``` json
{"level":"error","ts":1609092001.752515,"caller":"http/server.go:3088","msg":"http: TLS handshake error from ip:port: 429 urn:ietf:params:acme:error:rateLimited: Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/","source":"httpserver"}
```
This means that you've attempted to generate a cert too many times. You can find more information [here](https://letsencrypt.org/docs/rate-limits).

View File

@@ -0,0 +1,72 @@
---
title: "(Optional) Set up TLS"
---
You have two options if you want users to connect with HTTPS:
[Install a proxy such as NGINX](/deployment-guide/server/setup-nginx-proxy) and then [set up TLS on the proxy](#use-tls-on-nginx-as-a-proxy). This is our recommended option if you have a large number of users (more than 200), or if you want to use a reverse proxy for other reasons, such as load balancing or caching. A proxy server delivers better performance and provides standard HTTP request logs.
Alternatively, if you have fewer than 200 users, you can set up TLS on Mattermost server. This is the easiest option when you don't need to use a reverse proxy.
> - You can use [Let's Encrypt](https://letsencrypt.org/) to automatically install and set up the certificate.
> - You can also specify your own certificate.
> - You can use a self-signed certificate, but this is not recommended for production environments.
## Configure TLS on the Mattermost server
1. In **System Console \> Environment \> Web Server**:
> 1. Change the **Listen Address** setting to `:443`.
> 2. Change the **Connection Security** setting to `TLS`.
> 3. Change the **Forward port 80 to 443** setting to `true`.
2. Activate the `CAP_NET_BIND_SERVICE` capability to allow Mattermost to bind to low ports:
> ``` sh
> sudo setcap cap_net_bind_service=+ep /opt/mattermost/bin/mattermost
> ```
3. Install the security certificate. Use Let's Encrypt to automatically install and setup the certificate, or specify your own certificate.
## Use a Let's Encrypt certificate
The certificate is retrieved the first time that a client tries to connect to the Mattermost server. Certificates are retrieved for any hostname a client tries to reach the server at.
1. Change the **Use Let's Encrypt** setting to `true`.
2. Restart the Mattermost server for these changes to take effect.
<Note>
- If Let's Encrypt is enabled, forward port 80 through a firewall, with [Forward80To443](/administration-guide/configure/environment-configuration-settings#forward-port-80-to-443) `config.json` setting set to `true` to complete the Let's Encrypt certification.
- Your Mattermost server must be accessible from the Let's Encrypt CA in order to verify your domain name and issue the certificate. Be sure to open your firewall and configure any reverse proxies to forward traffic to ports 80 and 443. More information can be found [at Let's Encrypt](https://letsencrypt.org/how-it-works/).
</Note>
## Use your own certificate
1. Change the **Use Let's Encrypt** setting to `false`.
2. Change the **TLS Certificate File** setting to the location of the certificate file.
3. Change the **TLS Key File** setting to the location of the private key file.
4. Restart the Mattermost server for these changes to take effect.
<Note>
Password-protected certificates aren't supported.
</Note>
## Use TLS on NGINX (as a proxy)
<Warning>
Do not set up TLS on Mattermost before doing so for NGINX. It breaks the connection as the TLS prevents it from successfully communicating with the Mattermost server.
</Warning>
- NGINX will act as a forward proxy to encrypt the traffic between the client and Mattermost server. After installing the SSL certificate, the incoming traffic will be handled via NGINX on port 443 exposed to the internet, proxy to the Mattermost server running on port 80.
- (Optional) Upstream encryption between NGINX to Mattermost server is allowed.
- Follow [NGINX's guide on setting up SSL Termination for TCP Upstream Servers](https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-tcp/).
More helpful resources:
- [NGINX's SSL blog](https://www.f5.com/company/blog/nginx/nginx-ssl/)
- [NGINX's SSL guide](https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-http/)

View File

@@ -0,0 +1,215 @@
---
title: "MySQL installation troubleshooting"
unlisted: true
---
<Important>
- From Mattermost v11, Mattermost completely stops support MySQL as a database driver. MySQL support has been completely removed from the codebase, and the product will throw an invalid configuration error.
- PostgreSQL is our preferred database of choice. See the [database software](/deployment-guide/software-hardware-requirements#database-software) documentation for details on database version support, and see the [Migrate from MySQL to PostgreSQL](/administration-guide/manage/admin/postgres-migration) documentation for details on migrating from MySQL to PostgreSQL.
</Important>
Before you can run the Mattermost server, you must first install and configure a database. You can start Mattermost by navigating to the `/opt/mattermost` directory and entering the command `sudo -u mattermost bin/mattermost`. If the Mattermost server can't connect to the database, it will fail to start. This section deals with MySQL database issues that you may encounter when you start up Mattermost for the first time.
<Note>
- Additional database tuning guidance is available for specific Mattermost releases. See the [important upgrade notes](/administration-guide/upgrade/important-upgrade-notes) documentation for more details.
- See the [database configuration settings](/administration-guide/configure/environment-configuration-settings#database) documentation for details on configuration options specific to MySQL databases.
</Note>
How you install MySQL varies depending upon which Linux distribution you use. However, once MySQL is installed, the configuration instructions are the same. For all distributions you must create a `mattermost` database and a `mattermost` database user. Failure to create these database objects or improperly referencing them from the Mattermost configuration file, `/opt/mattermost/config/config.json`, causes Mattermost to fail. The troubleshooting tips given here deal with these specific issues.
Before proceeding, confirm that your MySQL server is running. You can do this by issuing the command `mysqladmin -u root -p status`. When prompted, enter your password. If MySQL is running you should see output like the following:
> Uptime: 877134 Threads: 1 Questions: 9902 Slow queries: 0 Opens: 522
> Flush tables: 1 Open tables: 371 Queries per second avg: 0.011
If MySQL is not running, review the instructions for installation on your distribution.
<Warning>
Some of the commands used in this section alter the database. **Use these commands only if your Mattermost installation has failed.** Do not directly manipulate the MySQL database for a working Mattermost installation.
</Warning>
## The `mattermost` database
The database created during installation is named `mattermost`. If you fail to create this database or you misname it, you will see an error such as the following when you attempt to start the Mattermost server:
> [2017/09/20 17:11:37 EDT] [INFO] Pinging SQL master database
> [2017/09/20 17:11:37 EDT] [ERROR] Failed to ping DB retrying in 10 seconds
> err-Error 1044: Access denied for user 'mmuser'@'%' to database 'mattermost'
Note that MySQL is specifically denying access to the `mattermost` database. This may mean that you have failed to create a database named `mattermost` or you may have incorrectly referenced this database from the `/opt/mattermost/config/config.json` file.
**Checking that the Database Exists**
To confirm that the `mattermost` database exists, open MySQL as *root* by executing `mysql -u root -p`. When prompted, enter your password and then issue the command `show databases;`. This command displays all the databases. You should see something similar to the following:
> +--------------------+
> | Database |
> +--------------------+
> | information_schema |
> | mattermost |
> | mysql |
> | performance_schema |
> | sys |
> +--------------------+
> 5 rows in set (0.03 sec)
**No mattermost Database**
If the `mattermost` database doesn't exist, create a database named `mattermost` by opening MySQL as root and issuing the command: `create database mattermost;`.
If you accidentally created a database with the wrong name, you can remove it by issuing the command: `drop database &#123;misnamed&#125;;`.
After creating the database, attempt to restart the Mattermost server by navigating to the `/opt/mattermost` directory and entering the command `sudo -u mattermost bin/mattermost`.
**The mattermost Database Exists**
If the `mattermost` database does exist, confirm that you have defined the database driver correctly in the `/opt/mattermost/config/config.json` file. Open this file in a text editor, and review the value of `"DataSource"`. It should be:
> "mmuser:*mmuser-password*@tcp(*host-name-or-IP*:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s"
You should also confirm that `DriverName` element (found immediately above the `DataSource` element) is set to `mysql`.
If you correct an error, restart the Mattermost server by navigating to the `/opt/mattermost` directory and entering the command `sudo -u mattermost bin/mattermost`.
## The Database User
During the installation you should create a MySQL database user from the *mysql* prompt by issuing the command
samp
<code>create user 'mmuser'@'%' identified by '&#123;mmuser-password&#125;';</code>.
The `mmuser-password` value is a placeholder for the password you chose. You may also have specified an IP address rather than the wild card `%`.
<Note>
A MySQL user is fully defined by their username and the host that they access MySQL from. These elements are separated by the `@` sign. The `%` character is a wild card indicating that the user can access MySQL from any IP address. If the user you created accesses MySQL from a specific IP address such as `10.10.10.2`, please adjust your actions accordingly.
</Note>
If the user and host combination that you created does not exist, you will see an error such as:
> [2017/09/20 17:06:18 EDT] [INFO] Pinging SQL master database
> [2017/09/20 17:06:18 EDT] [ERROR] Failed to ping DB retrying in 10 seconds
> err-Error 1045: Access denied for user 'mmuser'@'localhost' (using password: YES)
**Checking that mmuser Exists**
To check that this user exists, log in to MySQL as *root*: `mysql -u root -p`.
When prompted, enter the root password that you created when installing MySQL. From the `mysql` prompt enter the command `select User, Host from mysql.user;`. You should see something like the following:
> +------------------+-----------+
> | User | Host |
> +------------------+-----------+
> | mmuser | % |
> | debian-sys-maint | localhost |
> | mysql.session | localhost |
> | mysql.sys | localhost |
> | root | localhost |
> +------------------+-----------+
> 5 rows in set (0.00 sec)
**User Doesn't Exist**
If `'mmuser'@'%'` does not exist, create this user by logging into MySQL as *root* and issuing the command:
samp
<code>create user 'mmuser'@'%' identified by '&#123;mmuser-password&#125;';</code>.
After creating a user, ensure that this user has rights to the `mattermost` database.
**User Exists**
If the user `mmuser` exists, the DataSource element of the `/opt/mattermost/config/config.json` file may be incorrect. Open this file and search for `DataSource`. Its value should be:
> "mmuser:*mmuser-password*@tcp(*host-name-or-IP*:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s"
If you correct an error, restart the Mattermost server by navigating to the `/opt/mattermost` directory and issuing the command: `sudo -u mattermost bin/mattermost`.
## The user password
Mattermost will fail if you use an incorrect password for `mmuser`. An incorrect password displays an error message such as the following:
> [2017/09/20 17:09:10 EDT] [INFO] Pinging SQL master database
> [2017/09/20 17:09:10 EDT] [ERROR] Failed to ping DB retrying in 10 seconds
> err-Error 1045: Access denied for user 'mmuser'@'localhost' (using password: YES)
**The password in \`\`config.json\`\`**
The DataSource element of the `/opt/mattermost/config/config.json` file references the `mmuser` password. Open this file and search for `DataSource`. It's value should be:
> "mmuser:*mmuser-password*@tcp(*host-name-or-IP*:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s"
Check that the password is correct. If you correct an error, restart the Mattermost server by navigating to `/opt/mattermost` and issuing the command: `sudo -u mattermost bin/mattermost`.
**Unsure of Password**
If you are not sure that the `mmuser` password is correct, attempt to log in to MySQL as `mmuser` by issuing the command `mysql -u mmuser -p`. You will be prompted for your password. If your login fails, you are not using the correct password.
With a new database installation, the easiest solution for an unknown password is to remove the existing `mmuser` and then recreating that user. You can do this by logging in to MySQL as `root` and issuing the following commands:
- `drop user mmuser;`
- `flush privileges;`
- samp
<code>create user 'mmuser'@'%' identified by '&#123;mmuser-password&#125;';</code>
If you recreate `mmuser`, ensure that this user has rights to the `mattermost` database by following the instructions in the [granting privileges to mmuser](#mysql_grants) section below.
## Insufficient user privileges
If the database exists and the username and password are correct, the `mmuser` may not have sufficient rights to access the `mattermost` database. If this is the case, you may see an error message such as:
> [2017/09/20 17:20:53 EDT] [INFO] Pinging SQL master database
> [2017/09/20 17:20:53 EDT] [ERROR] Failed to ping DB retrying in 10 seconds
> err-Error 1044: Access denied for user 'mmuser'@'%' to database 'mattermost
<Note>
Examine the error message closely. The user name displayed in the error message is the user identified in the `DataSource` element of the `/opt/mattermost/config/config.json` file. For example, if the error message reads `Access denied for user 'muser'@'%' ...`, you will know that you have misidentified the user as `muser` in the `config.json` file.
</Note>
You can check if the user `mmuser` has access to the `mattermost` database by logging in to MySQL as `mmuser` and issuing the command: `show databases;`. If this user does not have rights to view the `mattermost` database, you will not see it in the output.
> +--------------------+
> | Database |
> +--------------------+
> | information_schema |
> +--------------------+
> 1 rows in set (0.00 sec)
<div id="mysql_grants">
**Granting privileges to mmuser**
</div>
If the `mattermost` database exists and `mmuser` cannot view it, exit from MySQL and then log in again as root. Issue the command `grant all privileges on mattermost.* to 'mmuser'@'%';` to grant all rights on `mattermost` to `mmuser`.
Restart the Mattermost server by navigating to the `/opt/mattermost` directory and entering the command `sudo -u mattermost bin/mattermost`.
## Server is set to SYSTEM timezone
Mattermost customers using v7.7 or earlier may see an errors occur on servers using MySQL in cases where the server is set to SYSTEM timezone and doesn’t support named timezones. These errors can be fixed by populating the `timezone` tables on the server. Refer to the following docs for more information on loading the timezone table:
- [Linux](https://dev.mysql.com/doc/refman/5.7/en/mysql-tzinfo-to-sql.html)
- [Windows](https://dev.mysql.com/downloads/timezones.html)
<Note>
This issue has been addressed from Mattermost v7.8.
</Note>
## Maximum allowed packet
The Go MySQL driver has changed the `maxAllowedPacket` size from 4MiB to 64MiB. This is to make it consistent with the change in the server-side default value from MySQL 5.7 to MySQL 8.0.
If your `max_allowed_packet` setting is not 64MiB, update the MySQL configuration DSN with an additional parameter of `maxAllowedPacket` to match with the server-side value. Alternatively, set a value of `0` to fetch the server-side value automatically on every new connection which has a performance overhead.

View File

@@ -0,0 +1,422 @@
---
title: "Deployment troubleshooting"
---
This document summarizes common deployment troubleshooting issues and resolutions, and describes the diagnostic data to gather before opening a support ticket. Some of these suggestions can be done directly, and others may need consultation from your network administrator.
If you already know which part of your deployment is failing, start with the guide for that layer:
- [PostgreSQL troubleshooting](/deployment-guide/server/prepare-database#troubleshooting), on the database setup page under **Prepare**.
- [Docker deployment troubleshooting](/deployment-guide/server/docker-troubleshooting), alongside the container deployment steps under **Choose a deployment method**.
- [Desktop app troubleshooting](/deployment-guide/desktop/desktop-troubleshooting), at the end of **Desktop app deployment**.
- [Mobile deployment troubleshooting](/deployment-guide/mobile/mobile-troubleshooting), at the end of **Mobile app deployment**.
## Start Mattermost at system boot
To have the Mattermost Server start at system boot, the systemd unit file needs to be enabled. Run the following command:
``` sh
sudo systemctl enable mattermost.service
```
If your database is on the same system as your Mattermost Server, we recommend editing the default `/etc/systemd/system/mattermost.service` systemd unit file to add `After=postgresql.service` and `BindsTo=postgresql.service` to the `[Unit]` section.
## Run Mattermost without a proxy
Mattermost binds to 443 instead of 8065. The Mattermost binary requires the correct permissions to do that binding. You must activate the `CAP_NET_BIND_SERVICE` capability to allow the new Mattermost binary to bind to ports lower than 1024 by running the following command:
``` sh
sudo setcap cap_net_bind_service=+ep ./mattermost/bin/mattermost
```
<Note>
We highly recommend using a proxy in front of Mattermost server for up to 200 concurrent users. If you have fewer than 200 concurrent users, you can [set up TLS](/deployment-guide/server/setup-tls). If you're exceeding 200 concurrent users, you'll need [a proxy](/deployment-guide/server/setup-nginx-proxy), such as NGINX, in front of Mattermost to manage the traffic.
</Note>
## Review Mattermost logs
You can access logs for Mattermost and use them for troubleshooting. These steps assume that you have appropriate [system admin permissions](/administration-guide/onboard/advanced-permissions) to do so.
### Mattermost Server logs
- Ensure that log files are being created: Navigate to **System Console \> Environment \> Logging**, confirm that **Output logs to file** is set to **true**.
- You can obtain the path for the log files in **System Console \> Environment \> Logging \> File Log Directory**.
The resulting server log file is called `mattermost.log` and can be opened with a standard text editor or shared directly.
<Note>
For a more complete log open **System Console \> Environment \> Logging**, set **File Log Level** to **DEBUG**, then replicate the issue to log it again. Make sure to revert the file log level to **INFO** after troubleshooting to save disk space.
</Note>
If filesystem access is not possible, navigate to **System Console \> Reporting \> Server Logs** to locate the current system logs which can be copied to a file.
You can find more on logging settings [here](/administration-guide/configure/environment-configuration-settings#logging).
#### Log files not accessible
From Mattermost v11.4, log file paths are validated to ensure they remain within a designated logging root directory.
1. If log files aren't appearing in **System Console \> Reporting \> Server Logs** or support packets, check error messages in server console to see if the log file path is outside the allowed directory: `"Blocked attempt to read log file outside allowed root"` Log file paths outside the directory specified by the `MM_LOG_PATH` environment variable generate errors and are excluded from support packet downloads. If `MM_LOG_PATH` is not set, the default `logs` directory is used.
The error message will identify which configuration setting has an invalid path:
- `LogSettings.FileLocation` - main server log file
- `LogSettings.AdvancedLoggingJSON` - advanced logging file targets
- `ExperimentalAuditSettings.AdvancedLoggingJSON` - audit logging file targets
2. Choose one of these solutions:
**Option A - Use default logging directory**:
- Update your configuration to use the default `logs` directory
- Remove or update the `MM_LOG_PATH` environment variable
- Restart Mattermost server
**Option B - Configure logging root to match your log paths**:
- Set the `MM_LOG_PATH` environment variable to a directory that contains all your log files
- Ensure all configured log file paths are within this root directory
- Restart Mattermost server
3. Verify logs are accessible:
- Navigate to **System Console \> Reporting \> Server Logs**
- Confirm log entries are visible
- Generate a test support packet to verify logs are included
See the [log path restrictions](/administration-guide/manage/logging#log-path-restrictions) documentation for detailed configuration examples.
### Mattermost Desktop App logs
Access desktop app logs by going to **Help \> Show logs** from the menu bar.
Alternatively, you can access desktop app log files in the following directory:
- **Windows:** `%userprofile%\AppData\Roaming\Mattermost\logs`
- **Linux:** `~/.local/share/Mattermost/logs` OR `~/.config/Mattermost/logs`
- **MacOS:** `~/Library/Logs/Mattermost` (DMG installation) OR `~Library/Containers/Mattermost.Desktop/Data/Library/Logs/Mattermost` (Appstore installation only)
### Mattermost web logs
The browser-based app does not produce additional log files. If the app has to be debugged, use the development tools integrated in your browser for action history.
### Mattermost Push Notification Service logs
Logging for the Mattermost Push Notification Service is handled via system log with logger and is appended to `/var/log/syslog`.
## Review Mattermost environment
Put together a timeline to eliminate events prior to the error/problem occurring. For example, if you recently reconfigured your firewall and are now having connection issues it might be worth reviewing the settings or rolling back to see whether that resolves the problem.
- If the problem occurred subsequent to some period of normal operation, did anything change in the environment?
> - Was the client, host, or server upgraded?
> - Was an operating system update applied?
> - Did the network environment change? For example, was a server moved or a domain migrated?
> - Did the system (client or server) recently fail or abnormally terminate?
- How many users are impacted?
> - Is this problem affecting one, some, or all users?
> - Is the problem occurring only for a user who was recently added to the environment, such as a new employee?
> - Do differences exist between the users who are affected and the users who are not affected?
You can also search the error messages online. Existing solutions from our [forum](https://forum.mattermost.com/t/how-to-use-the-troubleshooting-forum/150) can often be found and applied.
## Connect to another server
1. Create an account at [https://community.mattermost.com](https://community.mattermost.com).
2. Erase your mobile application and reinstall it.
3. In your mobile app, enter the server URL [https://community.mattermost.com](https://community.mattermost.com) and then your login credentials to test whether the connection is working.
## Connect with another device
- If you have another mobile device available, try connecting with that to see if your issue still reproduces.
- If you don’t have another device available, check with other teammates to see if they are having the same issue.
## Opening a support ticket for self-hosted deployments
If you have a [paid subscription to a Mattermost offering](/product-overview/editions-and-offerings), such as Mattermost Professional or Mattermost Enterprise, you're entitled to open support tickets via our [online support portal](https://support.mattermost.com/hc/en-us/requests/new).
When opening a Support ticket as part of your paid subscription, it's important that you provide us with as much information as you can in a timely manner. Knowing what information is relevant can be confusing. We use the anagram C.L.U.E.S. to remember what we need:
- Configurations
- Logs
- Users affected
- Environment
- Steps to reproduce
C.L.U.E.S. represents all of the information that can clarify your issue. With these details, we can begin searching for a cause, whether it's a simple configuration change or a product bug. It also helps us when we need to escalate the issue to our developers so they can spend as much time as possible improving our product.
### General guidelines for information
Follow these guidelines when providing diagnostic data to us:
- Make sure the files you provide are as complete as possible, rather than providing a few lines. Entire log files and configurations provide us with important context.
- Provide configuration and log files in plaintext format if possible, as these are far easier for us to search than screenshots.
- Be sure to sanitize configuration and log files to remove usernames, passwords, and LDAP groups. Replace these details with example strings that contain the same special characters if possible, as special characters are common causes of configuration errors.
- Provide screenshots or screen recordings of unexpected product behavior so that we know exactly what your users are seeing.
### Configuration
#### Why we need your configuration data
On Linux systems, settings are generally stored in configuration files. Many issues can be resolved by enabling or disabling a configuration setting. In order to find a resolution, we need to have as complete a picture of your system setup as possible. This also helps us to reproduce bugs so our developers can fix them.
#### What configuration data includes
Configuration includes (but is not limited to):
- The Mattermost `config.json` file.
- The configuration for the reverse proxy, e.g. NGINX, HAProxy, AWS.
- The database configuration.
- SAML configuration when the issue is regarding SAML authentication. The configuration for the Mattermost service is in the SAML IdP.
- Any other systems that Mattermost connects to or systems that exist between the user and the Mattermost server.
#### How to access your configuration data
**Mattermost configuration**
The Mattermost configuration is usually stored at `/opt/mattermost/config/config.json`. If you've migrated the Mattermost configuration to the database, you can get the configuration using `mmctl` or by running this database query:
``` SQL
SELECT Value FROM Configurations WHERE Active = 1;
```
**Reverse Proxy configuration**
NGINX usually splits its configuration into two parts: the main server configuration at `/etc/nginx/nginx.conf`, and a virtual server configuration. On Ubuntu, this is stored in `/etc/nginx/sites-available`. Providing both of these configuration files is helpful, but providing the latter is more important.
**SAML configuration**
If the issue you're seeing is with SAML login, we will need to see the full configuration for the Mattermost service in the SAML provider. The configuration for the Mattermost service is in the SAML IdP. Providing screenshots similar to the ones in the setup documentation is sufficient because most SAML providers are configured using a web interface.
**LDAP configuration**
The LDAP administrator should confirm the correct values for the following Mattermost LDAP settings:
- LDAP server hostname.
- LDAP connection port, security, and certificates.
- BaseDN, bind username, and bind password.
- User, Group, Guest, and Admin filters.
- Display attributes.
These can be provided as a text file or as screenshots from the LDAP server.
**Other configurations**
If you're experiencing an issue on mobile, and you're using an MDM or VPN to connect to the server, those configurations will be necessary to diagnose the problem. A system admin for the external system should be able to provide you with the configuration.
### Logs
#### Why we need them
Nearly all computer systems have logs of errors and application behavior that can show us what's happening when an application is running. Error logs are invaluable when diagnosing a problem, but only if they're as complete as possible.
#### What logs are available
**Mattermost**
Mattermost has two log files, one for general messages and the other for notification-related messages. These are found at:
- `/opt/mattermost/logs/mattermost.log`
- `/opt/mattermost/logs/notification.log`
**Proxy**
The location of these depend on your proxy configuration, but a good place to start looking is in `/var/log`. Your proxy administrator should be able to help you find the logs.
**Database**
PostgreSQL and MySQL have different logs, and their location varies based on your configuration. If the issue is related to database connectivity, check the database documentation to locate the logs.
**SAML, LDAP, and other systems**
Your organization's system admin should be able to find these for you.
#### How to access logs
**Mattermost**
Make sure [debug logging is enabled](/administration-guide/manage/logging#how-do-i-enable-debug-logging) so that we can get the most information from the logs. To do this, go to **System Console \> Environment \> Logging**, then set both **Console File Level** and **File Log Level** to **DEBUG**. Remember to save your changes.
If the behavior started at a known time or date, use `journalctl` to get the logs like this:
``` sh
sudo journalctl -u mattermost --since "2020-08-23 17:15:00" > mattermost_journalctl.log
```
Replace 2020-08-23 17:15:00 with the date and time (relative to the server) when the behavior started. To get the server time, use the `date` command. If the log files generated are too large to send, compress them with this command:
``` sh
tar -czf /tmp/mattermost.log.tgz
```
The compressed logs will be located on the server at `/tmp/mattermost.log.tgz`.
If the compressed file is still too big, use these commands to split the compressed file into two or more 20MB files:
``` sh
mkdir -p /tmp/mattermost-logs
cd /tmp/mattermost-logs
tar czf - /opt/mattermost/logs/mattermost.log | split -b 20m - mattermost.log.tgz.
```
The compressed files will be located on the server at `/tmp/mattermost-logs` and be named `mattermost.log.tgz.aa`, `mattermost.log.tgz.ab`, and so on. Use a file transfer client that supports SSH/SFTP, such as Cyberduck, to copy these files from the server.
If you are experiencing issues with Elasticsearch, LDAP, or the database, you can enable trace logging in `config.json` by setting `Trace` to `true` under their respective settings. Combining this with `DEBUG` level file log output will result in huge log files, so only leave trace logging on long enough to replicate the behavior. The resulting logs will also contain a lot more sensitive data, including user data, so be sure to sanitize it completely before sharing it with us.
**System logs**
The location of log files for other systems varies, but a good way to get the logs for all processes on the Mattermost server is to use `journalctl` like this:
``` sh
sudo journalctl --since "2020-08-23 17:15:00" > mattermost_journalctl.log
```
Replace 2020-08-23 17:15:00\` with the date and time (relative to the server) when the error occurred. You can use `--until` with the same timestamp format to get the logs between two times:
``` sh
sudo journalctl --since "2020-08-23 17:15:00" --until "2020-08-23 16:30:00" > mattermost_journalctl.log
```
### Users affected
#### Why we need it
Mattermost servers are chaotic places. Thousands of posts, websocket actions, and webhook calls happen every second while users can be in dozens of channels across multiple teams. Knowing which users are affected by a problem can help us sift through all this information to find the root cause.
#### What information to include
This should be a detailed explanation of anything the end users who are reporting the unexpected behavior have in common. This includes (but is not limited to):
- Team and Channel memberships, including Direct and Group Messages.
- Authentication methods.
- Client operating system and app versions.
- How users connect to the Mattermost server.
- Any other things these users have in common such as when they joined, whether their login information recently changed, or if they are being synchronized via LDAP.
Note for Agents: This information is also required:
- Customer name
- Customer contacts
- Customer license, e.g. Enterprise/Professional
- Customer tier
### Environment
Where the Mattermost server sits in your architecture has a lot of impact on potential issues. For example, a misconfigured proxy server can prevent users from connecting even if there's nothing wrong with Mattermost.
#### What information to include
Because of this, having a complete picture of the servers and network that the Mattermost server operates in is key to solving problems. This includes (but is not limited to):
- Mattermost version (e.g. 7.3.0, 7.8.3)
- Server OS and version (e.g. RHEL7, Ubuntu 20.04)
- Any orchestration/automation used like Docker or Kubernetes
- Reverse proxy and version (e.g. NGINX 1.16)
- Database type and version (e.g. PostgreSQL 14)
- SAML provider (e.g. Windows Server 2012 Active Directory, Okta, KeyCloak)
- LDAP provider (e.g. Windows Server 2016 Active Directory, Okta, OpenLDAP)
- The type and version of any proxies or VPNs on the network that the Mattermost server is connecting through
Be as specific as possible when describing the environment. If you are seeing errors like **Connection Refused** be sure to include any firewalls or filtering proxies that may be on your network, either inbound or outbound.
**Examples**
Mattermost server
> - External hostname: mattermost.example.com
> - Internal hostname: mattermost.lan
> - Mattermost v7.3.0
> - Zoom plugin v1.4.1
> - NGINX v1.18.0
Database server
> - Internal hostname: postgresql.lan
> - PostgreSQL v13
> - LDAP Provider - 192.168.1.102
> - Internal hostname: ldap.lan
> - OpenLDAP 2.4.54 (Docker container)
Mattermost servers
> - Hostnames: mm1.local.lan, mm2.local.lan, mm3.local.lan, mm4.local.lan
Mattermost server versions
> - mm1-3: 5.25.4
> - mm4: 5.21.0
Proxy server
> - External hostname: mattermost.example.com
> - Internal hostname: proxy.local.lan
> - NGINX v1.16.0
Database servers
> - Hostnames: db1.local.lan, db2.local.lan, db3.local.lan
> - Primary: db1.local.lan
> - Read-Only: db2.local.lan, db3.local.lan
> - PostgreSQL v13
Elasticsearch server
> - Hostname: elastic.local.lan
> - Elasticsearch v7.9 with these plugins
> - analysis-icu
### Steps to reproduce
#### What it is
If the behavior only happens when the user performs a specific action, providing detailed steps to reproduce it will help us make sure we find and fix the right bug. These details should be as descriptive as possible, but nothing is better than a screenshot or a screen recording of the behavior.
A short summary of the steps to reproduce is also helpful. If you want some examples, look at the bug tickets on some Mattermost Jira tickets.
#### How to provide these details
**macOS**
Press <kbd>⌘</kbd> <kbd>⇧</kbd> <kbd>5</kbd> to open the screen recording tool and select the region of the screen you want to record. To take a screenshot, press <kbd>⌘</kbd> <kbd>⇧</kbd> <kbd>4</kbd> and select the region to take a screenshot. The screenshot files are placed on the desktop by default.
**Windows**
Press <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>S</kbd> to open the snipping tool to take a screenshot. If you want to take a screen recording you'll need to install third-party software such as [OBS](https://obsproject.com/).
**iOS**
Take a screenshot or screen recording [on iPhone](https://support.apple.com/guide/iphone/take-a-screenshot-iphc872c0115/ios).
**Android**
Take a screenshot or record your screen on your [Android device](https://support.google.com/android/answer/9075928?hl=en).
## Appendix
**A note on mobile issues**
Because the mobile app doesn't have a debug mode, diagnosing issues stemming from user data requires a proxy like Charles or mitmproxy. These will intercept and record traffic from the client which can then be replayed to reproduce issues. Talk to a [Mattermost Expert](https://mattermost.com/contact-sales/) for help setting these up.
**SAML login issues**
If the issue is with SAML login, one important piece of context is the SAML login flow. This contains headers and authentication information that can reveal issues that are easy to fix. Follow these instructions to view the SAML login flow if you are experiencing SAML authentication.
### Checking keys and certificates
Key and certificate files should never be shared, but if the error indicates a problem with the format of a key or certificate, then you should verify the format of the keys and certificates by running this command:
``` sh
cat -A /path/to/key-or.cert
```
The output must meet these criteria exactly to be valid:
- Start with `-----BEGIN CERTIFICATE-----$`.
- All lines must end with `$`. If they end with `^M$` then convert them to UNIX line endings with `dos2unix`.
- End with `-----END CERTIFICATE-----$`.

View File

@@ -0,0 +1,320 @@
---
title: "Software and hardware requirements"
---
This guide outlines minimum software and hardware requirements for deploying Mattermost. Requirements may vary based on utilization and observing performance of pilot projects is recommended prior to scale out.
## Deployment overview
Please see the [Application architecture](/deployment-guide/application-architecture) documentation for a summary of software systems and components whose requirements are described in this document.
## Software requirements
### Client software
#### Desktop apps
<table>
<thead>
<tr>
<th>Operating System</th>
<th>Self-Hosted Technical Requirement</th>
<th>Cloud Technical Requirement</th>
</tr>
</thead>
<tbody>
<tr>
<td>Windows</td>
<td>Windows 11+</td>
<td>Windows 11+</td>
</tr>
<tr>
<td>Mac</td>
<td>macOS 14+</td>
<td>macOS 14+</td>
</tr>
<tr>
<td>Linux</td>
<td>Ubuntu LTS releases 22.04 or later</td>
<td>Ubuntu LTS releases 22.04 or later</td>
</tr>
</tbody>
</table>
Though not officially supported, the Linux desktop app also runs on RHEL/CentOS 7+.
##### Flatpak package requirements (Linux)
From Mattermost Desktop v6.1, Flatpak packages are available for Linux (currently in beta). The Flatpak version requires:
- Flatpak runtime installed on the system
- Freedesktop Platform/SDK 25.08
- Electron BaseApp 25.08
- Access to Flathub or compatible Flatpak repository for dependencies
Flatpak packages are available for x86_64 (Intel/AMD) and aarch64 (ARM) architectures. The Flatpak version includes Wayland display server support enabled by default.
<Note>
- <code>\*</code> Integrated Windows Authentication is not supported by Mattermost desktop apps. If you use ADFS we recommend [configuring intranet forms-based authentication for devices that do not support WIA](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configure-intranet-forms-based-authentication-for-devices-that-do-not-support-wia).
- From Windows Desktop v6.1.0, the MSI installer installs per-machine (system-wide) by default and requires administrator privileges for installation. This meets enterprise compliance requirements.
- The minimum content size is 800 x 600 pixels.
</Note>
#### PC web
<table>
<thead>
<tr>
<th>Browser</th>
<th>Self-Hosted Technical Requirement</th>
<th>Cloud Technical Requirement</th>
</tr>
</thead>
<tbody>
<tr>
<td>Chrome</td>
<td>v150+</td>
<td>v150+</td>
</tr>
<tr>
<td>Firefox</td>
<td>v140+</td>
<td>v140+</td>
</tr>
<tr>
<td>Safari</td>
<td>v26.2+</td>
<td>v26.2+</td>
</tr>
<tr>
<td>Edge</td>
<td>v150+</td>
<td>v150+</td>
</tr>
</tbody>
</table>
<code>\*</code> Internet Explorer (IE11) is no longer supported. We recommend using the [Mattermost desktop app](https://mattermost.com/apps/) or another supported browser. See [this forum post](https://forum.mattermost.com/t/mattermost-is-dropping-support-for-internet-explorer-ie11-in-v5-16/7575) to learn more.
#### Mobile apps
<table>
<thead>
<tr>
<th>Operating System</th>
<th>Technical Requirement</th>
</tr>
</thead>
<tbody>
<tr>
<td>iOS</td>
<td>iPhone 8+ devices and later with iOS 16.0+</td>
</tr>
<tr>
<td>Android</td>
<td>Android devices with Android 7+</td>
</tr>
</tbody>
</table>
<Note>
- <code>\*</code> Integrated Windows Authentication is not supported by Mattermost mobile apps. If you use ADFS we recommend [configuring intranet forms-based authentication for devices that do not support WIA](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configure-intranet-forms-based-authentication-for-devices-that-do-not-support-wia).
- The minimum and target content size is 320 x 460 pixels, matching the available space when the mobile app is opened in Safari on the minimum supported iOS device.
- The Mattermost mobile app for Android isn't supported on Chromebooks. Access Mattermost using the Chrome web browser, or install the web app as a Progressive Web App (PWA) directly from the browser for an app-like experience with a desktop icon and windowed view.
</Note>
#### Mobile web
<table>
<thead>
<tr>
<th>Browser</th>
<th>Technical Requirement</th>
</tr>
</thead>
<tbody>
<tr>
<td>iOS</td>
<td>iOS 16.0+ with Safari 26.2+ or Chrome 150+</td>
</tr>
<tr>
<td>Android</td>
<td>Android 7+ with Chrome 150+</td>
</tr>
</tbody>
</table>
#### Email client
- *Desktop clients:* Outlook 2010+, Apple Mail version 7+, Thunderbird 38.2+
- *Web based clients:* Entra ID, Outlook, Gmail, Yahoo, AOL
- *Mobile clients:* iOS Mail App (iOS 7+), Gmail Mobile App (Android, iOS)
### Server software
#### Mattermost server operating system
- Ubuntu, Debian Buster, CentOS 6+, CentOS 7+, Red Hat Enterprise Linux 7+, Oracle Linux 6+, Oracle Linux 7+.
- Using the Mattermost [Docker deployment](https://github.com/mattermost/docker) on a Docker-compatible operating system (Linux-based OS) is still recommended.
<Important>
Starting with Mattermost Server v12.0 (October 2026), Red Hat Enterprise Linux (RHEL) 7 and RHEL 8 will no longer be supported deployment targets. Mattermost v11.11 (September 2026) will be the last release to support RHEL 7 and RHEL 8. RHEL 9, Ubuntu 22.04/24.04 LTS, Debian Bookworm, and container-based deployments will remain fully supported. If you're running RHEL 7 or RHEL 8, plan to upgrade to RHEL 9 or migrate to another supported platform before the v12.0 release. See the [forum post](https://forum.mattermost.com/t/starting-with-mattermost-v12-0-october-2026-rhel-7-and-rhel-8-are-no-longer-supported-deployment-targets/25974) for full details and migration options.
</Important>
While community support exists for Fedora, FreeBSD, and Arch Linux, Mattermost does not currently include production support for these platforms.
#### Database software
- PostgreSQL 14.0+
Amazon Aurora equivalents of PostgreSQL is also supported. Our [Migration Guide](https://docs.mattermost.com/administration-guide/manage/admin/postgres-migration.html) outlines the steps, tools and support available for migrating from MySQL to PostgreSQL.
<Important>
- MariaDB v10+ no longer functions as a MySQL drop-in replacement, and it's not supported for Mattermost due to the requirement of MySQL 5.7.12. Prior versions of MariaDB were not officially supported but may have functioned in older Mattermost releases. If you are running MariaDB now, migrating from MariaDB to the MySQL equivalent is recommended.
- MySQL deployments requiring searching in Chinese, Japanese, and Korean languages require the configuration of [ngram Full-Text parser](https://dev.mysql.com/doc/refman/8.4/en/fulltext-search-ngram.html). For searching two characters, you will also need to set `ft_min_word_len` and `innodb_ft_min_token_size` to `2` and restart MySQL. See [CJK discussion](https://github.com/mattermost/mattermost/issues/2033#issuecomment-183872616) for details.
</Important>
##### Minimum PostgreSQL database support policy
To make planning easier and ensure your Mattermost deployment remains fast and secure, we are introducing a policy for updating the minimum supported version of PostgreSQL. The oldest supported PostgreSQL version Mattermost supports will match the oldest version supported by the PostgreSQL community. This ensures you benefit from the latest features and security updates.
This policy change takes effect from Mattermost v10.6, where the minimum PostgreSQL version required will be PostgreSQL 13. This aligns with the PostgreSQL community's support policy, which provides 5 years of support for each major version.
<Note>
Mattermost v10.6 is not an [Extended Support Release (ESR)](/product-overview/release-policy#extended-support-releases). Going forward, this database version support policy will only apply to ESR releases.
</Note>
When a PostgreSQL version reaches its end of life (EOL), Mattermost will require a newer version starting with the next scheduled ESR release. This means the following future PostgreSQL minimum version increases as follows:
<table>
<thead>
<tr>
<th>Mattermost Version</th>
<th>Release Date</th>
<th>Minimum PostgreSQL Version</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="/product-overview/unsupported-legacy-releases#release-v9-11-extended-support-release">v9.11 ESR</a></td>
<td>2024-8-16</td>
<td>11.x</td>
</tr>
<tr>
<td><a href="/product-overview/mattermost-v10-changelog#release-v10-5-extended-support-release">v10.5 ESR</a></td>
<td>2025-2-14</td>
<td>11.x</td>
</tr>
<tr>
<td><a href="/product-overview/mattermost-v10-changelog#release-v10-6-feature-release">v10.6</a></td>
<td>2025-3-14</td>
<td>13.x</td>
</tr>
<tr>
<td><a href="/product-overview/mattermost-v10-changelog#release-v10-11-extended-support-release">v10.11 ESR</a></td>
<td>2025-8-15</td>
<td>13.x</td>
</tr>
<tr>
<td><a href="/product-overview/mattermost-v11-changelog#release-v11-7-extended-support-release">v11.7 ESR</a></td>
<td>2026-5-15</td>
<td>14.x (EOL 2026-11-12)</td>
</tr>
</tbody>
</table>
Customers will have 9 months to plan, test, and upgrade their PostgreSQL version before the new requirement takes effect. This policy aims to provide clarity and transparency so you can align database upgrades with the Mattermost release schedule. Contact a [Mattermost Expert](https://mattermost.com/contact-sales/). to discuss your options.
##### Database Search limitations
Common limitations:
- Only the initial **1 MB** of the file content is available for search, even though much bigger files can be uploaded.
Search limitations on PostgreSQL:
- Email addresses do not return results.
- Hashtags or recent mentions of usernames containing a dash do not return search results.
- Terms containing a dash return incorrect results as dashes are ignored in the search query.
- Limitations set by [PostgreSQL itself](https://www.postgresql.org/docs/current/textsearch-limitations.html):
- One of them is: `The length of a tsvector (lexemes + positions) must be less than 1 megabyte`, which means that, based on the file content, even files with content less than 1 MB won't be searchable if they hit the `tsvector` limit of 1 MB.
- If any of the above is an issue, you can [set up and enable enterprise search](/deployment-guide/scale/enterprise-search).
##### MySQL Support
[MySQL database support](/deployment-guide/server/prepare-mattermost-mysql-database) is being deprecated starting with Mattermost v11. See the [PostgreSQL migration](/administration-guide/manage/admin/postgres-migration) documentation for guidance on migrating from MySQL to PostgreSQL.
- Search limitations on MySQL: Hashtags or recent mentions of usernames containing a dot do not return search results.
- The migration system requires the MySQL database user to have additional <code>EXECUTE</code>, <code>CREATE ROUTINE</code>, <code>ALTER ROUTINE</code> and <code>REFERENCES</code> privileges to run schema migrations.
- MariaDB v10+ no longer functions as a MySQL drop-in replacement, and it's not supported for Mattermost due to the requirement of MySQL 5.7.12. Prior versions of MariaDB were not officially supported but may have functioned in older Mattermost releases. If you are running MariaDB now, migrating from MariaDB to the MySQL equivalent is recommended.
- Deployments requiring searching in Chinese, Japanese, and Korean languages require MySQL 5.7.6+ and the configuration of [ngram Full-Text parser](https://dev.mysql.com/doc/refman/5.7/en/fulltext-search-ngram.html). For searching two characters, you will also need to set `ft_min_word_len` and `innodb_ft_min_token_size` to `2` and restart MySQL. See [CJK discussion](https://github.com/mattermost/mattermost/issues/2033#issuecomment-183872616) for details.
<Important>
MySQL 8.0.22 contains an [issue with JSON column types](https://bugs.mysql.com/bug.php?id=101284) changing string values to integers which is preventing Mattermost from working properly. Users are advised to avoid this database version.
</Important>
In MySQL 8.0.4, the default authentication plugin was changed from `mysql_native_password` to `caching_sha2_password`. Therefore, you will need to enable `mysql_native_password` by adding the following entry in your MySQL configuration file:
> ``` text
> [mysqld]
> default-authentication-plugin=mysql_native_password
> ```
In MySQL 8, the default collation changed to `utf8mb4_0900_ai_ci` ([https://dev.mysql.com/doc/mysqld-version-reference/en/optvar-changes-8-0.html](https://dev.mysql.com/doc/mysqld-version-reference/en/optvar-changes-8-0.html)). Therefore, if you update your MySQL installation to version 8, you'll need to convert your database tables to use the new default collation:
``` sql
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
```
If this change isn't made, tables in the database may end up having different collations which will cause errors when executing queries.
In MySQL versions 8.0.0 - 8.0.11 `ADMIN` is a [reserved keyword](https://dev.mysql.com/doc/refman/8.0/en/keywords.html), which is why our requirement for MySQL is version 8.0.12.
MySQL 8.0.22 contains an [issue with JSON column types](https://bugs.mysql.com/bug.php?id=101284) changing string values to integers which is preventing Mattermost from working properly. Users are advised to avoid this database version.
## Hardware requirements
Usage of CPU, RAM, and storage space can vary significantly based on user behavior. These hardware recommendations are based on traditional deployments and may grow or shrink depending on how active your users are.
Moreover, memory requirements can be driven by peak file sharing activity. Recommendation is based on default 50 MB maximum file size, which can be [adjusted from the System Console](/administration-guide/configure/environment-configuration-settings#maximum-file-size). Changing this number may change memory requirements.
For deployments larger than 2,000 users, it is recommended to use the Mattermost open source load testing framework to simulate usage of your system at full scale: [https://github.com/mattermost/mattermost-load-test-ng](https://github.com/mattermost/mattermost-load-test-ng).
Mattermost supports any 64-bit x86 processor architecture.
### Hardware requirements for team deployments
Most small to medium Mattermost team deployments can be supported on a single server with the following specifications based on registered users:
- 1 - 1,000 users - 1 vCPU/cores, 2 GB RAM
- 1,000 - 2,000 users - 2 vCPUs/cores, 4 GB RAM
### Hardware requirements for enterprise deployments (multi-server)
#### Scale requirements
For Enterprise Edition deployments with a multi-server setup, see [our scaling guide](/deployment-guide/scale/scaling-for-enterprise).
It is highly recommended that pilots are run before enterprise-wide deployments in order to estimate full scale usage based on your specific organizational needs. You can use the Mattermost open source load testing framework to simulate usage of your system: [https://github.com/mattermost/mattermost-load-test-ng](https://github.com/mattermost/mattermost-load-test-ng).
Mattermost's [performance monitoring](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring) tools can be used for detailed performance measurements and to inspect the running system to ensure sizing and installation is correct.
#### System requirements
For Enterprise Edition deployments with a multi-server setup, we highly recommend the following systems to support your Mattermost deployment:
- Prometheus to track system health of your Mattermost deployment, through [performance monitoring feature](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring) available in Mattermost Enterprise.
- Grafana to visualize the system health metrics collected by Prometheus with the [performance monitoring feature](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring). Grafana 5.0.0 and later is recommended.
- Elasticsearch to support highly efficient database searches in a cluster environment. Elasticsearch v8.x and v9.x are supported, and Elasticsearch v9.x or AWS OpenSearch is recommended. [Learn more](/deployment-guide/scale/enterprise-search).
- AWS S3 or any S3-compatible service. Mattermost is compatible with object storage systems which implement the S3 API. You can also use local storage or a network drive using NFS. Learn more about file storage configuration options [in our documentation](/administration-guide/configure/environment-configuration-settings#file-storage).

View File

@@ -0,0 +1,448 @@
---
title: "Configuring transport encryption"
---
<PlanAvailability slug="ent-plus" />
The components of the Mattermost setup are shown in the following diagram, including the transport encryption used. Aside from the encryption between the nodes of the Mattermost cluster, all transports rely on TLS encryption.
<Note>
The transport between the Application servers is not used by default and requires additional setup steps. Enhancing the core product to include automatic encryption between cluster nodes is in progress and planned for a later release.
</Note>
![Components of the Mattermost setup where all transports rely on TLS encryption.](/images/transport-encryption.png)
## Configuring proxy to Mattermost transport encryption
Mattermost is able to encrypt the traffic between the proxy and the application server using TLS.
### Prerequisites
- Operational Mattermost server or cluster.
- Authentication credentials for Mattermost user on application server.
### Example environment
In this scenario there is one Mattermost application server and one NGINX server, both running Ubuntu 20.04, with the following IPs:
- **transport-encryption-mattermost1:** 10.10.250.146
- **transport-encryption-nginx:** 10.10.250.107
### Configuring NGINX
On the NGINX server, connect to both servers with a sudo or root user. Open the Mattermost proxy configuration and search for the following line twice:
``` text
proxy_pass http://backend;
```
Change the protocol from `http` to `https`:
``` text
proxy_pass https://backend;
```
Afterwards do not reload the NGINX server yet to minimize the downtime of the service.
### Configuring Mattermost
On the Mattermost server, change to the config directory of Mattermost and generate a self-signed certificate that will be used to encrypt the traffic between the proxy server and the application server.
**Note:** Alternatively you can sign a certificate from your company's CA.
``` sh
cd /opt/mattermost/config
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
chown root:mattermost *.pem
chmod 640 *.pem
```
Once complete, open the file `config.json` and modify the values `ConnectionSecurity`, `TLSCertFile` and `TLSKeyFile` in the `ServiceSettings` section.
**Before**
``` json
{
"ServiceSettings": {
"SiteURL": "https://transport-encryption.dev.example.com",
"WebsocketURL": "",
"LicenseFileLocation": "",
"ListenAddress": ":8065",
"ConnectionSecurity": "",
"TLSCertFile": "",
"TLSKeyFile": "",
"...":"..."
},
"...":"..."
}
```
**After**
``` json
{
"ServiceSettings": {
"SiteURL": "https://transport-encryption.dev.example.com",
"WebsocketURL": "",
"LicenseFileLocation": "",
"ListenAddress": ":8065",
"ConnectionSecurity": "TLS",
"TLSCertFile": "/opt/mattermost/config/cert.pem",
"TLSKeyFile": "/opt/mattermost/config/key.pem",
"...":"..."
},
"...":"..."
}
```
Restart the Mattermost server and ensure it's up and running:
``` sh
sudo systemctl restart mattermost
systemctl status mattermost
```
``` text
● mattermost.service - Mattermost
Loaded: loaded (/etc/systemd/system/mattermost.service; static; vendor preset: enabled)
Active: active (running) since Mon 2019-10-28 16:45:29 UTC; 1h 15min ago
[...]
```
Finally, on the **NGINX server**, reload the configuration to ensure that requests are sent on HTTPS:
``` sh
sudo systemctl reload nginx
```
## Configuring database transport encryption
Mattermost is able to encrypt the traffic between the database and the application using TLS. This guide describes the setup steps for a single, separate MySQL server.
### Prerequisites
- Operational Mattermost server or cluster.
- Operational MySQL server.
- Confirmed connectivity between Mattermost and MySQL server.
- Authentication credentials for Mattermost user on MySQL server.
### Example environment
In this scenario there is one Mattermost application server and one MySQL server, both running Ubuntu 20.04, with the following IPs:
- **transport-encryption-mattermost1:** 10.10.250.146
- **transport-encryption-mysql1:** 10.10.250.148
### Configuring MySQL
As a first step, connect to both servers with a sudo or root user.
Execute the following command to prepare the server for SSL connections:
``` sh
sudo mysql_ssl_rsa_setup --uid=mysql
```
This generates self-signed certificates in `/var/lib/mysql/` that the MySQL server uses to encrypt the connection. If you would like to use certificates from your company CA, please follow the MySQL documentation for configuration steps.
**Note:** Optionally, it can be enforced that all connections must be made via a local socket connection or TLS. To do this, open `/etc/mysql/mysql.conf.d/mysqld.cnf` and append the following line to the file:
``` text
require_secure_transport = ON
```
Any connection to the MySQL server must now be made with secure transport enabled.
Last but not least, restart the server and confirm it is up and running:
``` sh
systemctl restart mysql
systemctl status mysql
```
``` text
● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2019-10-18 16:41:25 UTC; 2s ago
Process: 8380 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid (code=exited, status=0/SUCCESS)
Process: 8360 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 8382 (mysqld)
Tasks: 27 (limit: 2361)
CGroup: /system.slice/mysql.service
└─8382 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
Oct 18 16:41:25 transport-encryption-mysql1 systemd[1]: Stopped MySQL Community Server.
Oct 18 16:41:25 transport-encryption-mysql1 systemd[1]: Starting MySQL Community Server...
Oct 18 16:41:25 transport-encryption-mysql1 systemd[1]: Started MySQL Community Server.
```
### Configuring Mattermost
On the Mattermost server, open the file `config.json` and look for the `DataSource` value in the `SqlSettings` section. It should look similar to this:
``` text
"DataSource": "mmuser:sad09zusaopdhsad123@tcp(10.10.250.148:3306)/mattermost?charset=utf8mb4,utf8\u0026writeTimeout=30s",
```
At the end of the line, we can configure that TLS must be turned on with the `tls` flag which supports the following values:
- true (Require TLS + a trusted certificate)
- false
- skip-verify (Require TLS + accept self-signed)
- preferred (Try TLS, fallback to unencrypted)
In our case we need to use `skip-verify` since we use a self-signed certificate. The configuration setting will now look like this:
``` text
"DataSource": "mmuser:sad09zusaopdhsad123@tcp(10.10.250.148:3306)/mattermost?charset=utf8mb4,utf8\u0026writeTimeout=30s&tls=skip-verify",
```
If you're running Mattermost in a cluster, be sure to update the value on each node of the cluster. If you are using configuration in the database, be sure to update the `systemd` unit file and enable TLS for the configuration store.
Once complete, restart the Mattermost server and ensure the system is operational:
``` sh
sudo systemctl restart mattermost
systemctl status mattermost
```
``` text
● mattermost.service - Mattermost
Loaded: loaded (/etc/systemd/system/mattermost.service; static; vendor preset: enabled)
Active: active (running) since Fri 2019-10-18 16:47:08 UTC; 3s ago
Process: 3424 ExecStartPre=/opt/mattermost/bin/pre_start.sh (code=exited, status=0/SUCCESS)
Main PID: 3443 (mattermost)
Tasks: 20 (limit: 2361)
CGroup: /system.slice/mattermost.service
├─3443 /opt/mattermost/bin/mattermost --config=mysql://mmuser:sad09zusaopdhsad123@tcp(10.10.250.148:3306)/mattermost?charset=utf8mb4,utf8&writeTimeout=30s&tls=skip-verify
└─3459 plugins/com.mattermost.nps/server/dist/plugin-linux-amd64
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8637397,"caller":"scheduler/worker.go:36","msg":"Worker started","worker":"Plugins"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8639545,"caller":"jobs/jobs_watcher.go:38","msg":"Watcher Started"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"info","ts":1571417228.8641603,"caller":"jobs/schedulers.go:72","msg":"Starting schedulers."}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8645394,"caller":"app/web_hub.go:436","msg":"Hub for index 0 is starting with goroutine 3923"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8648505,"caller":"app/web_hub.go:436","msg":"Hub for index 1 is starting with goroutine 3924"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.8656101,"caller":"web/static.go:31","msg":"Using client directory at /opt/mattermost/client"}
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"info","ts":1571417228.8681324,"caller":"commands/server.go:105","msg":"Sending systemd READY notification."}
Oct 18 16:47:08 transport-encryption-mattermost1 systemd[1]: Started Mattermost.
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.9003174,"caller":"jobs/schedulers.go:166","msg":"Next run time for scheduler","scheduler_name":"MigrationsSched
Oct 18 16:47:08 transport-encryption-mattermost1 mattermost[3443]: {"level":"debug","ts":1571417228.9025588,"caller":"jobs/schedulers.go:166","msg":"Next run time for scheduler","scheduler_name":"PluginsSchedule
```
## Configuring cluster transport encryption
Mattermost is able to encrypt the messages sent within the cluster of a deployment using SSH tunneling. The guide walks through the deployment of this solution on Ubuntu 20.04, but it can be adapted for any Linux operating system.
While this document only describes the configuration of a three-node cluster, it is by no means limited to that number.
### Prerequisites
- SSH port whitelisted between each node of the deployment.
- Active ufw/iptables on each node.
- Access to the root/sudo user of each node for configuration.
- A configured Mattermost cluster.
- Mattermost running with a dedicated service user.
- Mattermost service is stopped on each cluster node.
<Note>
Support on the application level is currently in development and, when available, will deprecate this document.
</Note>
### Example environment
In this scenario there are three application nodes in our environment with the following hostname/IP mapping:
- **transport-encryption-mattermost1:** 10.10.250.146
- **transport-encryption-mattermost2:** 10.10.250.231
- **transport-encryption-mattermost3:** 10.10.250.165
### Preparations
- Connect to each Mattermost server with a sudo or root user.
- Make a note of the IP from each cluster member used for the internal communication.
- Ensure `AllowTcpForwarding` is enabled in `/etc/ssh/sshd_config` of each cluster node.
### SSH authentication
On each node, generate a SSH key-pair for the service account. In our scenario this is called `mattermost`:
``` sh
sudo -u mattermost ssh-keygen -t rsa
```
``` text
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mattermost/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mattermost/.ssh/id_rsa.
Your public key has been saved in /home/mattermost/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:redacted mattermost@transport-encryption-mattermost1
```
The location of the SSH key itself is irrelevant if company policies require the usage of another storage location.
Next, ensure that the SSH public key of each node is added to the `authorized_keys` file of the other nodes of the cluster. To do so, copy the contents of `/home/mattermost/.ssh/id_rsa.pub` of nodes 2 and 3, and add it to `/home/mattermost/.ssh/authorized_keys` of node 1.
Repeat this step for each node of the cluster. As a result, each node should be able to establish an SSH connection to the other nodes of the cluster.
<Note>
This service account can be separate from the service account already used for the Mattermost `systemd` service itself. It's important that this service account is allowed to create a SSH tunnel with port forwarding, but it doesn't require any additional permissions.
</Note>
### ufw configuration
As a next step, allow SSH access from each of the other member nodes, e.g.:
- mattermost1 allows from mattermost2 and mattermost3
- mattermost2 allows from mattermost1 and mattermost3
- mattermost3 allows from mattermost1 and mattermost2
To do so, we add an exception in the firewall. The commands for `mattermost1` look as follows:
``` sh
sudo ufw allow from 10.10.250.231/32 to any port ssh
sudo ufw allow from 10.10.250.165/32 to any port ssh
sudo ufw status
```
``` text
Rule added
Rule added
Status: active
To Action From
-- ------ ----
22/tcp ALLOW 10.10.250.10
8065/tcp ALLOW Anywhere
22/tcp ALLOW 10.10.250.231
22/tcp ALLOW 10.10.250.165
```
Repeat the same steps on the other nodes, replacing the IPs with the ones from the other member nodes. Do so for each member node, excluding the node itself.
Next, open `/etc/ufw/after.rules` and add the following block to the bottom of the file:
``` text
*nat
:POSTROUTING ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]
-A OUTPUT -p tcp -d 10.10.250.231 --dport 8075 -j DNAT --to-destination 127.0.0.1:18075
-A OUTPUT -p tcp -d 10.10.250.231 --dport 8074 -j DNAT --to-destination 127.0.0.1:18074
-A OUTPUT -p tcp -d 10.10.250.165 --dport 8075 -j DNAT --to-destination 127.0.0.1:28075
-A OUTPUT -p tcp -d 10.10.250.165 --dport 8074 -j DNAT --to-destination 127.0.0.1:28074
COMMIT
```
Two lines always belong to a single node, so in a deployment with four nodes:
``` text
-A OUTPUT -p tcp -d ip_node_2 --dport 8075 -j DNAT --to-destination 127.0.0.1:18075
-A OUTPUT -p tcp -d ip_node_2 --dport 8074 -j DNAT --to-destination 127.0.0.1:18074
-A OUTPUT -p tcp -d ip_node_3 --dport 8075 -j DNAT --to-destination 127.0.0.1:28075
-A OUTPUT -p tcp -d ip_node_3 --dport 8074 -j DNAT --to-destination 127.0.0.1:28074
-A OUTPUT -p tcp -d ip_node_4 --dport 8075 -j DNAT --to-destination 127.0.0.1:38075
-A OUTPUT -p tcp -d ip_node_4 --dport 8074 -j DNAT --to-destination 127.0.0.1:38074
```
Please be aware that the ports on the right side must be unique, so if you have a cluster of six nodes, use 8075 and 8074 with 1 to 5 in front of it. If the cluster is of bigger size, additional ports must be used.
Ensure that your operating system has IP forwarding enabled using the following command:
``` sh
sysctl -w net.ipv4.ip_forward=1
```
After that, reload the ufw rules and confirm that the iptable rules were successfully created:
``` sh
iptables -t nat -L
```
``` text
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere 10.10.250.231 tcp dpt:8075 to:127.0.0.1:18075
DNAT tcp -- anywhere 10.10.250.231 tcp dpt:8074 to:127.0.0.1:18074
DNAT tcp -- anywhere 10.10.250.165 tcp dpt:8075 to:127.0.0.1:28075
DNAT tcp -- anywhere 10.10.250.165 tcp dpt:8074 to:127.0.0.1:28074
```
Repeat those steps for every node on the cluster. At the end of this section the following should be configured:
- SSH access enabled in firewall from each cluster node to another.
- Per node 2 iptables rules for port 8074 and 8075.
- IP forwarding enabled.
### SSH configuration
As a next step, ensure that the SSH tunnels are created as part of the Mattermost service start. To do so, create a file called `pre_start.sh` in `/opt/mattermost/bin` on `mattermost1`:
``` sh
#!/bin/bash
ssh -N -f -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 18075:10.10.250.231:8075 10.10.250.231 || true
ssh -N -f -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 18074:10.10.250.231:8074 10.10.250.231 || true
ssh -N -f -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 28075:10.10.250.165:8075 10.10.250.165 || true
ssh -N -f -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L 28074:10.10.250.165:8074 10.10.250.165 || true
```
<Note>
- We're ignoring the error from the SSH connection itself in case a tunnel is already active. Otherwise the Mattermost server would fail to start.
- Please make sure to back up this script in case of a version upgrade.
</Note>
Afterwards, set the executable bit on the shell script:
``` sh
chmod +x /opt/mattermost/bin/pre_start.sh
```
Open the systemd unit file of Mattermost and search for `Type=Notify`. After this, enter a `ExecStartPre` script that will be executed before Mattermost itself is started:
``` text
[Service]
Type=notify
ExecStartPre=/opt/mattermost/bin/pre_start.sh
```
Reload the systemd daemon afterwards:
``` sh
systemctl daemon-reload
```
Repeat the same steps on each of the member nodes and adapt the node IPs and amount of entries for your environment.
### Cluster start
Once each node is configured, restart the service on each cluster and confirm that it's running using the command below:
``` sh
systemctl start mattermost
systemctl status mattermost.service
```
``` text
● mattermost.service - Mattermost
Loaded: loaded (/etc/systemd/system/mattermost.service; static; vendor preset: enabled)
Active: active (running) since Fri 2019-10-04 19:44:20 UTC; 5min ago
Process: 16734 ExecStartPre=/opt/mattermost/bin/pre_start.sh (code=exited, status=0/SUCCESS)
```
Next, open the Mattermost System Console and confirm that each node is reporting successfully in the High Availability section.