Installing Mattermost on Debian Buster

plans-img Available on all plans

deployment-img self-hosted deployments

Install a production-ready Mattermost system on up to three machines.

A complete Mattermost installation consists of three major components: a proxy server, a database server, and the Mattermost server. You can install all components on one machine, or you can install each component on its own machine. If you have only two machines, then install the proxy and the Mattermost server on one machine, and install the database on the other machine.

For the database, you can install either PostgreSQL or MySQL. The proxy is NGINX.

Note

If you have any problems installing Mattermost, see the troubleshooting guide, or join the Mattermost user community for troubleshooting help.

For help with inviting users to your system, see inviting team members and other getting started information.

To submit an improvement or correction to this page, select Edit in the top-right corner of the page.

Install Mattermost Server using the tarball

Available on all plans

Self-hosted deployments

Minimum system requirements:

  • Hardware: 1 vCPU/core with 2GB RAM (support for up to 1,000 users)
  • Database: PostgreSQL v11+
  • Network:
    • Application 80/443, TLS, TCP Inbound
    • Administrator Console 8065, TLS, TCP Inbound
    • SMTP port 10025, TCP/UDP Outbound

You can install the Mattermost Server on any 64-bit Linux system using the tarball. This is the most flexible installation method, but it comes with the highest effort, normally favored by advanced system administrators.

Mattermost Academy Learn about deploying Mattermost using a tarball

Tip

If you are running the Mattermost Server and database on a single system, we recommend the Mattermost Omnibus install method as this greatly reduces setup and ongoing maintenance, and uses the Mattermost PPA for updates. More modern installation methods such as the Mattermost Helm Chart or Kubernetes Operator are available and are highly recommended.

Note

You need a PostgreSQL database. See the database preparation documentation for details on this prerequisite.

A Mattermost deployment includes 3 steps: download, install, and setup.

Download

In a terminal window, ssh onto the system that will host the Mattermost Server.

Using wget, download the Mattermost Server release you want to install.

wget https://releases.mattermost.com/9.6.0/mattermost-9.6.0-linux-amd64.tar.gz Copied to clipboard

Install

Install the Mattermost Server by extracting the tarball, creating users and groups, and setting file/folder permissions.

First extract the tarball:

  tar -xvzf mattermost*.gz

Now move the entire folder to the /opt directory (or whatever path you require):

  sudo mv mattermost /opt

Note

If you choose a custom path, ensure this alternate path is used in all steps that follow.

By default the Mattermost Server uses /opt/mattermost/data as the folder for files. This can be changed in the System Console during setup (even using alternative storage such as S3). Create the default storage folder:

  sudo mkdir /opt/mattermost/data

Now set up a user and group called mattermost:

  sudo useradd --system --user-group mattermost

Note

If you choose a custom user and group name, ensure it is used in all the steps that follow.

Set the file and folder permissions for your installation:

  sudo chown -R mattermost:mattermost /opt/mattermost

Give the mattermost group write permissions to the application folder:

  sudo chmod -R g+w /opt/mattermost

You will now have the latest Mattermost Server version installed on your system. Starting and stopping the Mattermost Server is done using systemd. Create the systemd unit file:

  sudo touch /lib/systemd/system/mattermost.service

