Communication intermediate ⏱ 45 minutes

Mattermost: Self-Hosted Slack Alternative

Team collaboration platform with channels, integrations, and compliance features.

By homelabbing.io • 2025-12-17
#mattermost#slack#chat#collaboration#docker

Introduction

If you’ve ever wanted the power and user experience of Slack without the recurring costs, data privacy concerns, or message limits, Mattermost is your answer. It’s an open-source, self-hosted team collaboration platform that delivers enterprise-grade messaging with the control and customization that homelabbers and small businesses demand.

What you’ll learn:

  • Deploy Mattermost Team Edition with Docker Compose
  • Configure PostgreSQL for production reliability
  • Set up teams, channels, and user management
  • Install plugins for extended functionality
  • Configure mobile apps (iOS/Android)
  • Implement LDAP/SAML authentication
  • Enable compliance features and data retention
  • Optimize performance and troubleshoot issues

Prerequisites:

  • Docker and Docker Compose installed (v24.0+ and v2.20+)
  • Reverse proxy configured (Caddy, Nginx, or Traefik)
  • Domain name with SSL certificate
  • 2+ GB RAM, 10+ GB storage (for small teams)
  • Basic understanding of team collaboration tools
  • PostgreSQL familiarity (helpful but not required)

Why Mattermost?

The Slack Problem

Slack dominates team collaboration, but presents challenges:

  • Cost: $8-15 per user per month adds up fast
  • Message Limits: Free tier limits searchable message history
  • Data Control: Your conversations stored on Slack’s servers
  • Vendor Lock-in: Difficult to export data and migrate
  • Compliance: May not meet regulatory requirements

How Mattermost Solves This

Mattermost provides Slack-like features with complete control:

FeatureMattermost Team EditionSlack FreeSlack Pro
CostFree (self-hosted)Free$8/user/month
Message HistoryUnlimited90 daysUnlimited
File StorageYour disk space5GB total10GB/user
IntegrationsUnlimited10 appsUnlimited
UsersUnlimitedUnlimitedUnlimited
SSO/SAMLPaid add-onNoEnterprise only
Data Control100% yoursSlack’s serversSlack’s servers

Key Features

  • Real-time Messaging: Instant chat with threaded conversations
  • Channels: Public, private, and direct message channels
  • File Sharing: Upload documents, images, videos (configurable limits)
  • Search: Full-text search across all messages and files
  • Mobile Apps: Native iOS and Android applications
  • Integrations: Webhooks, slash commands, OAuth 2.0
  • Plugins: Extend functionality (Jira, GitHub, Zoom, etc.)
  • Voice Calls: Built-in audio calling and screen sharing
  • Compliance: Message retention, data export, audit logs

Mattermost Editions

Team Edition (Free):

  • Core messaging features
  • Unlimited users and teams
  • Unlimited message history
  • Mobile apps
  • Plugins and integrations
  • Perfect for homelabs and small teams

Professional/Enterprise (Paid):

  • LDAP/SAML authentication
  • Advanced compliance features
  • High availability clustering
  • Premium support
  • Guest accounts
  • Advanced permissions

This guide focuses on Team Edition with workarounds for enterprise features where possible.


Architecture Overview

Internet → Reverse Proxy (HTTPS) → Mattermost Server → PostgreSQL
              ↓                           ↓
         SSL/TLS (443)              Port 8065
              ↓
      Users (Web/Mobile)

Components:

  • Mattermost Server: Go application handling API, WebSocket, and file serving
  • PostgreSQL: Database storing messages, users, teams, and configuration
  • Reverse Proxy: Handles HTTPS, SSL termination, and routing
  • File Storage: Local filesystem or S3-compatible object storage

Resource Requirements:

UsersRAMCPUStorage
Under 502 GB1 core10 GB
50-1004 GB2 cores25 GB
100-5008 GB4 cores50+ GB
500+16+ GB8+ cores100+ GB

Installation: Docker Compose Method

Step 1: Create Directory Structure

mkdir -p /opt/mattermost/{data,config,logs,plugins,client-plugins}
mkdir -p /opt/mattermost/postgres_data
cd /opt/mattermost

Step 2: Create docker-compose.yml

version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    container_name: mattermost-postgres
    restart: always
    environment:
      POSTGRES_DB: mattermost
      POSTGRES_USER: mattermost
      POSTGRES_PASSWORD: CHANGE_THIS_SECURE_PASSWORD
      POSTGRES_HOST_AUTH_METHOD: scram-sha-256
      POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=en_US.UTF-8"
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
    networks:
      - mattermost
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U mattermost"]
      interval: 10s
      timeout: 5s
      retries: 5

  mattermost:
    image: mattermost/mattermost-team-edition:latest
    container_name: mattermost
    restart: always
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      # Database Configuration
      MM_SQLSETTINGS_DRIVERNAME: postgres
      MM_SQLSETTINGS_DATASOURCE: postgres://mattermost:CHANGE_THIS_SECURE_PASSWORD@postgres:5432/mattermost?sslmode=disable&connect_timeout=10

      # Site Configuration
      MM_SERVICESETTINGS_SITEURL: https://chat.example.com
      MM_SERVICESETTINGS_LISTENADDRESS: :8065

      # File Storage
      MM_FILESETTINGS_DRIVERNAME: local
      MM_FILESETTINGS_DIRECTORY: /mattermost/data/
      MM_FILESETTINGS_MAXFILESIZE: 52428800  # 50 MB

      # Email Configuration (optional - configure later)
      # MM_EMAILSETTINGS_ENABLESMTPAUTH: true
      # MM_EMAILSETTINGS_SMTPUSERNAME: [email protected]
      # MM_EMAILSETTINGS_SMTPPASSWORD: your-app-password
      # MM_EMAILSETTINGS_SMTPSERVER: smtp.gmail.com
      # MM_EMAILSETTINGS_SMTPPORT: 587
      # MM_EMAILSETTINGS_FEEDBACKEMAIL: [email protected]

      # Performance
      MM_SERVICESETTINGS_ENABLELINKPREVIEWS: true
      MM_SERVICESETTINGS_ENABLESVGS: true

      # Security
      MM_SERVICESETTINGS_ENABLEDEVELOPER: false
      MM_SERVICESETTINGS_ENABLEINSECUREOUTGOINGCONNECTIONS: false

      # Plugin Settings
      MM_PLUGINSETTINGS_ENABLE: true
      MM_PLUGINSETTINGS_ENABLEUPLOADS: true

      # Timezone
      TZ: America/New_York

    volumes:
      - ./config:/mattermost/config:rw
      - ./data:/mattermost/data:rw
      - ./logs:/mattermost/logs:rw
      - ./plugins:/mattermost/plugins:rw
      - ./client-plugins:/mattermost/client/plugins:rw
    ports:
      - "8065:8065"
    networks:
      - mattermost
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8065/api/v4/system/ping"]
      interval: 30s
      timeout: 10s
      retries: 3

networks:
  mattermost:
    driver: bridge

Important: Replace CHANGE_THIS_SECURE_PASSWORD with a strong password in both places.

Step 3: Configure Reverse Proxy

Caddy Configuration:

chat.example.com {
    reverse_proxy mattermost:8065 {
        # WebSocket support
        header_up X-Forwarded-Ssl on
        header_up X-Forwarded-Proto {scheme}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Host {host}
    }

    # Security headers
    header {
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
        X-XSS-Protection "1; mode=block"
        Strict-Transport-Security "max-age=31536000;"
    }

    # Increase timeouts for large uploads
    request_body {
        max_size 50MB
    }
}

Nginx Configuration:

upstream mattermost {
    server localhost:8065;
    keepalive 32;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;

server {
    server_name chat.example.com;

    location ~ /api/v[0-9]+/(users/)?websocket$ {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        client_max_body_size 50M;
        proxy_set_header Host $http_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_set_header X-Frame-Options SAMEORIGIN;
        proxy_buffers 256 16k;
        proxy_buffer_size 16k;
        client_body_timeout 60;
        send_timeout 300;
        lingering_timeout 5;
        proxy_connect_timeout 90;
        proxy_send_timeout 300;
        proxy_read_timeout 90s;
        proxy_pass http://mattermost;
    }

    location / {
        client_max_body_size 50M;
        proxy_set_header Connection "";
        proxy_set_header Host $http_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_set_header X-Frame-Options SAMEORIGIN;
        proxy_buffers 256 16k;
        proxy_buffer_size 16k;
        proxy_read_timeout 600s;
        proxy_cache mattermost_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 2;
        proxy_cache_use_stale timeout;
        proxy_cache_lock on;
        proxy_http_version 1.1;
        proxy_pass http://mattermost;
    }

    listen 443 ssl http2;
    ssl_certificate /etc/letsencrypt/live/chat.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/chat.example.com/privkey.pem;

    # SSL optimization
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
}

Step 4: Start Services

# Start all containers
docker compose up -d

# Monitor startup logs
docker compose logs -f mattermost

# Check container status
docker compose ps

First startup takes 30-60 seconds as Mattermost initializes the database schema.

Step 5: Initial Setup Wizard

  1. Navigate to https://chat.example.com
  2. Create first administrator account:
  3. Create your first team:
  4. Skip tutorial or walk through introduction
  5. You’re now in Mattermost!

Step 6: System Console Configuration

  1. Click profile icon → System Console
  2. Navigate through key settings:

Site Configuration:

  • Site URL: https://chat.example.com
  • Enable Email Notifications: true (configure SMTP later)

Authentication:

  • Enable Open Server: false (require email confirmation)
  • Session Length: 30 days
  • Enable MFA: true (optional)

Files and Storage:

  • Max File Size: 50 MB
  • Storage Driver: Local File System
  • Directory: /mattermost/data/

Notifications:

  • Enable Push Notifications: false (requires Mattermost Cloud)
  • Enable Email Notifications: true (requires SMTP)

Plugins:

  • Enable Plugins: true
  • Enable Plugin Uploads: true

Performance:

  • Enable Link Previews: true
  • Enable LaTeX Rendering: true (optional, for math formulas)

Click Save after each section.


Team and Channel Management

Creating Teams

Teams are isolated workspaces within Mattermost:

  1. Main Menu → Create a Team
  2. Team Name: “Engineering”
  3. Team URL: engineering
  4. Click Next
  5. Invite team members (optional)
  6. Click Finish

Use cases for multiple teams:

  • Departments (Engineering, Sales, Marketing)
  • Projects (Project Alpha, Project Beta)
  • Clients (Client A, Client B)
  • Public vs. Private workspaces

Channel Types

Public Channels:

  • Visible to all team members
  • Anyone on team can join
  • Example: #general, #random, #announcements

Private Channels:

  • Invite-only
  • Not visible in channel list to non-members
  • Example: #leadership, #hr, #finance

Direct Messages:

  • One-on-one conversations
  • Not visible to others

Group Messages:

  • Private conversations with up to 7 people

Creating Channels

  1. Click + next to Channels
  2. Select Create New Channel
  3. Configure:
    • Display Name: “Development”
    • Handle: dev (becomes /myteam/channels/dev)
    • Purpose: “Development team discussions”
    • Header: “All dev-related topics”
    • Make Private: unchecked (for public) or checked (for private)
  4. Click Create Channel

Channel Organization Best Practices:

#general - Default channel for announcements
#random - Water cooler chat
#support - Help requests
#dev-team - Development discussions
#marketing - Marketing coordination
#projects-alpha - Project-specific channel
#customers - Customer support

User Management

Inviting Users:

  1. Main Menu → Invite People
  2. Enter email addresses (one per line)
  3. Click Invite Members
  4. Users receive email with invitation link

User Roles:

  • System Admin: Full control over Mattermost instance
  • Team Admin: Manage team settings and members
  • Member: Standard user access
  • Guest: Limited access (Enterprise only in official version)

Promoting Users:

  1. System Console → Users
  2. Find user → Click email
  3. Role → Select role
  4. Save

Plugin Ecosystem

Plugins extend Mattermost functionality. Here are essential plugins:

Installing Plugins

Method 1: Marketplace (Recommended)

  1. Main Menu → Marketplace
  2. Search for plugin
  3. Click Install
  4. Enable in System Console → Plugins

Method 2: Manual Upload

  1. Download plugin .tar.gz file
  2. System Console → Plugins → Upload Plugin
  3. Select file → Upload
  4. Enable plugin

Essential Plugins

1. GitHub Plugin

Integrates GitHub notifications and actions:

# Install from marketplace
# Or download from: https://github.com/mattermost/mattermost-plugin-github

Features:

  • Subscribe to repository events in channels
  • Create issues from messages
  • Review PRs without leaving Mattermost
  • Link GitHub accounts

Configuration:

  1. Create GitHub OAuth app
  2. Configure in plugin settings
  3. Users connect accounts: /github connect

2. Jira Plugin

Connect Jira issues to conversations:

Features:

  • Create Jira issues from messages
  • Get notifications on issue updates
  • View issue details inline
  • Link Jira accounts

Setup:

/jira setup
# Follow OAuth authentication flow

3. Zoom Plugin

Start Zoom meetings directly from channels:

Features:

  • Start instant Zoom meetings: /zoom start
  • Schedule meetings with channel members
  • Post meeting links automatically

Configuration:

  1. Create Zoom OAuth app
  2. Configure OAuth credentials in plugin settings
  3. Users authenticate: /zoom connect

4. Google Calendar Plugin

Sync calendar events to Mattermost:

Features:

  • Daily schedule summaries
  • Meeting reminders
  • RSVP to events from Mattermost

5. Giphy Plugin

Add GIF reactions to messages:

/gif happy dance

6. WelcomeBot Plugin

Automatically welcome new users with helpful info.

Custom Integrations

Incoming Webhooks:

Post messages from external services:

  1. Integrations → Incoming Webhooks → Add
  2. Configure:
    • Title: “Monitoring Alerts”
    • Channel: #alerts
  3. Copy webhook URL

Example POST request:

curl -X POST https://chat.example.com/hooks/YOUR_WEBHOOK_ID   -H 'Content-Type: application/json'   -d '{
    "text": "Server CPU usage high: 95%",
    "username": "Monitoring Bot",
    "icon_emoji": ":warning:"
  }'

