Install Mattermost on CentOS 8 with Nginx

Ranch
You can support us by downloading this article in PDF format via the link below.

Download the guide as a PDF

turn off
Ranch

Ranch
Ranch

In this guide, we will explore how to install Mattermost on CentOS 8 using Nginx as a reverse proxy. Mattermost is a free and open source online team collaboration and chat platform with hundreds of existing integrations from Mattermost and the community. This allows you to build custom workflows that can scale to thousands of concurrent users. You can easily and securely integrate with most popular DevOps tools (CI / CD, Robot, Git).

Mattermost can be installed on-premises, in the cloud, or through a hybrid architecture deployment (public and private cloud). For AWS, Azure, and Google Cloud, pre-built open source images are supported and easy to install. You can access Mattermost from the web or your favorite devices (iOS, Android, Windows, Linux, and Mac).

So let’s start installing Mattermost on CentOS 8 using Nginx reverse proxy and choose to configure a secure connection with an “encrypted SSL” certificate.

Step 1: Update the system

Make sure the system is updated.

sudo yum -y update

After upgrading, you may need to reboot your system.

sudo reboot

Step 2: Install the database server

Our Mattermost server will need a database server to store its data. For this, we will use MariaDB database server.

sudo yum -y install @mariadb
sudo systemctl enable --now mariadb
sudo mysql_secure_installation

After installing the database, log in to the MariaDB shell and create the database and user for Mattermost.

$ mysql -u root -p
CREATE DATABASE mattermost;
GRANT ALL PRIVILEGES ON mattermost.* TO [email protected] IDENTIFIED BY '[email protected]';
FLUSH PRIVILEGES;
QUIT;

Step 3: Install Mattermost server on CentOS 8

Add system users to manage Mattermost services.

sudo useradd -d /opt/mattermost -U -M mattermost

Mattermost Server is now installed on CentOS 8 Linux. The latest version of Mattermost is available at The most important download page. At the time of writing, the latest version available is 5.20.1.

wget https://releases.mattermost.com/5.20.2/mattermost-5.20.2-linux-amd64.tar.gz

Unzip the file after downloading.

tar xvf mattermost-5.20.2-linux-amd64.tar.gz

Move the extracted files to the / opt directory.

sudo mv mattermost /opt

Create storage directories for files and images posted to Mattermost by users.

sudo mkdir /opt/mattermost/data

Set directory permissions.

sudo chown -R mattermost:mattermost /opt/mattermost
sudo chmod -R g+w /opt/mattermost

Configure the database driver.

sudo vim /opt/mattermost/config/config.json

We need to set:

  • Set “DriverName” to “MySQL
  • Set the Data Source to:
"mmuser:@tcp(:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s"

So for me, this would be:

"SqlSettings": {
        "DriverName": "mysql",
        "DataSource": "mattermost:[email protected]@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8u0026readTimeout=30su0026writeTimeout=30s",
        "DataSourceReplicas": [],
        "DataSourceSearchReplicas": [],
        "MaxIdleConns": 20,
        "ConnMaxLifetimeMilliseconds": 3600000,
        "MaxOpenConns": 300,
        "Trace": false,
        "AtRestEncryptKey": "myyti1r597i99qrk7eu91ywqhaawz4md",
        "QueryTimeout": 30
    },

Change to whatmost directory to test Mattermost server.

cd /opt/mattermost

The most important thing is to start the Mattermost server:

$ sudo -u mattermost ./bin/mattermost
{"level":"info","ts":1583869117.6809375,"caller":"utils/i18n.go:83","msg":"Loaded system translations","for locale":"en","from locale":"/opt/mattermost/i18n/en.json"}
{"level":"info","ts":1583869117.6810265,"caller":"app/server_app_adapters.go:58","msg":"Server is initializing..."}
{"level":"info","ts":1583869117.6850379,"caller":"sqlstore/supplier.go:221","msg":"Pinging SQL","database":"master"}
{"level":"info","ts":1583869118.8863454,"caller":"sqlstore/upgrade.go:111","msg":"The database schema version has been set","version":"5.20.0"}
{"level":"error","ts":1583869121.576649,"caller":"app/server_app_adapters.go:129","msg":"SiteURL must be set. Some features will operate incorrectly if the SiteURL is not set. See documentation for details: https://about.mattermost.com/default-site-url"}
{"level":"info","ts":1583869121.5776517,"caller":"app/license.go:39","msg":"License key from https://mattermost.com required to unlock enterprise features."}
{"level":"info","ts":1583869121.5779395,"caller":"app/migrations.go:26","msg":"Migrating roles to database."}
{"level":"info","ts":1583869121.6382146,"caller":"sqlstore/post_store.go:1354","msg":"Post.Message has size restrictions","max_characters":16383,"max_bytes":65535}
{"level":"info","ts":1583869121.6425729,"caller":"app/migrations.go:102","msg":"Migrating emojis config to database."}
{"level":"info","ts":1583869122.121464,"caller":"mlog/log.go:167","msg":"Starting up plugins"}
{"level":"info","ts":1583869122.1215749,"caller":"app/plugin.go:199","msg":"Syncing plugins from the file store"}
{"level":"info","ts":1583869123.3940613,"caller":"mlog/sugar.go:19","msg":"Ensuring Surveybot exists","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1583869123.4156811,"caller":"mlog/sugar.go:19","msg":"Surveybot created","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1583869123.432906,"caller":"mlog/sugar.go:19","msg":"Upgrade detected. Checking if a survey should be scheduled.","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1583869123.5542266,"caller":"mlog/sugar.go:19","msg":"Scheduling next survey for Mar 31, 2020","plugin_id":"com.mattermost.nps"}
{"level":"info","ts":1583869123.8526862,"caller":"app/server.go:232","msg":"Current version is 5.20.0 (5.20.1/Sun Feb 16 15:51:14 UTC 2020/0e1a9f7e530061cdd2c7c17899e458afe2c83a9b/551cbd55b9c0d896b5886f42fc0193c9b97edb33)","current_version":"5.20.0","build_number":"5.20.1","build_date":"Sun Feb 16 15:51:14 UTC 2020","build_hash":"0e1a9f7e530061cdd2c7c17899e458afe2c83a9b","build_hash_enterprise":"551cbd55b9c0d896b5886f42fc0193c9b97edb33"}
{"level":"info","ts":1583869123.8527322,"caller":"app/server.go:241","msg":"Enterprise Build","enterprise_build":true}
{"level":"info","ts":1583869123.8527455,"caller":"app/server.go:247","msg":"Printing current working","directory":"/opt/mattermost"}
{"level":"info","ts":1583869123.852752,"caller":"app/server.go:248","msg":"Loaded config","source":"file:///opt/mattermost/config/config.json"}
{"level":"error","ts":1583869123.8604512,"caller":"mlog/log.go:175","msg":"RPC call OnConfigurationChange to plugin failed.","plugin_id":"com.mattermost.nps","error":"connection is shut down"}
{"level":"error","ts":1583869123.89252,"caller":"mlog/log.go:175","msg":"RPC call OnConfigurationChange to plugin failed.","plugin_id":"com.mattermost.nps","error":"connection is shut down"}
{"level":"info","ts":1583869123.894262,"caller":"jobs/workers.go:68","msg":"Starting workers"}
{"level":"info","ts":1583869123.8990135,"caller":"app/web_hub.go:75","msg":"Starting websocket hubs","number_of_hubs":2}
{"level":"info","ts":1583869123.9066868,"caller":"jobs/schedulers.go:74","msg":"Starting schedulers."}
{"level":"info","ts":1583869123.9202466,"caller":"app/server.go:470","msg":"Starting Server..."}
{"level":"info","ts":1583869123.9206858,"caller":"app/server.go:538","msg":"Server is listening on [::]:8065","address":"[::]:8065"}

Step 4: Configure Mattermost systemd unit files

Create a systematic unit file for Mattermost:

sudo tee /etc/systemd/system/mattermost.service<

Disable SELinux or set it to licensed mode

sudo setenforce 0
sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config

Make the service executable.

sudo systemctl daemon-reload
sudo systemctl enable --now mattermost

Confirm the service status.

$ systemctl status mattermost.service 
● mattermost.service - Mattermost
   Loaded: loaded (/etc/systemd/system/mattermost.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2020-03-13 20:01:03 EAT; 2min 47s ago
 Main PID: 9154 (mattermost)
    Tasks: 16 (limit: 11497)
   Memory: 114.2M
   CGroup: /system.slice/mattermost.service
           ├─9154 /opt/mattermost/bin/mattermost
           └─9224 plugins/com.mattermost.nps/server/dist/plugin-linux-amd64

Mar 13 20:01:02 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118862.898295,"caller":"app/server.go:247","msg":"Printing current working",>
Mar 13 20:01:02 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118862.8983018,"caller":"app/server.go:248","msg":"Loaded config","source":">
Mar 13 20:01:02 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118862.920317,"caller":"sqlstore/post_store.go:1354","msg":"Post.Message has>
Mar 13 20:01:03 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118862.9979806,"caller":"jobs/workers.go:68","msg":"Starting workers"}
Mar 13 20:01:03 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118863.0024703,"caller":"app/web_hub.go:75","msg":"Starting websocket hubs",>
Mar 13 20:01:03 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118863.0136616,"caller":"jobs/schedulers.go:74","msg":"Starting schedulers."}
Mar 13 20:01:03 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118863.0337238,"caller":"app/server.go:470","msg":"Starting Server..."}
Mar 13 20:01:03 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118863.033907,"caller":"app/server.go:538","msg":"Server is listening on [::>
Mar 13 20:01:03 cent8.novalocal mattermost[9154]: {"level":"info","ts":1584118863.0339284,"caller":"commands/server.go:105","msg":"Sending systemd READ>
Mar 13 20:01:03 cent8.novalocal systemd[1]: Started Mattermost.

Verify that Mattermost is running.

$ curl https://localhost:8065

You should see the HTML returned by the Mattermost server.

Step 5: Install and configure Nginx

When running Mattermost in a production environment, use a proxy server to improve Mattermost's security and performance.

Install Nginx on a CentOS Linux machine.

sudo dnf -y install epel-release
sudo dnf -y install nginx

Start and enable the Nginx service.

sudo systemctl enable --now nginx

Then configure the Nginx web server as a proxy for Mattermost Server.

sudo vi /etc/nginx/conf.d/mattermost.conf

Paste and edit the following code snippet into the file to configure Nginx at the most basic level.

upstream backend {
   server 127.0.0.1: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 {
   listen 80;
   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 https://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_cache mattermost_cache;
       proxy_cache_revalidate on;
       proxy_cache_min_uses 2;
       proxy_cache_use_stale timeout;
       proxy_cache_lock on;
       proxy_http_version 1.1;
       proxy_pass https://backend;
   }
}

Modify mattermost.example.com Set the correct value for your Mattermost domain.

Verify your Nginx configuration file.

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If everything works, restart Nginx.

sudo systemctl restart nginx

Open http and https ports on Firewalld.

sudo firewall-cmd --add-service={http,https} --permanent
sudo firewall-cmd --reload

Check that the status is running.

$ sudo systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2020-03-13 20:17:05 EAT; 2min 9s ago
  Process: 9772 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 9769 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 9768 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 9774 (nginx)
    Tasks: 3 (limit: 11497)
   Memory: 5.2M
   CGroup: /system.slice/nginx.service
           ├─9774 nginx: master process /usr/sbin/nginx
           ├─9775 nginx: worker process
           └─9776 nginx: cache manager process

Mar 13 20:17:05 cent8.novalocal systemd[1]: Starting The nginx HTTP and reverse proxy server...
Mar 13 20:17:05 cent8.novalocal nginx[9769]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Mar 13 20:17:05 cent8.novalocal nginx[9769]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Mar 13 20:17:05 cent8.novalocal systemd[1]: nginx.service: Failed to parse PID from file /run/nginx.pid: Invalid argument
Mar 13 20:17:05 cent8.novalocal systemd[1]: Started The nginx HTTP and reverse proxy server.

You should be able to access the Mattermost domain configured on Nginx.

$ curl mattermost.example.com

Step 6: Configure Mattermost server

Now, we can start configuring Mattermost server by opening the domain configured on Nginx.

https://mattermost.example.com

Create an admin user on the homepage-this user will be able to create or invite other new users.

Choose to create a team or go directly to the console.

If you chose to create a team, provide a team name and click Next.

Set the team URL and click Finish.

Mattermost's dashboard console should look like this.

You can then invite members to join the team you created. Also consider installing the following applications PC, Mac, iOS and Android Easy to access and notify on the go.

Step 7: Configure "Let's Encrypt / Custom SSL Certificate"

You can use SSL to ensure greater security by ensuring that communications between Mattermost clients and Mattermost servers are encrypted. It also allows you to configure NGINX to use the HTTP / 2 protocol.

Get "Let's Encrypt SSL Certificate" for your domain. First download the certbot script.

wget https://dl.eff.org/certbot-auto
chmod +x certbot-auto
sudo mv certbot-auto /usr/local/bin

Stop the Nginx service.

sudo systemctl stop nginx

Then set up "domain and email" for expired alerts and get free "encrypted" certificates.

export DOMAIN="mattermost.example.com"
export EMAIL_ALERTS="[email protected]"
sudo /usr/local/bin/certbot-auto certonly --standalone -d $DOMAIN --preferred-challenges http --agree-tos -n -m $EMAIL_ALERTS --keep-until-expiring

Update your nginx configuration file to set up SSL.

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

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 ;

  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;
  ssl_protocols TLSv1.2;
  ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:50m;
  # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 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;


  location ~ /api/v[0-9]+/(users/)?websocket$ {
    proxy_set_header Upgrade $http_upgrade;
    .
    .
    .

location / {
    proxy_http_version 1.1;
    .
    .
    .

Restart Nginx.

sudo systemctl restart nginx

Confirm from your web browser that the service is now on https. Visit the official The most important documents understand more.

More guides.

Best open source collaboration and groupware software solution

FileCloud Community Edition-Secure File Sharing Service

Install OpenProject Community Edition on Debian 10 (Buster)

Ranch
You can support us by downloading this article in PDF format via the link below.

Download the guide as a PDF

turn off
Ranch

Ranch
Ranch

Related Posts