Mattermost
Mattermost Team Edition: self-hosted team chat
Mattermost on Cubeship
Mattermost is an open-source team chat: channels, direct messages, threads, file sharing and integrations, with desktop and mobile apps, running on your own server.
This template installs Mattermost Team Edition on a Cubeship instance, with the managed Postgres it keeps messages and its configuration in, and a volume for uploaded files.
What it creates
- mattermost — Mattermost Team Edition, from
mattermost/mattermost-team-edition:11.7.10, answering on the domain you choose, with a volume at/mattermost/data: every uploaded file and image, and the bundles of the plugins you install. - mattermost-db — a managed Postgres 18 database holding users, teams, channels, messages and the server's configuration.
It needs Cubeship 0.7.0 or newer.
11.7 is Mattermost's Extended Support Release, supported until May 2027, and the version upstream's own Docker setup ships. Feature releases come monthly and are supported for three months each; an ESR is supported for a year, and upgrading from one ESR to the next is what upstream tests.
What you are asked
| Input | What to give |
|---|---|
| Where Mattermost answers | A domain you control, pointed at your instance. It also becomes the Site URL. |
After installing
- Open the domain straight away. Mattermost has no default account: the first person to sign up becomes the system admin. Until you do, that is anyone who finds the domain.
- Create your team, then invite people from its menu. After the first account, nobody can sign up without an invite link unless you open the server under System Console → Authentication → Signup.
- In the desktop and mobile apps, give
https://<your domain>as the server URL.
The Site URL and the database connection are set by the app's variables,
so they are greyed out in the System Console. To move to another domain,
change MM_SERVICESETTINGS_SITEURL on the mattermost app and redeploy.
Configuration
Everything else changed in the System Console is kept in the database, not in
config.json: MM_CONFIG points Mattermost at Postgres for its configuration,
so it survives deploys without a volume of its own.
No mail is set up, and Mattermost runs without it — but then nobody can reset a forgotten password, verify an address or get email notifications. Set it under System Console → Environment → SMTP, and turn on Site Configuration → Notifications → Enable Email Notifications.
Calls
Voice and video calls will not work. The Calls plugin ships with
Mattermost, but it carries media on port 8443, UDP or TCP, straight to the
server — not through the domain — and Cubeship cannot expose a port other than
a domain's HTTP. Making it work needs the
media service reachable some other way: Mattermost's standalone rtcd on a
machine with port 8443 open, or a TURN server such as coturn that clients
can reach — see upstream's
Calls deployment guide.
Team Edition's calls are limited to one-to-one and 40 minutes even then.
Mobile push notifications
A new server sends mobile push notifications through Mattermost's free Test
Push Notification Service, https://push-test.mattermost.com. It works out
of the box but comes with no uptime guarantee, and upstream does not recommend
it for production. The production Hosted Push Notification Service needs a
paid license; the alternative is to run your own push proxy with your own
builds of the mobile apps. Either is set under
System Console → Environment → Push Notification Server.
Diagnostics
Mattermost sends usage statistics and error reports to Mattermost, Inc. by
default. Turn it off under
System Console → Environment → Logging → Enable Diagnostics and Error Reporting,
or set MM_LOGSETTINGS_ENABLEDIAGNOSTICS to false on the app and redeploy.
Resetting a password
A forgotten password is reset over SSH on the machine the app runs on, since
Cubeship has no console into an app. The image has no shell, but it carries
Mattermost's mmctl, which talks to the running server directly:
docker exec -it $(docker ps -qf name=cubeship-mattermost-production-mattermost) \
mmctl --local user change-password <username> --password '<new password>'
The same mmctl --local makes a user a system admin
(user create … --system-admin), lists users, and more.
The volume
The app runs as one copy on the machine its volume is on, and a deploy stops it for a few seconds, during which nobody can connect. Back up the volume and the database together: messages are in one and the files they link to are in the other.
Server logs go to the app's log output. The copies Mattermost also writes under
/mattermost/logs are not kept across deploys, and neither is a Bleve search
index, which is off by default.
Resources
The app is limited to 1 CPU and 2 GiB of memory, what Mattermost recommends for
up to 1,000 users. Raise limits in template.yaml if you need more.
What this creates
mattermost
mattermost/mattermost-team-edition:11.7.10
mattermost-db
Postgres 18
/mattermost/data
Volume of mattermost
# yaml-language-server: $schema=https://cubeship.dev/schema/template/v1.json
version: 1
# The first release that keeps a volume's data across deploys.
minCubeship: "0.7.0"
project: mattermost
inputs:
- key: domain
type: domain
label: Where Mattermost answers
databases:
- key: db
name: mattermost-db
engine: postgres
version: "18"
database: mattermost
apps:
- key: web
name: mattermost
image: mattermost/mattermost-team-edition
# 11.7 is the Extended Support Release, supported until May 2027.
tag: "11.7.10"
port: 8065
health: /api/v4/system/ping
domains:
- host: ${input.domain}
# Uploaded files, and the bundles of installed plugins, which Mattermost
# unpacks again from here every time it starts.
volumes:
- path: /mattermost/data
limits: { cpu: 1, memory: 2Gi }
env:
MM_SQLSETTINGS_DRIVERNAME: postgres
MM_SQLSETTINGS_DATASOURCE: postgres://${db.db.user}:${db.db.password}@${db.db.host}:${db.db.port}/${db.db.name}?sslmode=disable&connect_timeout=10
# Keeps the configuration in the database instead of config.json, so
# System Console changes survive a deploy without a volume for them.
MM_CONFIG: postgres://${db.db.user}:${db.db.password}@${db.db.host}:${db.db.port}/${db.db.name}?sslmode=disable&connect_timeout=10
MM_SERVICESETTINGS_SITEURL: https://${input.domain}