Deployment guide

Mattermost

Overview

Mattermost Team Edition is an MIT-licensed, self-hosted team collaboration and messaging platform, and an open-source alternative to Slack. It gives your organisation channels, threads, direct messages and file sharing while keeping every conversation on infrastructure you control.

The SecureAnyCloud image installs Mattermost Team Edition 10.5.5, the free open-source build with no Enterprise license prompt.

What you get:

  • Mattermost Team Edition 10.5.5 (MIT-licensed open-source build) installed at /opt/mattermost and served by mattermost.service as the non-root mattermost user
  • A local PostgreSQL 16 database on loopback 127.0.0.1:5432, with a per-VM database password generated on first boot
  • nginx reverse proxy on port 80, proxying to Mattermost on 127.0.0.1:8065 with the WebSocket upgrade headers Mattermost's realtime channel needs for /api/v4/websocket
  • All state on a dedicated 40 GiB Azure data disk at /var/lib/mattermost: the file store, plugins, logs and the PostgreSQL data directory
  • A unique per-VM System Admin account (admin@sac.local), created non-interactively on first boot, with the password written to a root-only credentials file
  • Open sign-up disabled by default, so only the seeded System Admin exists until you invite users
  • An unauthenticated GET /health endpoint on nginx for load-balancer and uptime checks
  • 24/7 SecureAnyCloud support

Mattermost binds loopback 127.0.0.1:8065 only. You reach it through the nginx reverse proxy on port 80. PostgreSQL is never exposed. It listens on 127.0.0.1:5432 only.

Prerequisites

  • An active Azure subscription
  • An SSH key pair
  • A VNet and subnet in the target region

Standard_B4ms (4 vCPU, 16 GiB RAM) is a good starting point.

In the NSG inbound rules, allow 22/tcp from your management network and 80/tcp from the clients that will use Mattermost. For production, front the VM with TLS (see the final step) and allow 443/tcp instead of plain 80.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Mattermost Team Edition by SecureAnyCloud and select Create.

On Basics, pick your subscription, resource group, region and size (Standard_B4ms). Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80). Then choose Review + create and Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:mattermost-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name mattermost \
  --image sac1647283583153:mattermost-ubuntu-24-04:default:latest \
  --size Standard_B4ms \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name mattermost --port 80 --priority 900

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm Mattermost, PostgreSQL and nginx are running

systemctl is-active postgresql mattermost nginx

You should see three active lines:

active active active

Mattermost binds loopback only, and nginx fronts it on port 80. Confirm the listeners:

ss -tln | grep -E ':8065|:5432|:80'
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* LISTEN 0 4096 127.0.0.1:8065 0.0.0.0:* LISTEN 0 200 127.0.0.1:5432 0.0.0.0:*

The Mattermost API answers an unauthenticated health ping, and nginx exposes a static /health endpoint for load balancers:

curl -s http://127.0.0.1:8065/api/v4/system/ping
{"status":"OK"}
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/health
200

Step 5 - Retrieve your per-VM System Admin password

Each VM generates its own System Admin password on first boot and writes it to a root-only credentials file:

sudo cat /root/mattermost-credentials.txt

The file contains MATTERMOST_ADMIN_PASSWORD, the username (admin), the email (admin@sac.local), the web URL and the System Console URL. Store the password in your secrets manager. In the commands below, <MATTERMOST_ADMIN_PASSWORD> stands for the value of MATTERMOST_ADMIN_PASSWORD.

Set the Site URL to your public address

First boot sets Mattermost's Site URL from the address Azure reports. With a Standard SKU public IP (the Azure default, and the --public-ip-sku Standard in Step 2), the image records the VM's private address (http://10.0.0.x). Mattermost then refuses the realtime WebSocket from a browser at the public IP (HTTP 403). You can sign in, but messages and channels do not update live. Check the Site URL:

sudo grep '^MATTERMOST_URL=' /root/mattermost-credentials.txt

If it shows a 10. address, set the public IP on the VM. Azure's instance metadata service reports the public IP to the VM itself, and nothing leaves the VM:

PUBLIC_IP=$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/loadbalancer?api-version=2020-10-01' | grep -o '"frontendIpAddress":"[^"]*"' | head -1 | cut -d'"' -f4)
PRIV=$(hostname -I | awk '{print $1}'); echo "public $PUBLIC_IP, private $PRIV"
sudo /opt/mattermost/bin/mmctl --local config set ServiceSettings.SiteURL "http://$PUBLIC_IP"
sudo sed -i "s/\b$PRIV\b/$PUBLIC_IP/g" /root/mattermost-credentials.txt

The change applies at once and survives restarts. Your password does not change. When you move to a DNS name and TLS (Step 10), set the Site URL to that https:// address the same way.

Step 6 - Sign in to the Mattermost web UI

Open http://<vm-public-ip>/ in a browser. Sign in with the email admin@sac.local and the per-VM password from Step 5.

You land in your team's channels: Town Square, Off-Topic and any channels you create. Post messages, start threads and share files with your team.

Mattermost keeps every conversation self-hosted on your own Azure VM. Create channels, threads and direct messages as you would in any modern team messenger.

Step 7 - Administer the server from the System Console

As the System Admin, you can manage users, teams, channels, authentication and server settings from the System Console at http://<vm-public-ip>/admin_console. The Edition and License page confirms that you are running the MIT-licensed Team Edition.

Step 8 - Verify authentication from the API

The credentials file drives a real login round-trip. This command reads the per-VM password from the file and posts it to the login API. The API returns 200 for the correct password and rejects a wrong one with 401:

PW=$(sudo grep '^MATTERMOST_ADMIN_PASSWORD=' /root/mattermost-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'login=%{http_code}\n' -X POST -H 'Content-Type: application/json' \
  -d "{\"login_id\":\"admin@sac.local\",\"password\":\"$PW\"}" \
  http://127.0.0.1:8065/api/v4/users/login
login=200

Step 9 - Where your data lives

All Mattermost state is on the dedicated Azure data disk mounted at /var/lib/mattermost. It survives image updates and can be snapshotted independently:

df -h /var/lib/mattermost | tail -1
/dev/sda 40G 285M 37G 1% /var/lib/mattermost

The file store (data/), plugins, logs and the PostgreSQL data directory (pgdata/) all live on this disk.

Step 10 - Put TLS in front for production

The image serves plain HTTP on port 80 so you can validate it immediately. Before you expose Mattermost to real users, terminate TLS with your own domain and a certificate.

A common approach is to point a DNS record at the VM, add an 443 inbound rule to the NSG, and use Certbot with the nginx plugin to obtain and install a certificate. Set ServiceSettings.SiteURL in the System Console (or config.json) to your https:// URL, so links and the realtime WebSocket use the correct host.

Support

SecureAnyCloud maintains this image and provides 24/7 support. Mattermost Team Edition is distributed under the MIT license. For product help, contact SecureAnyCloud support through the Azure Marketplace listing.

Deploy on Azure

Launch Mattermost Team Edition on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure