Skip to main content

Self-Host Mattermost: Open Source Slack for Teams 2026

·OSSAlt Team
mattermostslackteam-messagingcollaborationself-hostingdocker2026

TL;DR

Mattermost (MIT, ~30K GitHub stars, Go + React) is a self-hosted team messaging platform that closely mirrors Slack's UX. Channels, threads, mentions, file sharing, slash commands, webhooks, and integrations — all in a self-hosted package. Slack Pro costs $7.25/user/month ($145/month for 20 users). Mattermost Team Edition is free for any team size. The paid Enterprise features (SSO, compliance exports, advanced permissions) are optional.

Key Takeaways

  • Mattermost: MIT license, ~30K stars, Go + React — self-hosted, unlimited users free
  • Slack UX parity: Channels, DMs, threads, reactions, file sharing, search
  • Integrations: Webhooks, slash commands, bots, GitHub/GitLab/Jira integrations
  • Mobile apps: iOS and Android apps (free, unofficial builds also available)
  • RAM: ~500MB for the app + Postgres
  • Enterprise: SSO, compliance export, advanced RBAC available in paid tiers

Mattermost vs Matrix vs Slack

FeatureMattermost CEMatrix + SynapseSlack Pro
LicenseMITApache 2.0Proprietary
CostFree (hosting)Free (hosting)$7.25/user/mo
Slack-like UXYes (near identical)Different (Element UI)Native
FederationNoYes (Matrix)No
E2EEBetaYesNo
BridgingLimited30+ bridgesYes (paid)
LDAP/OIDCFree (basic)YesYes
ThreadsYesYesYes
CallsPluginElement CallYes
GitHub Stars~30K~12K

Part 1: Docker Setup

# docker-compose.yml
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: mattermost
      POSTGRES_USER: mattermost
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U mattermost"]
      interval: 10s

  mattermost:
    image: mattermost/mattermost-team-edition:latest
    container_name: mattermost
    restart: unless-stopped
    ports:
      - "8065:8065"
    depends_on:
      postgres:
        condition: service_healthy
    volumes:
      - mattermost_config:/mattermost/config
      - mattermost_data:/mattermost/data
      - mattermost_logs:/mattermost/logs
      - mattermost_plugins:/mattermost/plugins
    environment:
      MM_SQLSETTINGS_DRIVERNAME: postgres
      MM_SQLSETTINGS_DATASOURCE: "postgres://mattermost:${POSTGRES_PASSWORD}@postgres:5432/mattermost?sslmode=disable"
      MM_SERVICESETTINGS_SITEURL: "https://chat.yourdomain.com"
      MM_SERVICESETTINGS_LISTENADDRESS: ":8065"

volumes:
  postgres_data:
  mattermost_config:
  mattermost_data:
  mattermost_logs:
  mattermost_plugins:
docker compose up -d

Part 2: HTTPS with Caddy

chat.yourdomain.com {
    reverse_proxy localhost:8065
}

Visit https://chat.yourdomain.com → create admin account → create your team.


Part 3: Initial Configuration

After first login:

System Console → Site Configuration:

  • Site URL: https://chat.yourdomain.com
  • Enable invitations: Yes or No
  • Allow team creation: Yes (open) or No (admin only)

System Console → Email:

SMTP Server: smtp.yourdomain.com
SMTP Port: 587
SMTP Username: noreply@yourdomain.com
SMTP Password: your-smtp-password

Disable open registration (admin creates accounts or invites): System Console → Authentication → Email → Enable account creation: Off


Part 4: Invite and Onboard Team Members

System Console → User Management → Invite People

Or share invite link: https://chat.yourdomain.com/signup_user_complete/?id=TEAM_ID

Bulk import users from CSV:

# Create import file:
cat > users.jsonl << 'EOF'
{"type":"user","user":{"username":"jsmith","email":"jsmith@company.com","first_name":"John","last_name":"Smith"}}
{"type":"user","user":{"username":"alee","email":"alee@company.com","first_name":"Amy","last_name":"Lee"}}
EOF

# Import:
docker exec mattermost ./mattermost import bulk users.jsonl --apply

Part 5: Channels and Workspace Setup

Create Channels

In any team:

  • +New Channel → Public or Private
  • Suggested channels: #general, #announcements, #engineering, #random, #ops

Channel Types

  • Public: Visible and joinable by all team members
  • Private: Invite-only, doesn't appear in channel list
  • Direct Messages: 1:1 private chat
  • Group Messages: Up to 8 people, no channel name

Part 6: Webhooks and Integrations

Incoming Webhook (External → Mattermost)

  1. Main Menu → Integrations → Incoming Webhooks → Add Incoming Webhook
  2. Choose channel
  3. Copy webhook URL
# Post to Mattermost from any script:
curl -X POST https://chat.yourdomain.com/hooks/your-webhook-id \
  -H 'Content-Type: application/json' \
  -d '{"text": "Deploy complete for v2.1.0 ✅", "channel": "engineering"}'

Outgoing Webhook (Mattermost → External)

Fire a webhook when a user says a keyword:

  1. Integrations → Outgoing Webhooks → Add
  2. Trigger word: !deploy
  3. Callback URL: your service endpoint
  4. When someone types !deploy, Mattermost POSTs to your URL

Slash Commands

Create a custom slash command:

  1. Integrations → Slash Commands → Add Slash Command
  2. Command: /standup
  3. Request URL: https://your-bot.yourdomain.com/standup
  4. Usage: Users type /standup → your service gets a request → responds to channel

Part 7: GitHub Integration

  1. Main Menu → Integrations → GitHub Plugin (or install from marketplace)
  2. Set GitHub OAuth App credentials
  3. /github connect in any channel to link your GitHub account
  4. /github subscribe org/repo — get PR/issue notifications in channel
New PR from jsmith:
Fix login timeout issue (#247)
https://github.com/org/repo/pull/247

Part 8: GitLab Notifications

# In GitLab project: Settings → Integrations → Mattermost
# or use generic webhook:

curl https://chat.yourdomain.com/hooks/YOUR_HOOK_ID \
  -d '{"text":"New commit to main by @jsmith: Fix authentication bug"}'

Part 9: LDAP / OIDC SSO

Free LDAP (basic): System Console → Authentication → LDAP:

  • LDAP Server: ldap.yourdomain.com
  • Base DN: dc=yourdomain,dc=com
  • Bind Username / Password

OIDC via Authentik (free in Community Edition): System Console → Authentication → OpenID Connect:

  • Discovery Endpoint: https://auth.yourdomain.com/application/o/mattermost/.well-known/openid-configuration
  • Client ID + Secret from Authentik

Part 10: Calls Plugin

Enable voice and screen sharing via the Calls plugin:

  1. System Console → Plugin Marketplace → Install Calls
  2. Enable the plugin
  3. Configure STUN server (uses Google's by default, or self-host coturn)
  4. Users can start calls in any channel

Maintenance

# Update Mattermost:
docker compose pull
docker compose up -d

# Backup:
docker exec postgres pg_dump -U mattermost mattermost | gzip \
  > mattermost-db-$(date +%Y%m%d).sql.gz

tar -czf mattermost-data-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect mattermost_mattermost_data --format '{{.Mountpoint}}')

# Logs:
docker compose logs -f mattermost

# Admin CLI:
docker exec mattermost ./mattermost user list
docker exec mattermost ./mattermost channel list your-team-name

See all open source team communication tools at OSSAlt.com/alternatives/slack.

Comments