Self-Host Mattermost: Open Source Slack for Teams 2026
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
| Feature | Mattermost CE | Matrix + Synapse | Slack Pro |
|---|---|---|---|
| License | MIT | Apache 2.0 | Proprietary |
| Cost | Free (hosting) | Free (hosting) | $7.25/user/mo |
| Slack-like UX | Yes (near identical) | Different (Element UI) | Native |
| Federation | No | Yes (Matrix) | No |
| E2EE | Beta | Yes | No |
| Bridging | Limited | 30+ bridges | Yes (paid) |
| LDAP/OIDC | Free (basic) | Yes | Yes |
| Threads | Yes | Yes | Yes |
| Calls | Plugin | Element Call | Yes |
| 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)
- Main Menu → Integrations → Incoming Webhooks → Add Incoming Webhook
- Choose channel
- 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:
- Integrations → Outgoing Webhooks → Add
- Trigger word:
!deploy - Callback URL: your service endpoint
- When someone types
!deploy, Mattermost POSTs to your URL
Slash Commands
Create a custom slash command:
- Integrations → Slash Commands → Add Slash Command
- Command:
/standup - Request URL:
https://your-bot.yourdomain.com/standup - Usage: Users type
/standup→ your service gets a request → responds to channel
Part 7: GitHub Integration
- Main Menu → Integrations → GitHub Plugin (or install from marketplace)
- Set GitHub OAuth App credentials
/github connectin any channel to link your GitHub account/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:
- System Console → Plugin Marketplace → Install Calls
- Enable the plugin
- Configure STUN server (uses Google's by default, or self-host coturn)
- 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.