Should I self-host Slack?
Per-seat pricing means the math flips hard around 4 seats — a 10-person team escapes $1,050/yr for one weekend of setup. Worth it if someone genuinely owns the pager; chat is the one service your team notices being down within 90 seconds.
Slack's mobile push reliability — Mattermost push routes through their relay or you build your own, and half-working push kills adoption
The integration directory: webhooks exist, but every SaaS ships a Slack app and maybe a Mattermost one
Huddles-grade calls without extra setup
Message history import is one-way and lossy — the escape is easier before the archive matters
channels & DMs · mobile apps with reliable push · search across full history · integrations & incoming webhooks · huddles/calls
* Percent of the subscription price. Your time is priced at the slider's rate — $0/h ("my homelab time is free and I love it") is a legitimate position. Every number is derived from the record, never hand-written. Price source, checked 2026-08-05.
Runs comfortably on a real VPS (2 GB+).


The image ships no shell, curl or wget, so a CMD-SHELL healthcheck fails forever while the server is fine — exec-form mmctl system status --local (with local mode enabled) is the probe that works
First admin account creation is a UI step — plan it into the rollout, whoever clicks first owns the workspace
# Mattermost Team Edition — self-hosted team chat (replaces Slack)
services:
mattermost:
image: mattermost/mattermost-team-edition:latest
container_name: mattermost
restart: unless-stopped
depends_on:
mm-postgres:
condition: service_healthy
environment:
MM_SQLSETTINGS_DRIVERNAME: postgres
MM_SQLSETTINGS_DATASOURCE: postgres://mmuser:mmpass@mm-postgres:5432/mattermost?sslmode=disable&connect_timeout=10
MM_SERVICESETTINGS_SITEURL: http://localhost:8065
MM_SERVICESETTINGS_ENABLELOCALMODE: "true"
ports:
- "8065:8065"
volumes:
- mm-data:/mattermost/data
- mm-logs:/mattermost/logs
- mm-config:/mattermost/config
- mm-plugins:/mattermost/plugins
- mm-client-plugins:/mattermost/client/plugins
- mm-bleve:/mattermost/bleve-indexes
healthcheck:
# The image ships no shell, curl or wget — exec-form mmctl over the local socket
# is the only probe that works (requires MM_SERVICESETTINGS_ENABLELOCALMODE above).
test: ["CMD", "/mattermost/bin/mmctl", "system", "status", "--local"]
interval: 5s
timeout: 10s
retries: 36
start_period: 30s
mm-postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: mmuser
POSTGRES_PASSWORD: mmpass
POSTGRES_DB: mattermost
volumes:
- mm-pg:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U mmuser"]
interval: 5s
timeout: 5s
retries: 12
volumes:
mm-data:
mm-logs:
mm-config:
mm-plugins:
mm-client-plugins:
mm-bleve:
mm-pg:
Want a guided install instead? caniselfhostit.com/slack has AI-agent prompts that assume a bare machine — that's their half of the stool, and it's good.
FULL TIMED LOG
# Timed setup log: Slack → Mattermost **Protocol:** v1 · **Verified by:** zernonia · **Date:** 2026-08-10 **Assistant:** claude-code · **Environment:** containerized runner, 2 vCPU class, Docker 29.3 / Compose v5.1 ## Timeline | Step | Time | |---|---| | Draft compose (mattermost + postgres, datasource string, site URL) | 15 min | | **Boot #1: server up and serving, but never reported healthy** (see What broke) | 15 min to diagnose | | Switch healthcheck to `mmctl system status --local`, re-up | 3 min | | Boot #2 to healthy + core workflow: create admin + team, post in a channel, second browser sees it live | 25 min | | Re-run from clean volumes | 7 min | | **Total: ~65 min** | | ## Measurements - 2 containers · Mattermost idle RAM ~450 MB + postgres ~40 MB — wants the full 2 GB box - Server boots and serves within ~60 s; plugin unpacking continues for a while after ## What broke 1. **The image ships no shell, curl or wget** — a `CMD-SHELL` healthcheck fails with "stat /bin/sh: no such file or directory" forever while the server is actually fine. Exec-form `mmctl system status --local` (with `MM_SERVICESETTINGS_ENABLELOCALMODE=true`) is the healthcheck that works. 2. **First admin is a race**: whoever completes the first-run screen owns the workspace. Plan the rollout; don't send the URL to the team before you've clicked through. ## Verdict-relevant notes - Channels, DMs, search, webhooks: solid. Mobile push routes through Mattermost's relay (or you run your own push proxy) — test it before you migrate anyone who matters. - The KINDA is arithmetic: per-seat pricing versus a flat server cost. At 1 seat you're losing money; at 10 seats you're keeping ~$1,000/yr for one weekend plus ops ownership.