Outgoing Webhooks:

Trigger external services from Mattermost:

  1. Integrations → Outgoing Webhooks → Add
  2. Configure:
    • Trigger Words: !weather
    • Callback URL: https://your-service.com/webhook
    • Channel: Town Square
  3. Save

Slash Commands:

Create custom commands:

  1. Integrations → Slash Commands → Add
  2. Configure:
    • Command Trigger Word: weather
    • Request URL: https://your-service.com/weather
    • Method: POST
  3. Save

Usage: /weather San Francisco


Mobile App Configuration

iOS Setup

  1. Install “Mattermost” from App Store
  2. Open app → Enter Server URL
  3. Enter: https://chat.example.com
  4. Log in with credentials
  5. Allow notifications when prompted

Features:

  • Push notifications (requires enterprise or mobile app setup)
  • Offline message caching
  • File uploads (photos, videos, documents)
  • Biometric authentication (Face ID/Touch ID)

Android Setup

  1. Install “Mattermost” from Google Play
  2. Open app → Enter Server URL
  3. Enter: https://chat.example.com
  4. Log in with credentials
  5. Configure notifications

Features:

  • Push notifications
  • Share from other apps
  • File uploads
  • Fingerprint authentication

Enabling Push Notifications (Self-Hosted)

By default, push notifications require Mattermost Cloud or enterprise license. Workaround:

Option 1: Mattermost Push Proxy (Free)

  1. Sign up at https://mattermost.com/pl/
  2. System Console → Notifications → Mobile Push
  3. Push Notification Server: https://push-test.mattermost.com
  4. Save

Limitations: Shared service, best effort delivery

Option 2: Self-Hosted Push Proxy (Advanced)

Run your own Mattermost Push Notification Service:

# Clone repository
git clone https://github.com/mattermost/mattermost-push-proxy
cd mattermost-push-proxy

# Build Docker image
docker build -t mattermost-push-proxy .

# Run proxy
docker run -p 8066:8066 mattermost-push-proxy

Configure in System Console to use http://localhost:8066.


Email Configuration

Enable email notifications for mentions, direct messages, and updates:

Gmail Configuration

  1. Generate App Password:

  2. Update docker-compose.yml:

      MM_EMAILSETTINGS_ENABLESMTPAUTH: true
      MM_EMAILSETTINGS_SMTPUSERNAME: your-[email protected]
      MM_EMAILSETTINGS_SMTPPASSWORD: your-app-password-here
      MM_EMAILSETTINGS_SMTPSERVER: smtp.gmail.com
      MM_EMAILSETTINGS_SMTPPORT: 587
      MM_EMAILSETTINGS_SMTPSERVERTIMEOUT: 10
      MM_EMAILSETTINGS_CONNECTIONSECURITY: STARTTLS
      MM_EMAILSETTINGS_FEEDBACKEMAIL: [email protected]
      MM_EMAILSETTINGS_FEEDBACKNAME: Mattermost
      MM_EMAILSETTINGS_REPLYTOADDRESS: [email protected]
  1. Restart Mattermost:
docker compose restart mattermost
  1. Test email:
    • System Console → Notifications → Email
    • Connection Security: STARTTLS
    • Click Test Connection

Alternative SMTP Providers

Mailgun:

MM_EMAILSETTINGS_SMTPSERVER: smtp.mailgun.org
MM_EMAILSETTINGS_SMTPPORT: 587
MM_EMAILSETTINGS_SMTPUSERNAME: [email protected]

SendGrid:

MM_EMAILSETTINGS_SMTPSERVER: smtp.sendgrid.net
MM_EMAILSETTINGS_SMTPPORT: 587
MM_EMAILSETTINGS_SMTPUSERNAME: apikey
MM_EMAILSETTINGS_SMTPPASSWORD: YOUR_SENDGRID_API_KEY

Advanced Authentication

LDAP Integration (Workaround for Team Edition)

Official LDAP support requires Professional license, but you can use plugins:

Mattermost LDAP Plugin (Community):

While native LDAP requires paid license, you can:

  1. Use Authentik/Keycloak with OAuth 2.0
  2. Use SAML plugin (if available)
  3. Manage users via API automation

OAuth 2.0 with GitLab

Allow users to sign in with GitLab:

  1. Create GitLab application:

    • Visit GitLab → Applications → New
    • Redirect URI: https://chat.example.com/signup/gitlab/complete
    • Scopes: read_user
    • Save and copy Application ID and Secret
  2. Configure Mattermost:

# Add to docker-compose.yml
      MM_GITLABSETTINGS_ENABLE: true
      MM_GITLABSETTINGS_ID: YOUR_GITLAB_APP_ID
      MM_GITLABSETTINGS_SECRET: YOUR_GITLAB_SECRET
      MM_GITLABSETTINGS_AUTHENDPOINT: https://gitlab.com/oauth/authorize
      MM_GITLABSETTINGS_TOKENENDPOINT: https://gitlab.com/oauth/token
      MM_GITLABSETTINGS_USERAPIENDPOINT: https://gitlab.com/api/v4/user
  1. Restart and test login via GitLab button

Multi-Factor Authentication (MFA)

Enable MFA for enhanced security:

  1. System Console → Authentication → MFA
  2. Enable Multi-Factor Authentication: true
  3. Save

Users enable MFA:

  1. Account Settings → Security → MFA
  2. Scan QR code with authenticator app (Google Authenticator, Authy)
  3. Enter verification code
  4. Save backup codes

Enforce MFA for all users:

MM_SERVICESETTINGS_ENFORCEMULTIFACTORAUTHENTICATION: true

Compliance and Data Retention

Message Retention Policies

Automatically delete old messages:

  1. System Console → Compliance → Data Retention Policy
  2. Enable Message Retention: true
  3. Message Retention Period: 365 days
  4. File Retention Period: 365 days
  5. Run Policy: Daily at 02:00
  6. Save

Custom retention per channel (Enterprise feature):

Team Edition doesn’t support per-channel policies, but you can manually export/delete:

# Export channel data
docker exec mattermost mmctl channel archive CHANNEL_ID --permanent

# Bulk export all data
docker exec mattermost mattermost export bulk export.zip

Data Export

Manual Export:

  1. System Console → Compliance → Compliance Export
  2. Enable Compliance Exports: true
  3. Export Format: CSV or Actiance XML
  4. Daily Run Time: 02:00
  5. Save

Automated Daily Backup:

#!/bin/bash
# mattermost-export.sh

BACKUP_DIR="/opt/backups/mattermost"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"

# Export database
docker exec mattermost-postgres pg_dump -U mattermost mattermost |     gzip > "$BACKUP_DIR/mattermost-db-${DATE}.sql.gz"

# Export files and config
tar czf "$BACKUP_DIR/mattermost-data-${DATE}.tar.gz"     /opt/mattermost/data     /opt/mattermost/config     /opt/mattermost/plugins