As root, edit the systemd unit file to add the following lines:

  [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

Save the file and reload systemd using sudo systemctl daemon-reload. Mattermost Server is now installed and is ready for setup.

Note

If you are installing the Mattermost server on the same system as your database, you may want to add both After=postgresql.service and BindsTo=postgresql.service to the [Unit] section of the systemd unit file.

Setup

Before you start the Mattermost Server, you need to edit the configuration file. A default configuration file is located at /opt/mattermost/config/config.json.

We recommend taking a backup of this default config ahead of making changes:

  sudo cp /opt/mattermost/config/config.json /opt/mattermost/config/config.defaults.json

Configure the following properties in this file:

  • Set DriverName to "postgres". This is the default and recommended database for all Mattermost installations.

  • Set DataSource to "postgres://mmuser:<mmuser-password>@<host-name-or-IP>:5432/mattermost?sslmode=disable&connect_timeout=10" replacing mmuser, <mmuser-password>, <host-name-or-IP>, and mattermost with your database name.

  • Set your "SiteURL": The domain name for the Mattermost application (e.g. https://mattermost.example.com).

After modifying the config.json configuration file, you can now start the Mattermost server:

  sudo systemctl start mattermost

Verify that Mattermost is running: curl http://localhost:8065. You should see the HTML that’s returned by the Mattermost Server.

The final step, depending on your requirements, is to run sudo systemctl enable mattermost.service so that Mattermost will start on system boot.

Updates

Updating your Mattermost Server installation when using the tarball requires several manual steps. See the upgrade Mattermost Server documentation for details.

Remove Mattermost

If you wish to remove the Mattermost Server for any reason, you must stop the Mattermost Server, back up all important files, and then run this command:

 sudo rm /opt/mattermost

Note

Depending on your configuration, there are several important folders in /opt/mattermost to backup. These are config, logs, plugins, client/plugins, and data. We strongly recommend you back up these locations before running the rm command.

You may also remove the Mattermost systemd unit file and the user/group created for running the application.

Frequently asked questions

Why doesn’t Mattermost start at system boot?

To have the Mattermost Server start at system boot, the systemd until file needs to be enabled. Run the following command:

  sudo systemctl enable mattermost.service

Why does Mattermost fail to start at system boot?

If your database is on the same system as your Mattermost Server, we recommend editing the default /lib/systemd/system/mattermost.service systemd unit file to add After=postgresql.service and BindsTo=postgresql.service to the [Unit] section.

Can I run Mattermost without a proxy?

Yes. 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:

  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. If you’re exceeding 200 concurrent users, you’ll need a proxy, such as NGINX, in front of Mattermost to manage the traffic.

Install a database

Note

You only need one database: either PostgreSQL or MySQL. See the database software documentation for details on database version support.

Install and set up a PostgreSQL database for use by the Mattermost server. These instructions assume that the IP address of this server is 10.10.10.1.

  1. Log in to the server that will host the database, and install PostgreSQL. See the PostgreSQL documentation for details. When the installation is complete, the PostgreSQL server is running, and a Linux user account called postgres has been created.

  2. Log in to the postgres account by running sudo --login --user postgres.

  3. Start the PostgreSQL interactive terminal by running psql.

  4. Create the Mattermost database by running postgres=# CREATE DATABASE mattermost;.

  5. Create the Mattermost user ‘mmuser’ by running postgres=# CREATE USER mmuser WITH PASSWORD 'mmuser-password';.

Note

Use a password that is more secure than mmuser-password.

  1. Grant the user access to the Mattermost database by running postgres=# GRANT ALL PRIVILEGES ON DATABASE mattermost to mmuser;.

  2. Exit the PostgreSQL interactive terminal by running postgres=# \q.

  3. Log out of the postgres account by running exit.

  4. (Optional) If you use separate servers for your database and the Mattermost app server, you may allow PostgreSQL to listen on all assigned IP Addresses. To do so, open /etc/postgresql/{version}/main/postgresql.conf as root in a text editor, and replacing {version} with the version of PostgreSQL that’s currently running. As a best practice, ensure that only the Mattermost server is able to connect to the PostgreSQL port using a firewall.

  1. Find the following line: #listen_addresses = 'localhost'.

  2. Uncomment the line and change localhost to *: listen_addresses = '*'.

  3. Restart PostgreSQL for the change to take effect: sudo systemctl restart postgresql.

  1. Modify the file pg_hba.conf to allow the Mattermost server to communicate with the database.

If the Mattermost server and the database are on the same machine:

  1. Open /etc/postgresql/9.4/main/pg_hba.conf in a text editor as root user.

  2. Find the following lines:

local   all             all                        peer

host    all             all         ::1/128        ident

  1. Change peer and ident to trust:

local   all             all                        trust

host    all             all         ::1/128        trust

If the Mattermost server and the database are on different machines:

  1. Open /etc/postgresql/9.4/main/pg_hba.conf in a text editor as root user.

  2. Add the following line to the end of the file, where {mattermost-server-IP} is the IP address of the machine that contains the Mattermost server: host all all {mattermost-server-IP}/32 md5.

  1. Reload PostgreSQL by running sudo systemctl reload postgresql.

  2. Verify that you can connect with the user mmuser.

  1. If the Mattermost server and the database are on the same machine, use the following command: psql --dbname=mattermost --username=mmuser --password

  2. If the Mattermost server is on a different machine, log into that machine and use the following command: psql --host={postgres-server-IP} --dbname=mattermost --username=mmuser --password

Note

You might have to install the PostgreSQL client software to use the command.

The PostgreSQL interactive terminal starts. To exit the PostgreSQL interactive terminal, type \q and press Enter on Windows or Linux, or on Mac.

With the database installed and the initial setup complete, you can now install the Mattermost server.

Configure Mattermost server

Create the System Admin user and set up Mattermost for general use.

  1. Open a browser and navigate to your Mattermost instance. For example, if the IP address of the Mattermost server is 10.10.10.2 then go to http://10.10.10.2:8065.

  2. Create the first team and user. The first user in the system has the system_admin role, which gives you access to the System Console.

  3. To open the System Console, select the Product menu in the top-left corner of the navigation panel, then select System Console.

  4. Set the site URL:

  • Open System Console > Environment > Web Server.

  • In the Site URL field, set the URL that users point their browsers at. For example, https://mattermost.example.com. If you’re using HTTPS, make sure that you set up TLS, either on Mattermost server or on a proxy.

  1. Set up email notifications.

  • In Site Configuration > Notifications make the following changes:

    • Set Enable Email Notifications to true

    • Set Notification Display Name to No-Reply

    • Set Notification From Address to {your-domain-name} For example, example.com

  • In System Console > Environment > SMTP make the following changes:

    • Set SMTP Server Username to {SMTP-username} For example, admin@example.com

    • Set SMTP Server Password to {SMTP-password}

    • Set SMTP Server to {SMTP-server} For example, mail.example.com

    • Set SMTP Server Port to 465

    • Set Connection Security to TLS or STARTTLS, depending on what the SMTP server accepts

  • Select Save

  • Select Test Connection.

  1. Open System Console > Environment > File Storage to set up the file and image storage location.

  • If you store the files locally, set File Storage System to Local File System, and then either accept the default for the Local Storage Directory or enter a location. The location must be a directory that exists and has write permissions for the Mattermost server. It can be an absolute path or a relative path. Relative paths are relative to the mattermost directory.

  • If you store the files on Amazon S3, set File Storage System to Amazon S3 and enter the appropriate values for your Amazon account.

Note

  • Files and images that users attach to their messages are not stored in the database. Instead, they’re stored in a location that you specify, such as the local file system or in Amazon S3.

  • Make sure that the location has enough free space. The amount of storage required depends on the number of users and the number and size of files that users attach to messages.

  1. Select Save to apply the configuration.

  2. Review and configure any other settings that may be applicable.

  3. Restart Mattermost by running sudo systemctl restart mattermost.

Configure TLS on Mattermost server

You have two options if you want users to connect with HTTPS:

  1. Set up TLS on Mattermost server.

  2. Install a proxy such as NGINX and set up TLS on the proxy.

The easiest option is to set up TLS on the Mattermost Server, but if you expect to have more than 200 users, use a proxy for better performance. A proxy server also provides standard HTTP request logs.

Note

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.

Configure TLS on the Mattermost server

  1. In System Console > Environment > Web Server (or System Console > General > Configuration in versions prior to 5.12).

  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.

  1. Activate the CAP_NET_BIND_SERVICE capability to allow Mattermost to bind to low ports.

sudo setcap cap_net_bind_service=+ep /opt/mattermost/bin/mattermost

  1. Install the security certificate. You can use Let’s Encrypt to automatically install and setup the certificate, or you can specify your own certificate.

To 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 config.json setting set to true to complete the Let’s Encrypt certification.

To 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 are not supported.

Use TLS on NGINX (as a proxy)

Note

Do not set up TLS on Mattermost before before doing so for NGINX. It breaks the connection as the TLS prevents it from successfully communicating with the Mattermost server.

  • 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.

Other helpful resources:

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:

sudo apt update

sudo apt install nginx

After accepting the procedure, apt will install NGINX and any required dependencies to your server.

  1. 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.

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:

<!DOCTYPE html>
<html>
<head>
<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

  1. 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 with server push 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 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.

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;
   server_name    mattermost.example.com;

   http2_push_preload on; # Enable HTTP/2 Server Push

   ssl on;
   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 $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 60;
       send_timeout 300;
       lingering_timeout 5;
       proxy_connect_timeout 90;
       proxy_send_timeout 300;
       proxy_read_timeout 90s;
       proxy_http_version 1.1;
       proxy_pass http://backend;
   }

   location / {
       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;
   }
}

