Mattermost is an open-source, self-hosted team chat platform with channels, direct messages, file sharing and integrations, similar to Slack but running on infrastructure you control. In this tutorial you will install Mattermost on Ubuntu 24.04 from the official Mattermost package repository, store its data in PostgreSQL, and publish it over HTTPS behind Nginx with a free Let's Encrypt certificate. At the end you will have a working workspace with an admin account, a first team and a daily backup.
Prerequisites
To follow this guide you need:
- A server running Ubuntu 24.04 LTS (x86_64), for example a CubePath VPS, with at least 2 vCPUs and 4 GB of RAM. Mattermost recommends 8 GB for teams above a few hundred users.
- A non-root user with
sudoprivileges. - A domain or subdomain, such as
chat.your_domain, with a DNS A record pointing to your server's public IP. This guide usesyour_domainas a placeholder. - Ports 22, 80 and 443 reachable from the Internet.
Step 1 - Preparing the server and firewall
Start by updating the package index and installed packages so you install on top of current security fixes:
sudo apt update && sudo apt upgrade -y
Allow SSH, HTTP and HTTPS through UFW. Mattermost itself listens on port 8065, which stays closed to the outside because Nginx will proxy all traffic:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Check the active rules:
sudo ufw status
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
Step 2 - Installing PostgreSQL and creating the database
Mattermost uses PostgreSQL as its database (MySQL support has been dropped in recent releases). Install the PostgreSQL server shipped with Ubuntu 24.04:
sudo apt install -y postgresql
Open a PostgreSQL shell as the postgres superuser:
sudo -u postgres psql
Create a database and a dedicated user. Replace your_strong_password with a long random password and keep it at hand for Step 4:
CREATE DATABASE mattermost;
CREATE USER mmuser WITH PASSWORD 'your_strong_password';
ALTER DATABASE mattermost OWNER TO mmuser;
GRANT ALL PRIVILEGES ON DATABASE mattermost TO mmuser;
\c mattermost
GRANT USAGE, CREATE ON SCHEMA public TO mmuser;
\q
Confirm that the new user can log in over TCP, which is how Mattermost will connect:
psql -h 127.0.0.1 -U mmuser -d mattermost -c 'SELECT current_user;'
Enter the password when prompted. You should see:
current_user
--------------
mmuser
(1 row)
Step 3 - Installing Mattermost from the official repository
Mattermost publishes an APT repository for Ubuntu and a small script that adds it with its signing key. Download the script first so you can read it before running it with root privileges:
curl -fsSL -o mattermost-repo-setup.sh https://deb.packages.mattermost.com/repo-setup.sh
less mattermost-repo-setup.sh
Run it with the mattermost argument to configure the Mattermost Server repository:
sudo bash mattermost-repo-setup.sh mattermost
Install the package:
sudo apt update
sudo apt install -y mattermost
The package installs Mattermost under /opt/mattermost, creates a mattermost system user and registers a mattermost systemd unit. Verify that the package is installed and check its version:
dpkg -s mattermost | grep -E '^(Status|Version)'
Status: install ok installed
The Version line shows the latest Mattermost release available when you installed it. Upgrades will now arrive through apt upgrade like any other package.
Step 4 - Configuring the database connection and site URL
Mattermost ships a template configuration file. Copy it to config.json with the right owner and restrictive permissions, since it will contain the database password:
sudo install -C -m 600 -o mattermost -g mattermost /opt/mattermost/config/config.defaults.json /opt/mattermost/config/config.json
Open the file:
sudo nano /opt/mattermost/config/config.json
Find the SqlSettings section and set DriverName and DataSource. Use the password from Step 2:
"SqlSettings": {
"DriverName": "postgres",
"DataSource": "postgres://mmuser:[email protected]:5432/mattermost?sslmode=disable&connect_timeout=10",
In the ServiceSettings section, set the public URL and bind Mattermost to localhost so it is only reachable through Nginx:
"ServiceSettings": {
"SiteURL": "https://your_domain",
"ListenAddress": "127.0.0.1:8065",
Leave the other keys in those sections unchanged. If your password contains characters such as @, : or /, URL-encode them in the DataSource string.
Start Mattermost and enable it at boot:
sudo systemctl enable --now mattermost
The first start creates the database schema and can take up to a minute. Check the service:
sudo systemctl status mattermost
● mattermost.service - Mattermost
Loaded: loaded (.../mattermost.service; enabled; preset: enabled)
Active: active (running) since ...
Then query the health endpoint locally:
curl -s http://127.0.0.1:8065/api/v4/system/ping
The JSON response ends with "status":"OK". If the service fails, sudo journalctl -u mattermost -n 50 usually shows a database connection error pointing at a typo in DataSource.
Step 5 - Setting up Nginx as a reverse proxy
Install Nginx:
sudo apt install -y nginx
Create a site configuration for Mattermost:
sudo nano /etc/nginx/sites-available/mattermost
Paste the following block, replacing your_domain. The separate WebSocket location keeps real-time messaging connections open for long periods:
upstream mattermost_backend {
server 127.0.0.1:8065;
keepalive 32;
}
server {
listen 80;
listen [::]:80;
server_name your_domain;
client_max_body_size 100M;
location ~ /api/v[0-9]+/(users/)?websocket$ {
proxy_pass http://mattermost_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 600s;
proxy_buffering off;
}
location / {
proxy_pass http://mattermost_backend;
proxy_http_version 1.1;
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_read_timeout 600s;
}
}
Enable the site, disable the default one, and test the syntax:
sudo ln -s /etc/nginx/sites-available/mattermost /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Reload Nginx:
sudo systemctl reload nginx
Step 6 - Enabling HTTPS with Let's Encrypt
Install Certbot with its Nginx plugin:
sudo apt install -y certbot python3-certbot-nginx
Request a certificate. Certbot validates the domain over port 80, then adds the TLS directives and an HTTP to HTTPS redirect to the Mattermost site:
sudo certbot --nginx -d your_domain
Follow the prompts for your email address and the terms of service. When it finishes, confirm that automatic renewal works:
sudo certbot renew --dry-run
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)
The certbot.timer systemd timer installed by the package handles renewals from now on.
Step 7 - Creating the admin account and first team
Open https://your_domain in a browser. On a fresh installation Mattermost shows the account creation screen: the first account you create becomes the System Admin. Enter an email, username and a strong password, then follow the wizard to name your organization and create your first team.
After the wizard, open the System Console from the product menu (top left) and review two settings:
- Environment > SMTP: enter your mail server details and click Test Connection. Without SMTP, invitation and notification emails are not sent.
- Authentication > Signup: decide whether anyone with the link can sign up, or restrict account creation to invitations or specific email domains.
Invite colleagues from the team menu with Invite People, either by email or by sharing the invite link.
Step 8 - Backing up Mattermost
A complete backup needs the PostgreSQL database, the config directory (it holds the database credentials and settings) and the data directory (uploaded files). Create a backup script:
sudo nano /usr/local/bin/mattermost-backup
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/var/backups/mattermost"
STAMP="$(date +%F_%H%M)"
mkdir -p "$BACKUP_DIR"
chmod 700 "$BACKUP_DIR"
# Database dump in PostgreSQL custom format
runuser -u postgres -- pg_dump -Fc mattermost > "$BACKUP_DIR/db-$STAMP.dump"
# Configuration and uploaded files
tar -czf "$BACKUP_DIR/files-$STAMP.tar.gz" -C /opt/mattermost config data
# Keep 14 days of backups
find "$BACKUP_DIR" -type f -mtime +14 -delete
Make it executable and run it once to test it:
sudo chmod 750 /usr/local/bin/mattermost-backup
sudo /usr/local/bin/mattermost-backup
sudo ls -lh /var/backups/mattermost
-rw-r--r-- 1 root root 2.1M Sep 25 02:00 db-2026-09-25_0200.dump
-rw-r--r-- 1 root root 5.4M Sep 25 02:00 files-2026-09-25_0200.tar.gz
Schedule it daily at 02:30 with a cron file:
echo '30 2 * * * root /usr/local/bin/mattermost-backup' | sudo tee /etc/cron.d/mattermost-backup
Copy these files off the server regularly (for example to object storage), since a backup on the same disk does not protect against losing the server. To restore the database, stop Mattermost and use pg_restore --clean -d mattermost on the dump as the postgres user.
Troubleshooting
- 502 Bad Gateway from Nginx: Mattermost is not running or is still starting. Check
sudo systemctl status mattermostandsudo journalctl -u mattermost -n 50. - "pq: password authentication failed" in the logs: the password in
DataSourcedoes not match the one set in PostgreSQL, or it contains unencoded special characters. - Messages only appear after a page reload: WebSockets are not reaching Mattermost. Make sure the WebSocket
locationblock is present in the Nginx site and thatSiteURLuseshttps://. - Uploads fail for large files: raise
client_max_body_sizein Nginx and File Sharing and Downloads > Maximum File Size in the System Console.
Conclusion
You now have Mattermost running on Ubuntu 24.04 with PostgreSQL, served over HTTPS by Nginx, updated through APT and backed up every night. From here you can connect incoming webhooks and slash commands under Integrations, enable GitLab single sign-on in the System Console, and install the desktop and mobile apps pointing them at https://your_domain.
