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,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-----$`.