Deploying Mattermost on Azure with Private MySQL Backend

Soham RoySoham Roy
6 min read

✨ Objective :

Deploy a secure, self-hosted team communication platform (Mattermost) using Microsoft Azure services. This includes:

  • Creating a custom virtual network with public/private subnets

  • Deploying VMs in each subnet

  • Hosting MySQL in the private subnet

  • Hosting Mattermost in the public subnet


πŸ›οΈ Architecture Overview

Key Components:

  • Virtual Network (VNet): Logical network to isolate resources

  • Subnets:

    • Public Subnet: Hosts Mattermost (internet-facing)

    • Private Subnet: Hosts MySQL (no internet exposure)

  • NSGs (Security Groups):

    • Public subnet can access internet

    • Private subnet only accessible from public subnet


πŸš€ Implementation Steps

Step 1: Set Up Azure Environment

1. . Create Resource Group

  • Go to the Azure Portal

  • Search for Resource Groups in the top bar and click + Create

  • Choose a subscription and enter a unique Resource Group name (e.g., rg-mattermost)

  • Select a region (e.g., East US) and click Review + Create > Create

2. Create Virtual Network (VNet) with two subnets: public-subnet, private-subnet

  • In the Azure Portal, search for Virtual Networks and click + Create

  • Select the previously created Resource Group and give the VNet a name (e.g., vnet-mattermost)

  • Set the region to match your resource group (e.g., East US)

  • Under IP Addresses, define an address space (e.g., 10.0.0.0/16)

  • Click + Add subnet:

    • Subnet name: public-subnet

    • Subnet address range: 10.0.1.0/24

  • Click + Add subnet again:

    • Subnet name: private-subnet

    • Subnet address range: 10.0.2.0/24

  • Click Review + Create > Create

πŸ” Configure NSG Rules

πŸ”Ή Public VM NSG: Allow inbound ports 22, 80, 443

  1. Go to Azure Portal β†’ Network Security Groups

  2. Click + Create, give it a name like public-nsg, assign the same region and resource group

  3. Once created, open the public-nsg

  4. Go to Inbound security rules β†’ + Add

    • Name: Allow-SSH
      Port: 22
      Protocol: TCP
      Source: Any
      Priority: 100

    • Name: Allow-HTTP
      Port: 80
      Protocol: TCP
      Source: Any
      Priority: 101

    • Name: Allow-HTTPS
      Port: 443
      Protocol: TCP
      Source: Any
      Priority: 102

  5. Click Save after adding each rule

  6. Go to Networking tab of the public VM β†’ Attach Network Security Group β†’ select public-nsg


    πŸ›‘οΈ Private VM Network Configuration

    πŸ”Ή Ensure No Public IP for Private VM

    1. During VM creation β†’ on the Networking tab:

      • Under NIC network configuration, select private-subnet

      • Public IP: Choose None

    2. Complete the VM creation process

πŸ”Ή Ensure VM is Attached to Private Subnet Only

  1. Go to the VM β†’ Networking tab

  2. Confirm the NIC is in the private-subnet

  3. Confirm there is no associated public IP


πŸš€ Step 2: Provision Virtual Machines

πŸ”Ή VM 1: Public VM (Mattermost)

  1. Go to Azure Portal β†’ Virtual Machines β†’ + Create β†’ Azure virtual machine

  2. Basics Tab:

    • Subscription: Select your active subscription

    • Resource Group: Use the one created earlier

    • Virtual Machine Name: mattermost-vm

    • Region: Same as your VNet

    • Image: Ubuntu Server 20.04 LTS

    • Size: e.g., Standard B1s (adjust as needed)

    • Authentication type: Password or SSH

    • Username: your choice (e.g., azureuser)

    • Password/SSH Key: enter accordingly

  3. Inbound Ports:

    • Select Allow selected ports

    • Check SSH (22), HTTP (80), HTTPS (443)

  4. Networking Tab:

    • Virtual Network: Select the one you created

    • Subnet: Select public-subnet

    • Public IP: Create new or use auto-assigned

    • NIC network security group: Attach public-nsg

  5. Disks, Management, Monitoring: Leave default or customize

  6. Click Review + Create, then Create