# Cleanup old backups (keep 30 days)
find "$BACKUP_DIR" -name "mattermost-*.gz" -mtime +30 -delete

echo "Backup completed: $DATE"

Schedule:

0 3 * * * /opt/mattermost/mattermost-export.sh

Audit Logging

Enable detailed audit logs:

# docker-compose.yml
      MM_EXPERIMENTALSETTINGS_ENABLEAUTOMATICUSERSTATUSUPDATE: true
      MM_LOGSETTINGS_ENABLEWEBHOOKDEBUGGING: true
      MM_LOGSETTINGS_ENABLEDIAGNOSTICS: true

View logs:

docker compose logs -f mattermost | grep -i audit

Performance Tuning

Database Optimization

PostgreSQL Configuration:

Create postgres_data/postgresql.conf:

# Memory
shared_buffers = 512MB
effective_cache_size = 2GB
maintenance_work_mem = 128MB
work_mem = 8MB

# Checkpoint tuning
checkpoint_completion_target = 0.9
wal_buffers = 16MB

# Query planner
random_page_cost = 1.1
effective_io_concurrency = 200

# Connections
max_connections = 200

Mount in docker-compose.yml:

    command: postgres -c config_file=/etc/postgresql/postgresql.conf
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
      - ./postgresql.conf:/etc/postgresql/postgresql.conf

Database Maintenance:

# Weekly vacuum
docker exec mattermost-postgres psql -U mattermost -c "VACUUM ANALYZE;"

# Check database size
docker exec mattermost-postgres psql -U mattermost -c     "SELECT pg_size_pretty(pg_database_size('mattermost'));"

Mattermost Configuration

config.json Tuning:

Edit /opt/mattermost/config/config.json:

{
  "ServiceSettings": {
    "MaximumLoginAttempts": 10,
    "GoroutineHealthThreshold": -1,
    "EnablePostSearch": true,
    "EnableFileSearch": true,
    "EnableUserTypingMessages": true,
    "EnablePostUsernameOverride": false,
    "EnablePostIconOverride": false,
    "GoogleDeveloperKey": "",
    "EnableEmailInvitations": true
  },
  "SqlSettings": {
    "MaxIdleConns": 20,
    "MaxOpenConns": 300,
    "QueryTimeout": 30,
    "ConnMaxLifetimeMilliseconds": 3600000
  },
  "FileSettings": {
    "MaxFileSize": 52428800,
    "DriverName": "local",
    "Directory": "/mattermost/data/",
    "EnableFileAttachments": true,
    "EnableMobileUpload": true,
    "EnableMobileDownload": true
  }
}

Caching

Enable Redis for improved performance (optional):

# Add to docker-compose.yml
  redis:
    image: redis:7-alpine
    container_name: mattermost-redis
    restart: always
    command: redis-server --requirepass YOUR_REDIS_PASSWORD
    networks:
      - mattermost

Configure Mattermost to use Redis (requires config.json edit).


Monitoring and Troubleshooting

Health Checks

# Check service health
curl https://chat.example.com/api/v4/system/ping

# Check database connection
docker exec mattermost-postgres pg_isready -U mattermost

# View active users
docker exec mattermost mmctl user list

Common Issues

Issue 1: Users Cannot Upload Files

Symptoms: “File upload failed” error

Solutions:

# Check permissions
docker exec mattermost ls -la /mattermost/data

# Fix ownership
docker exec mattermost chown -R 2000:2000 /mattermost/data

# Verify max file size
# System Console → Files → Max File Size

Issue 2: Slow Performance

Symptoms: Messages delayed, page load slow

Solutions:

# Check resource usage
docker stats mattermost

# Analyze slow queries
docker exec mattermost-postgres psql -U mattermost -c     "SELECT query, mean_exec_time FROM pg_stat_statements      ORDER BY mean_exec_time DESC LIMIT 10;"

# Rebuild database indexes
docker exec mattermost-postgres psql -U mattermost -c "REINDEX DATABASE mattermost;"

Issue 3: Email Notifications Not Sending

Symptoms: Users not receiving email notifications

Solutions:

# Test SMTP connection
# System Console → Notifications → Email → Test Connection

# Check logs
docker compose logs mattermost | grep -i email

# Verify SMTP credentials
# Common issue: App password required for Gmail with 2FA

Issue 4: High Memory Usage

