Install Mattermost with PostgreSQL on Ubuntu 22.04 server

Mattermost, a popular team messaging platform, provides a self-hosted solution that gives you full control over your communication environment. This guide will walk you through the process of how to install Mattermost on an Ubuntu 22.04 server, utilizing PostgreSQL as the backend database. By the end of this tutorial, you’ll have a messaging system up and running, allowing your team to collaborate securely and efficiently.

Mattermost-logo

Looking to install Mattermost with MariaDB? Click here

Configure the system

Before installing anything, make sure to update your system.

apt update && apt upgrade

Enable the firewall and allow only specific ports.

ufw default allow outgoing
ufw default deny incoming
ufw allow 22
ufw allow 80
ufw allow 443
ufw enable
ufw status

We will also install Apache, Snap, and other software.

apt install apache2 snap curl

Enable some of the required Apache modules and configure Apache to start at boot time.

a2enmod ssl rewrite headers proxy proxy_http deflate cache proxy_wstunnel http2 proxy_fcgi env expires

systemctl restart apache2
systemctl enable apache2

Setup database

Install PostgreSQL version 14 from the default Ubuntu repositories.

apt install postgresql

After installation, check the status and configure it to start at boot time.

systemctl status postgresql
systemctl enable postgresql

We will now create our database and user in PostgreSQL. Replace PASSWORD with a strong password.

sudo -u postgres psql

CREATE DATABASE mattermost;
CREATE USER mmuser WITH PASSWORD 'PASSWORD';

Finally, we will grant permissions to the user.

GRANT ALL PRIVILEGES ON DATABASE mattermost to mmuser;
ALTER DATABASE mattermost OWNER TO mmuser;
GRANT USAGE, CREATE ON SCHEMA PUBLIC TO mmuser;

When you’re done, exit psql.

\q

Modify the file pg_hba.conf to allow the Mattermost server to communicate with the database by setting the host connection types to trust.

vim /etc/postgresql/14/main/pg_hba.conf

Make the following changes (after line 94 on-wards):

ChangeTo
local all all peerlocal all all trust
local all all scram-sha-256
OR
host all all 127.0.0.1/32 scram-sha-256
local all all trust
OR
host all all 127.0.0.1/32 trust
host all all ::1/128 scram-sha-256host all all ::1/128 trust

Save the file and reload PostgreSQL.

systemctl reload postgresql

To verify that everything is set up correctly, log in to the database using the newly created user and then exit psql.

psql --dbname=mattermost --username=mmuser --password

Apache virtual host

Create a virtual host file for Mattermost in /etc/apache2/sites-available.

cd /etc/apache2/sites-available
vim mattermost.conf

Paste the following text into it and make any necessary changes.

<VirtualHost *:80>
	ServerName DOMAIN.COM
	DocumentRoot /var/www/html

	<Directory "/var/www/html">
		AllowOverride All
		Options -Indexes +FollowSymLinks
	</Directory>

	ErrorLog /var/log/apache2/DOMAIN.COM_error.log
</VirtualHost>

Enable this configuration and restart Apache.

a2dissite 000-default.conf
a2ensite mattermost.conf

apachectl -t
systemctl restart apache2

SSL

If you already have your SSL certificates, you can skip this section, as it is specifically for obtaining free SSL certificates from Let’s Encrypt.

Note: Make sure you have pointed the domain to the server IP and is propagated.

snap install certbot --classic

Run the following command to get the certificate.

certbot certonly --webroot -w /var/www/html -d DOMAIN.COM

Mattermost setup

We will now download the Mattermost source and set it up. As of the time of writing, Mattermost’s version is 9.2.2.

cd ~
wget https://releases.mattermost.com/9.2.2/mattermost-9.2.2-linux-amd64.tar.gz

Extract and move it to /opt.

tar -xvzf mattermost*.gz
mv mattermost /opt

mkdir /opt/mattermost/data

Create a system user to run Mattermost under it.

useradd --system --user-group mattermost

Change mattermost directory ownership.

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

Let’s configure a few things before starting the Mattermost server.

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

vim /opt/mattermost/config/config.json

Change the database driver and source string.

  • Update SiteURL to your actual URL (line 3)
  • DriverName should be postgres (line 145)

Change source (line 146):

postgres://mmuser:mostest@localhost/mattermost_test?sslmode=disable\u0026connect_timeout=10\u0026binary_parameters=yes

To (Change PASSWORD to your actual db password)

postgres://mmuser:PASSWORD@localhost:5432/mattermost?sslmode=disable&connect_timeout=10

Save the file.

Create a Systemd unit file.

vim /lib/systemd/system/mattermost.service

Paste this in it and save it.

[Unit]
Description=Mattermost
After=network.target
After=postgresql.service
BindsTo=postgresql.service

[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 the Systemd daemon.

systemctl daemon-reload

It’s time to start Mattermost now.

systemctl enable mattermost
systemctl start mattermost

systemctl status mattermost

Update Apache virtual host

Now that we have our SSL certificates, it’s time to update the Apache virtual host with the 443 block.

vim /etc/apache2/sites-available/mattermost.conf

Paste the following in it and change DOMAIN.COM.

<VirtualHost *:443>
	ServerName DOMAIN.COM

	ProxyPreserveHost On
	RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
	RequestHeader set "X-Forwarded-SSL" expr=%{HTTPS}

	RewriteEngine On
	RewriteCond %{REQUEST_URI} /api/v[0-9]+/(users/)?websocket [NC,OR]
	RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
	RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
	RewriteRule .* ws://127.0.0.1:8065%{REQUEST_URI} [P,QSA,L]

	<Location />
		Require all granted
		ProxyPass http://127.0.0.1:8065/
		ProxyPassReverse http://127.0.0.1:8065/
		ProxyPassReverseCookieDomain 127.0.0.1 DOMAIN.COM
	</Location>

	SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4
	SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
	SSLHonorCipherOrder On
	Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
	Header always set X-Frame-Options DENY
	Header always set X-Content-Type-Options nosniff

    Protocols h2 http/1.1

    ErrorLog /var/log/apache2/DOMAIN.COM_error.log

	SSLEngine on
	SSLCertificateKeyFile /etc/letsencrypt/live/DOMAIN.COM/privkey.pem
	SSLCertificateFile /etc/letsencrypt/live/DOMAIN.COM/fullchain.pem
</VirtualHost>

Save and restart Apache.

apachectl -t
systemctl restart apache2

You can now head over to the browser and start the initial setup by creating new account and team.