πŸ”Ή VM 2: Private VM (MySQL)

  1. Go to Azure Portal β†’ Virtual Machines β†’ + Create

  2. Basics Tab:

    • Name: mysql-vm

    • Same configuration as above: Ubuntu 20.04, same region, same resource group

    • Authentication type: Password or SSH (same user is okay)

  3. Inbound Ports:

    • Select: None (We don't want this VM publicly reachable)
  4. Networking Tab:

    • Virtual Network: Same VNet

    • Subnet: Select private-subnet

    • Public IP: None (this is critical)

    • NIC network security group: Attach private-nsg

  5. Disks, Management, Monitoring: Leave default or configure as needed

  6. Click Review + Create, then Create

βœ… Once both VMs are created:

  • You can SSH into the public VM using its public IP

  • You’ll access the private VM via private IP from within the public VM (bastion-style)


Step 3: Install and Configure MySQL (Private VM)

sudo apt update
sudo apt install mysql-server
sudo systemctl start mysql.service

Secure MySQL and set root password:

sudo mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'yourpassword';
exit
sudo mysql_secure_installation

Create a database and a user:

sudo mysql -u root -p
CREATE DATABASE mattermost;
CREATE USER 'mmuser'@'%' IDENTIFIED BY 'mmuser-password';
GRANT ALL PRIVILEGES ON mattermost.* TO 'mmuser'@'%';
FLUSH PRIVILEGES;
exit

Step 4: Install Mattermost (Public VM)

wget https://d6opu47qoi4ee.cloudfront.net/install_mattermost_linux.sh
sudo apt install dos2unix -y
sudo dos2unix install_mattermost_linux.sh
chmod 700 install_mattermost_linux.sh
sudo ./install_mattermost_linux.sh <PRIVATE_IP_OF_MYSQL_VM>

Set correct permissions:

sudo chown -R mattermost:mattermost /opt/mattermost
sudo chmod -R g+w /opt/mattermost
cd /opt/mattermost
sudo -u mattermost ./bin/mattermost

🌐 Access Mattermost via the public VM’s external IP in a browser.

🧭 Post-Installation Setup & Configuration

Once Mattermost is accessible in the browser via the public VM IP, complete the following steps:

1. Complete the Initial Setup Wizard

  • Visit http://<public_vm_ip>:8065

  • Fill in:

    • Admin Email

    • Username & Password

  • Click Create Account to proceed to the admin dashboard

2. Configure System Console Settings

  • Go to System Console β†’ Environment β†’ Database

  • Confirm the DB string is:
    mysql://mmuser:mmuser-password@<private_mysql_ip>:3306/mattermost

  • Set:

    • Site URL to your public IP or custom domain

    • Optional: Email, file storage, and logging settings

3. Configure Reverse Proxy (Optional)

If you want Mattermost to run on ports 80/443 (standard web ports):

  • Install Nginx:

      sudo apt install nginx
    
  • Create an Nginx config:

      server {
        listen 80;
        server_name your_domain_or_public_ip;
    
        location / {
          proxy_pass http://localhost:8065;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
          proxy_set_header Host $http_host;
          proxy_set_header X-Real-IP $remote_addr;
        }
      }
    

    Restart Nginx:

      sudo systemctl restart nginx
    

4. Enable HTTPS (Optional)

  • Install Certbot:

      sudo apt install certbot python3-certbot-nginx
    
  • Run setup:

      sudo certbot --nginx
    

5. Run Mattermost as a systemd Service

  • Set up: Create a proper service unit file at /lib/systemd/system/mattermost.service or /etc/systemd/system/mattermost.service:
init
Copy
Edit
[Unit]
Description=Mattermost
After=network.target

[Service]
Type=simple
ExecStart=/opt/mattermost/bin/mattermost
WorkingDirectory=/opt/mattermost
User=mattermost
Group=mattermost
Restart=always
LimitNOFILE=49152

[Install]
WantedBy=multi-user.target
  •       sudo systemctl daemon-reexec
          sudo systemctl enable mattermost
          sudo systemctl start mattermost
    
  • Monitor:

      sudo journalctl -u mattermost.service
    

πŸ“– Lessons & Observations

Lessons Learned

  • Architecture must be tailored to workload needs

  • Security is key: subnet isolation, NSGs, strong passwords

  • Plan for scalability and monitor performance

  • Azure managed services reduce complexity

Observations

  • Azure's flexibility is powerful but requires planning

  • Understanding networking, compute, and identity is critical

  • Always balance cost vs. performance

  • Leverage community and documentation for faster troubleshooting


πŸ“ˆ Summary

This deployment demonstrates a real-world use case of hosting a secure team chat platform using Azure. It reflects core principles of:

  • Cloud architecture design

  • Subnet isolation for security

  • Real-time app + DB connectivity

This guide is reusable for teams looking to build compliant, scalable, self-hosted collaboration tools.


CloudOps Journal: Practical AWS, DevOps & scripting β€” one hands-on cloud project at a time.

You can connect with me on LinkedIn here ~ Soham Roy

0
Subscribe to my newsletter

Read articles from Soham Roy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Soham Roy
Soham Roy

Hi, I’m Soham Royβ€”a cloud and DevOps practitioner, passionate about making Cloud(AWS/Azure/GCP) infrastructure and automation accessible to everyone. I write detailed, visual guides on setting up cloud environments, automating operations, and building CI/CD pipelines. My goal: help you master cloud technologies, boost efficiency, and avoid common pitfalls!