# 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 "";
}
  1. 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)

  2. 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)

  3. Restart NGINX by running sudo systemctl restart nginx.

  4. 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.

  1. 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, a free certificate authority.

Note

If Let’s Encrypt is enabled, forward port 80 through a firewall, with Forward80To443 config.json setting set to true to complete the Let’s Encrypt certification. See the Let’s Encrypt/Certbot documentation for additional assistance.

  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 {ip} 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.

Note

  • 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.

upstream backend {
    server {ip}:8065;
    keepalive 32;
    }

server {
    listen 80 default_server;
    server_name mattermost.example.com;

    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 $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 60;
        send_timeout 300;
        lingering_timeout 5;
        proxy_connect_timeout 90;
        proxy_send_timeout 300;
        proxy_read_timeout 90s;
        proxy_pass http://backend;
    }

    location / {
        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;
    }
}
  1. 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).

  2. 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).

  3. 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.

  4. Restart NGINX by running sudo systemctl start nginx.

  5. 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.

  1. Install and update Snap by running sudo snap install core; sudo snap refresh core.

  2. Install the Certbot package by running sudo snap install --classic certbot.

  3. Add a symbolic link to ensure Certbot can run by running sudo ln -s /snap/bin/certbot /usr/bin/certbot.

  4. 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.

  1. 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.

  2. Ensure your SSL is configured properly by running curl https://{your domain here}

  3. 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:

upstream backend {
    server {ip}:8065;
   keepalive 32;
    }

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;

server {
    server_name mattermost.example.com;

    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 $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 60;
        send_timeout 300;
        lingering_timeout 5;
        proxy_connect_timeout 90;
        proxy_send_timeout 300;
        proxy_read_timeout 90s;
        proxy_http_version 1.1;
        proxy_pass http://backend;
    }

    location / {
        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;
    }

    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;
}


server {
    if ($host = mattermost.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80 default_server;
    server_name mattermost.example.com;
    return 404; # managed by Certbot

}
  1. 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.

  • If there’s an error about the missing chain or certificate path, there is likely an intermediate certificate missing that needs to be included.

NGINX configuration FAQ

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:

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.

"EnableUserAccessTokens": false,
"AllowCorsFrom": "domain.com domain.com:443 im.domain.com",
"SessionLengthWebInDays": 30,

For other troubleshooting tips for WebSocket errors, see potential solutions here.

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.

docker network ls
# Grep the name of your Mattermost network like "mymattermost_default".
docker network connect mymattermost_default nginx-proxy
  1. Restart the Mattermost Docker containers.

docker-compose stop app
docker-compose start app

Tip

You don’t need to run the ‘web’ container, since NGINX proxy accepts incoming requests.

  1. Update your docker-compose.yml file to include a new environment variable VIRTUAL_HOST and an expose directive.

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?

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.

Certbot rate limiting

If you’re running certbot as stand-alone you’ll see this error:

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:

{"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.