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.

Looking to install Mattermost with MariaDB? Click here
Configure the system
Before installing anything, make sure to update your system.
apt update && apt upgradeEnable 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 statusWe will also install Apache, Snap, and other software.
apt install apache2 snap curlEnable 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 apache2Setup database
Install PostgreSQL version 14 from the default Ubuntu repositories.
apt install postgresqlAfter installation, check the status and configure it to start at boot time.
systemctl status postgresql
systemctl enable postgresqlWe 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.
\qModify 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.confMake the following changes (after line 94 on-wards):
| Change | To | 
|---|---|
| local all all peer | local all all trust | 
| local all all scram-sha-256OR host all all 127.0.0.1/32 scram-sha-256 | local all all trustOR host all all 127.0.0.1/32 trust | 
| host all all ::1/128 scram-sha-256 | host all all ::1/128 trust | 
Save the file and reload PostgreSQL.
systemctl reload postgresqlTo 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 --passwordApache virtual host
Create a virtual host file for Mattermost in /etc/apache2/sites-available.
cd /etc/apache2/sites-available
vim mattermost.confPaste 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 apache2SSL
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 --classicRun the following command to get the certificate.
certbot certonly --webroot -w /var/www/html -d DOMAIN.COMMattermost 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.gzExtract and move it to /opt.
tar -xvzf mattermost*.gz
mv mattermost /opt
mkdir /opt/mattermost/dataCreate a system user to run Mattermost under it.
useradd --system --user-group mattermostChange mattermost directory ownership.
chown -R mattermost:mattermost /opt/mattermost
chmod -R g+w /opt/mattermostLet’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.jsonChange the database driver and source string.
- Update SiteURLto your actual URL (line 3)
- DriverNameshould be- postgres(line 145)
Change source (line 146):
postgres://mmuser:mostest@localhost/mattermost_test?sslmode=disable\u0026connect_timeout=10\u0026binary_parameters=yesTo (Change PASSWORD to your actual db password)
postgres://mmuser:PASSWORD@localhost:5432/mattermost?sslmode=disable&connect_timeout=10Save the file.
Create a Systemd unit file.
vim /lib/systemd/system/mattermost.servicePaste 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.targetReload the Systemd daemon.
systemctl daemon-reloadIt’s time to start Mattermost now.
systemctl enable mattermost
systemctl start mattermost
systemctl status mattermostUpdate 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.confPaste 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 apache2You can now head over to the browser and start the initial setup by creating new account and team.







