1
Why Self-Host Mattermost?
- Complete data sovereignty and privacy compliance (GDPR, HIPAA)
- Unlimited message history and file storage
- No per-user licensing fees for the open-source edition
- Custom integrations with internal tools and APIs
- Air-gapped deployment capability for sensitive environments
2
Prerequisites
RamNode VPS Requirements by Team Size
| Team Size | RAM | CPU | Storage |
|---|---|---|---|
| 1-50 users | 2 GB | 2 vCPUs | 25 GB SSD |
| 50-250 users | 4 GB | 4 vCPUs | 50 GB SSD |
| 250-1000 users | 8 GB | 6 vCPUs | 100 GB SSD |
| 1000+ users | 16+ GB | 8+ vCPUs | 200+ GB SSD |
Software Requirements
- Ubuntu 22.04 LTS or Debian 12
- Docker Engine 24.0+ and Docker Compose v2
- A registered domain name pointing to your VPS IP
- Root or sudo access
3
Initial Server Setup
Update system
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget gnupg lsb-release ca-certificatesConfigure firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable4
Install Docker
Install Docker Engine
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add repository
echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Add user to docker group
sudo usermod -aG docker $USER
newgrp docker5
Mattermost Deployment
Create directory structure
sudo mkdir -p /opt/mattermost/{config,data,logs,plugins,client-plugins}
sudo mkdir -p /opt/mattermost/postgres
cd /opt/mattermostCreate docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: mattermost-postgres
restart: unless-stopped
security_opt:
- no-new-privileges:true
pids_limit: 100
read_only: true
tmpfs:
- /tmp
- /var/run/postgresql
volumes:
- ./postgres:/var/lib/postgresql/data
environment:
- POSTGRES_USER=mattermost
- POSTGRES_PASSWORD=YOUR_SECURE_DB_PASSWORD
- POSTGRES_DB=mattermost
networks:
- mattermost-network
mattermost:
image: mattermost/mattermost-team-edition:latest
container_name: mattermost-app
restart: unless-stopped
depends_on:
- postgres
security_opt:
- no-new-privileges:true
pids_limit: 200
tmpfs:
- /tmp
volumes:
- ./config:/mattermost/config:rw
- ./data:/mattermost/data:rw
- ./logs:/mattermost/logs:rw
- ./plugins:/mattermost/plugins:rw
- ./client-plugins:/mattermost/client/plugins:rw
environment:
- TZ=UTC
- MM_SQLSETTINGS_DRIVERNAME=postgres
- MM_SQLSETTINGS_DATASOURCE=postgres://mattermost:YOUR_SECURE_DB_PASSWORD@postgres:5432/mattermost?sslmode=disable&connect_timeout=10
- MM_SERVICESETTINGS_SITEURL=https://chat.yourdomain.com
ports:
- '8065:8065'
networks:
- mattermost-network
networks:
mattermost-network:
driver: bridgeSet permissions and launch
# Mattermost runs as UID 2000
sudo chown -R 2000:2000 /opt/mattermost/config
sudo chown -R 2000:2000 /opt/mattermost/data
sudo chown -R 2000:2000 /opt/mattermost/logs
sudo chown -R 2000:2000 /opt/mattermost/plugins
sudo chown -R 2000:2000 /opt/mattermost/client-plugins
# Start containers
docker compose up -d
# Verify
docker compose ps
docker compose logs -f mattermost6
Nginx Reverse Proxy with SSL
Install Nginx
sudo apt install -y nginxCreate Nginx configuration
# /etc/nginx/sites-available/mattermost
upstream mattermost_backend {
server 127.0.0.1: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 {
listen 80;
listen [::]:80;
server_name chat.yourdomain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name chat.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/chat.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chat.yourdomain.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000" always;
# WebSocket support
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;
proxy_read_timeout 600s;
proxy_pass http://mattermost_backend;
}
location / {
client_max_body_size 100M;
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_backend;
}
}Enable site and obtain SSL
sudo ln -s /etc/nginx/sites-available/mattermost /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
# Install Certbot
sudo apt install -y certbot python3-certbot-nginx
# Obtain SSL certificate
sudo certbot --nginx -d chat.yourdomain.com
sudo systemctl restart nginx
sudo systemctl enable nginx7
Initial Configuration
Navigate to https://chat.yourdomain.com to create your first admin account and team.
Key Settings to Configure
| Setting | Recommendation |
|---|---|
| Site URL | Set to your full HTTPS URL |
| SMTP Settings | Configure for notifications |
| Rate Limiting | Enable (10 req/sec recommended) |
| Session Length | Set based on security needs |
Configure SMTP (Optional)
Add to docker-compose.yml environment
- MM_EMAILSETTINGS_ENABLESMTPAUTH=true
- MM_EMAILSETTINGS_SMTPUSERNAME=your-smtp-user
- MM_EMAILSETTINGS_SMTPPASSWORD=your-smtp-password
- MM_EMAILSETTINGS_SMTPSERVER=smtp.yourmailprovider.com
- MM_EMAILSETTINGS_SMTPPORT=587
- MM_EMAILSETTINGS_CONNECTIONSECURITY=STARTTLS
- MM_EMAILSETTINGS_FEEDBACKEMAIL=noreply@yourdomain.com8
Production Hardening
Security Best Practices
- Change default database password with a strong, random password
- Enable rate limiting to prevent brute-force attacks
- Configure session management with appropriate expiry
- Enable audit logging for compliance
- Restrict team creation permissions
Mattermost Deployed Successfully!
Your self-hosted team communication platform is now running. Create your team, configure integrations, and enjoy secure, unlimited messaging for your organization.
