Introduction
Mattermost is a self-hosted, open-source messaging platform designed as a secure alternative to Slack or Microsoft Teams. In 2026, it's still the top choice for DevOps, IT teams, and companies with data sovereignty requirements, thanks to its native GDPR compliance and Kubernetes support.
This beginner tutorial guides you step-by-step through installing Mattermost locally with Docker Compose, including a dedicated PostgreSQL database. You'll learn to launch the server, complete the initial web setup, create your first team, and invite members. Why Docker? It simplifies installation on any OS (Linux, macOS, Windows), manages dependencies automatically, and enables easy scaling.
At the end, you'll have a working Mattermost instance ready for 100+ users in 15 minutes. Think of it like assembling Lego with clear instructions—no complex tools needed. The benefits: cut costs (free vs. $10/user/month for Slack) and own your data.
Prerequisites
- Docker version 27+ and Docker Compose v2.29+ installed (check with
docker --versionanddocker compose version). - Ports 8065 (Mattermost HTTP) and 5432 (Postgres, internal) available.
- At least 4 GB RAM and 2 vCPUs for testing (8 GB recommended for production).
- Basic terminal knowledge (copy-paste is enough for beginners).
- A domain or local IP for access (e.g., localhost:8065).
Create the Docker Compose file
version: '3.8'
services:
db:
build:
context: .
dockerfile: postgres/Dockerfile
restart: unless-stopped
volumes:
- ./volumes/db/var/lib/postgresql/data:/var/lib/postgresql/data:rw
environment:
POSTGRES_USER: mmuser
POSTGRES_PASSWORD: mmuser_password
POSTGRES_DB: mattermost
networks:
- mattermost
app:
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
depends_on:
- db
ports:
- '8065:8065'
volumes:
- ./volumes/app/mattermost/config:/mattermost/config:rw
- ./volumes/app/mattermost/data:/mattermost/data:rw
- ./volumes/app/mattermost/logs:/mattermost/logs:rw
- ./volumes/app/mattermost/plugins:/mattermost/plugins:rw
- ./volumes/app/mattermost/client/plugins:/mattermost/client/plugins:rw
environment:
- MM_USERNAME=mmuser
- MM_PASSWORD=mmuser_password
- MM_DATABASE=mattermost
- MM_SERVICESETTINGS_SITEURL=http://localhost:8065
- MM_SERVICESETTINGS_LISTENADDRESS=:8065
networks:
- mattermost
networks:
mattermost:
driver: bridge
volumes:
db_data:
app_data:This docker-compose.yml defines two services: db (custom PostgreSQL for performance) and app (official Mattermost). Volumes persist data outside containers to avoid losses on restart. Environment variables set up the DB and access URL. Tip: Don't forget :rw on volumes for write access; validate with docker compose config before up.
Launch Mattermost
Place the file in an empty folder (e.g., mattermost-local/). Create subfolders ./volumes/app/mattermost/ and ./volumes/db/var/lib/postgresql/data/ with mkdir -p. Run the commands from the next code section. Docker will download ~1 GB of images (first time only). Wait 2-3 minutes for DB initialization (check logs: docker compose logs -f). Access http://localhost:8065—the setup wizard will appear.
Start the containers
#!/bin/bash
# Clone the official Dockerfiles repo (optional, for custom builds)
git clone https://github.com/mattermost/docker.git .
# Create volumes if missing
mkdir -p volumes/app/mattermost/{config,data,logs,plugins,client/plugins}
mkdir -p volumes/db/var/lib/postgresql/data
# Launch in background
./bin/docker compose up -d
# Check status
echo "DB Logs:"
docker compose logs db
echo "\nApp Logs:"
docker compose logs app
# Wait for init (manual or sleep 120)
sleep 10
echo "Mattermost ready at http://localhost:8065"This bash script clones the official Dockerfiles (for 2026 compatibility), creates volumes, and runs docker compose up -d in daemon mode. Logs help with debugging. Tip: If DB error 'role does not exist', rerun up after 30s; use docker compose down -v for a full reset.
Initial setup via web interface
At http://localhost:8065, follow the wizard:
- Database Setup: URL
postgres://mmuser:mmuser_password@db:5432/mattermost?sslmode=disable&connect_timeout=10. - Site URL:
http://localhost:8065. - Admin Account: Create
admin@localwith a strong password.
Submit: Mattermost restarts automatically. Log in as admin. Analogy: Like setting up a WiFi router, but with persistent DB storage.
Email (SMTP) configuration
{
"ServiceSettings": {
"SMTPServer": "smtp.gmail.com",
"SMTPPort": "587",
"SMTPUsername": "votre.email@gmail.com",
"SMTPPassword": "votre-app-password",
"ConnectionSecurity": "TLS",
"SendEmailNotifications": true,
"FeedbackName": "Mattermost",
"FeedbackEmail": "feedback@local"
},
"EmailSettings": {
"EnableSignUpWithEmail": true,
"RequireEmailVerification": true
}
}Copy this JSON to ./volumes/app/mattermost/config/config.json and restart (docker compose restart app). It enables email notifications via Gmail (use 2026 App Password). Tip: TLS required for Gmail; test in Mattermost's /admin_console/general/email. Configs persist outside containers.
Create your first team
In the interface:
- Click + Create Team > Name
MyTeam> Description. - Invite Members: Via email or link (e.g., http://localhost:8065/signup_user_complete/?id=xxx).
Visual: Teams are like Slack workspaces. Create channels
#general, #random. Share files (50 MB limit by default).Automated backup script
#!/bin/bash
BACKUP_DIR="/path/to/backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p $BACKUP_DIR
# Backup DB
docker compose exec db pg_dump -U mmuser mattermost > $BACKUP_DIR/mattermost.sql
# Backup app data
cp -r volumes/app/mattermost/{config,data,logs,plugins} $BACKUP_DIR/
tar czf $BACKUP_DIR.tar.gz -C /path/to/backups $BACKUP_DIR
rm -rf $BACKUP_DIR
echo "Backup created: $BACKUP_DIR.tar.gz"
# Cron: add to crontab -e
# 0 2 * * * /path/to/backup.shThis bash script dumps the Postgres DB and archives app volumes. Run chmod +x backup.sh. Add to cron for nightly backups at 2 AM. Tip: Customize /path/to/backups; test restore with docker compose down -v then SQL import.
Install a plugin (e.g., Jira)
#!/bin/bash
PLUGIN_URL="https://github.com/mattermost/mattermost-plugin-jira/releases/download/v2.4.0/com.mattermost.jira.tar.gz"
PLUGIN_DIR="./volumes/app/mattermost/plugins"
# Download and extract
wget -O /tmp/jira.tar.gz $PLUGIN_URL
tar -xzf /tmp/jira.tar.gz -C $PLUGIN_DIR
rm /tmp/jira.tar.gz
# Restart app
./bin/docker compose restart app
echo "Jira plugin installed. Enable in System Console > Plugins > Jira."Script to install the official Jira plugin (2026 compatible). Places it in ./plugins and auto-restarts. Tip: Only signed plugins in production; check logs with docker compose logs app for errors. Extends Mattermost without rebuilding.
Best practices
- Security: Change default DB passwords; enable HTTPS with Let's Encrypt + Nginx reverse proxy.
- Scalability: Switch to Kubernetes for >500 users; add Redis for caching.
- Monitoring: Integrate Prometheus (
docker compose exec app mattermost plugin add mattermost-prometheus). - Updates: Run
docker compose pull && up -dmonthly; test in staging. - 3-2-1 Backups: 3 copies, 2 media types, 1 offsite.
Common errors to avoid
- Port in use: Run
lsof -i:8065andkill; or change port in compose. - DB not initialized: Wait 2 min or
docker compose logs db | grep ready. - Config.json not read: Fix ownership
chown -R 2000:2000 volumes/app/mattermost/(Mattermost UID). - Email fails: Verify Gmail App Password (not regular password).
Next steps
- Official docs: Mattermost Docker.
- Advanced: Kubernetes Helm Chart.
- Plugins marketplace: 100+ available.
- Check our Learni DevOps and collaboration courses to master Mattermost in production.