Symptoms: Container consumes excessive RAM

Solutions:

# Add resource limits to docker-compose.yml
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 1G

Logging Configuration

Enable detailed logging:

# docker-compose.yml
      MM_LOGSETTINGS_CONSOLELEVEL: DEBUG
      MM_LOGSETTINGS_FILELEVEL: INFO
      MM_LOGSETTINGS_ENABLEFILE: true

View logs:

# Real-time logs
docker compose logs -f mattermost

# Search for errors
docker compose logs mattermost | grep -i error

# Export logs to file
docker compose logs mattermost > /opt/mattermost/debug.log

Security Hardening

Essential Security Settings

  1. System Console → Security → Signup

    • Enable Open Server: false
    • Enable Email Invitations: true
    • Restrict team creation to admins
  2. System Console → Security → Password

    • Minimum Length: 10
    • Require Lowercase: true
    • Require Uppercase: true
    • Require Number: true
    • Require Symbol: true
  3. System Console → Security → Connections

    • Enable Insecure Outgoing Connections: false
    • Allow untrusted internal connections: false
  4. Session Security:

    • Session Length: 30 days
    • Extend Session Length on Activity: true
    • Session Cache: 10 minutes

Rate Limiting

Prevent brute-force attacks:

{
  "RateLimitSettings": {
    "Enable": true,
    "PerSec": 10,
    "MaxBurst": 100,
    "MemoryStoreSize": 10000,
    "VaryByRemoteAddr": true,
    "VaryByUser": false
  }
}

Content Security Policy

Add CSP headers in reverse proxy:

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;

Backup and Recovery

Automated Backup Script

#!/bin/bash
# mattermost-backup.sh

BACKUP_DIR="/opt/backups/mattermost"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

mkdir -p "$BACKUP_DIR"

echo "Starting Mattermost backup: $DATE"

# Backup PostgreSQL database
docker exec mattermost-postgres pg_dump -U mattermost mattermost |     gzip > "$BACKUP_DIR/db-${DATE}.sql.gz"

if [ $? -eq 0 ]; then
    echo "Database backup successful"
else
    echo "Database backup FAILED!" >&2
    exit 1
fi

# Backup Mattermost data and config
tar czf "$BACKUP_DIR/data-${DATE}.tar.gz"     /opt/mattermost/data     /opt/mattermost/config     /opt/mattermost/plugins

if [ $? -eq 0 ]; then
    echo "File backup successful"
else
    echo "File backup FAILED!" >&2
    exit 1
fi

# Cleanup old backups
find "$BACKUP_DIR" -name "*.gz" -mtime +$RETENTION_DAYS -delete

echo "Backup completed: $DATE"
echo "Backup size: $(du -sh $BACKUP_DIR | cut -f1)"

Schedule daily:

chmod +x /opt/mattermost/mattermost-backup.sh
crontab -e
# Add: 0 2 * * * /opt/mattermost/mattermost-backup.sh >> /var/log/mattermost-backup.log 2>&1

Disaster Recovery

# Stop services
cd /opt/mattermost
docker compose down

# Restore database
gunzip -c /opt/backups/mattermost/db-YYYYMMDD.sql.gz |     docker exec -i mattermost-postgres psql -U mattermost mattermost

# Restore files
tar xzf /opt/backups/mattermost/data-YYYYMMDD.tar.gz -C /

# Restart services
docker compose up -d

# Verify
docker compose logs -f mattermost

Conclusion

You now have a fully functional Mattermost Team Edition deployment with:

  • Production-ready Docker Compose configuration
  • PostgreSQL database for reliability
  • Team and channel management
  • Plugin ecosystem for extended functionality
  • Mobile app support for iOS and Android
  • Email notifications for user engagement
  • Compliance features and data retention
  • Automated backups and monitoring

Next steps:

  1. Invite team members and create channels
  2. Install essential plugins (GitHub, Jira, Zoom)
  3. Configure mobile apps for your team
  4. Set up automated backups
  5. Explore additional integrations
  6. Consider upgrading to Professional for LDAP/SAML

Mattermost provides enterprise-grade team collaboration without recurring costs or data privacy concerns. Your team’s communications are yours to control.


Additional Resources

Official:

Community:

Tools:


Last Updated: December 2025 Version Covered: Mattermost 9.11.0+ Word Count: 3,421 words