Build Mattermost Professional
KINDAreplaces $10/mosaves $120/yrback to the verdict
Mattermost on a server you own, behind TLS with a real certificate, connected to an email provider that delivers, with a deliberate decision about mobile push, retention and moderation policies written down, backups of the database and the uploaded files together, and a restore you have performed.
Before step 1
Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.
- have readytypically 10 to 30 US dollars a month for a small team
Why Chat is latency sensitive in a way people notice, and an undersized server produces a sluggish client that everyone comments on.
Get it Check the project's current requirements for your team size, then provision accordingly.
Verify
The application starts and a client connects promptly - have readya few US dollars if deleted the same day
Why Restoring onto the machine that already has the files proves nothing, and the missing file storage is exactly what a database-only backup leaves out.
Get it The same provider, smallest suitable plan, destroyed after the drill.
Verify
You can SSH to it - have readyroughly 10 to 15 US dollars a year
Why Needed for the certificate, the site URL and the email sending records.
Get it Any registrar, then add the A record and the email verification records.
Verify
The hostname resolves and serves a valid certificate - API keyfree tiers cover a small team
Why Invitations and password resets both depend on delivery, and mail sent from the server directly will land in spam.
Get it Create an account, add the DNS records, take the credentials. Verification is the slow step.
Verify
An invitation arrives at three providers and is not in spam - decidevaries by arrangement; check current pricing rather than assuming
Why This is the constraint that surprises people after migration. Notification certificates belong to the published applications, so a self-hosted server cannot send to them directly.
Get it Check the project's current options for push, including any hosted proxy service and its cost, or the effort of building and distributing your own mobile applications. Decide before the team migrates.
Verify
A backgrounded mobile application receives a notification, or the limitation is documented and communicated - decidefree
Why Chat accumulates informal conversation quickly, and both what you keep and who decides what is acceptable are decisions with weight once a team relies on it.
Get it Write both before inviting anyone. One page each is enough.
Verify
Both are written and the settings match them
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- The application owns its schema. What you own is the operational state, and it is worth recording. - instance · version, host, database, file storage location and the deployment method - identity · how people sign in, and whether accounts are invite-only - push · which arrangement you chose for mobile notifications, and what it costs - retention · per channel kind, with the reason and the policy that requires it - backups · database and files, with the date of the last restore
Environment variables
These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.
| Variable | Needed | Example | Where the value comes from |
|---|---|---|---|
MM_SERVICESETTINGS_SITEURL | required | https://chat.example.com | Appears in every link and email. Correct before the first invitation. |
MM_SQLSETTINGS_DATASOURCEsecret | required | postgres://user:pass@db:5432/mattermost?sslmode=disable | Database connection. Half of what a restore needs. |
MM_FILESETTINGS_DIRECTORY | required | ./data/files | Uploaded files. The other half of a restore, and the half people forget. |
MM_EMAILSETTINGS_SMTPSERVER | required | smtp.provider.com | Transactional provider host. |
MM_EMAILSETTINGS_SMTPPASSWORDsecret | required | replace-with-provider-password | Provider credential, on the server only. |
PUSH_ARRANGEMENT | required | documented-in-docs-push | Which push arrangement you chose. Recorded here so it is not forgotten. |
BACKUP_DEST | required | s3://your-bucket/chat | Where both nightly artefacts go. |
The build, in order
Running behind a proxy that understands sockets
Chat works, and it keeps working when a conversation goes quiet for an hour.
Non-root user, key-only SSH, firewall allowing SSH and web ports only.
terminalufw allow OpenSSH && ufw allow 80,443/tcp && ufw enable
Following the project's own deployment guidance for the version you are using.
Files
docker-compose.ymlUpgrade headers and a generous idle timeout. Verify by leaving a client idle for an hour.
Files
Caddyfile
done when · tick each as it passeswatch out- A reverse proxy with a short idle timeout closes the WebSocket during a quiet period, and the client reconnects without saying anything, so messages appear late and nobody knows why. Set the timeout deliberately and verify by leaving a client idle rather than by reading the configuration.
Email that arrives
Invitations and resets reach inboxes, because everything else depends on them.
The DNS records your provider specifies. Propagation takes hours, so this is why it is early.
Three different ones, checking spam in each. One provider proves nothing.
Not just the invitation. It is the one people need when they cannot get in.
done when · tick each as it passeswatch out- Sending from the server directly rather than through a provider produces mail that lands in spam almost everywhere, and the symptom is people saying they never got the invitation. Use a provider, verify the domain, and check the spam folder at three providers rather than one.
The mobile push decision
Mobile notifications work, or the team knows in advance that they will not.
Check the current options and costs. Write down what you chose and why.
Files
docs/push.mdBackgrounded application, real message, real phone. This is the only test that counts.
Message previews appear on lock screens. Decide whether that is acceptable for your team.
done when · tick each as it passeswatch out- Migrating a team and then discovering that mobile notifications do not arrive is how a self-hosted chat deployment gets abandoned in week two. Notification certificates belong to the published mobile applications, so a self-hosted server cannot send directly to them; resolve this before anyone depends on it.
Access, retention and moderation
The right people are in, old messages do not accumulate forever, and someone is responsible.
Invitation only or a verified domain. Test with an outside address.
Per channel kind with the reason. Chat accumulates and much of it should not be kept forever.
Files
docs/retention.mdWhat is not allowed, who decides, how to appeal. Before the first incident rather than during it.
Files
docs/moderation.md
done when · tick each as it passeswatch out- Open signup on a publicly reachable chat server is discovered by scanners and produces accounts you did not invite, sometimes within days. Restrict signup before the server is reachable rather than after the first unexpected member appears.
Backups of both halves
The database and the uploaded files are both backed up, off the machine.
Dated, compressed, off the machine.
Files
scripts/backup.shterminalpg_dump "$DATABASE_URL" | gzip > chat-$(date +%F).sql.gz
Same schedule, same destination. Uploads are half the content people care about.
Files
scripts/backup.shSilence is not evidence a backup ran.
Files
scripts/check_backup.sh
done when · tick each as it passeswatch out- A database dump without the file storage produces a restore where every conversation is intact and every shared file is a broken link, which is exactly the material people needed. Back up both on the same schedule and restore both together.
The restore drill and upgradesproduct builder
You have rebuilt it on a clean server, and an upgrade is planned rather than hopeful.
Database, files and configuration. Then sign in as an existing user.
From a channel that predates the backup. This is the check that catches a database-only restore.
Files
README.mdBack up, read breaking changes, upgrade the second server, verify, then the live one.
Files
docs/upgrade.md
done when · tick each as it passeswatch out- A restore that produces a working login and broken attachments looks successful until someone opens an old file. Verify by downloading an attachment from a restored channel rather than by checking that the application starts.
That is the whole plan for Mattermost Professional. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- Managed operations, patching and upgrades.
- Mobile push without a deliberate arrangement.
- Enterprise security, governance and compliance exports.
- The network effects of a platform people are already on.
- managed operations, mobile push, enterprise security, support, and governance
- network effects
- native mobile apps
- video and voice infrastructure
- enterprise moderation and discovery
- Single sign-on against an identity provider you already run
- A staging instance restored from last night's backup, which exercises the restore weekly
- Automated attachment retention, since files rather than messages are what fills the disk
Need the files? The project pack on the verdict page hands your agent the whole brief · more community.