English
Get started

← All templates · Social and community

Deploy Mattermost in one click

Open-source team chat with channels, threads, file sharing and integrations

A self-hosted alternative to Slack and Microsoft Teams.

What is Mattermost?

Mattermost is an open-source collaboration platform for team chat: public and private channels, direct and group messages, threads, file sharing, search, Markdown and custom emoji, in more than 20 languages. Webhooks, slash commands, bots, plugins and an API connect it to other tools, with integrations for Jira, GitHub and GitLab. Apps for Windows, macOS, Linux, iOS and Android connect to its address.

This template runs Mattermost Team Edition, the free build under the MIT license, with PostgreSQL, and makes the System Admin from the fields before the page answers anyone. Team Edition is meant for small teams: it takes up to 250 active users and has no single sign-on, guest accounts or group calls, which are in the paid plans. The catch: push notifications to the phone apps go through Mattermost’s free Test Push Notification Service, which it does not recommend for production.

Hosting Mattermost on Pethost

  1. You sign in to Pethost with a passkey, GitHub or Google. No machine yet? You pick a plan, and the link waits until it is ready.
  2. New project opens at Mattermost. You fill in what it asks for and click Create project: Email, Username, Admin password.
  3. In a minute or two Mattermost is live at its own address with HTTPS. Its secrets are made at random, and its data is in the nightly backup.
  4. It is a project like any other: you or your agent can change it, roll it back or restore it.

Questions about Mattermost

Is Mattermost free?

Yes. Mattermost Team Edition is free, compiled under the MIT license from open source code, and keeps the whole message history. It is meant for teams under 250 active users; the paid plans add SSO, guest accounts, group calls and compliance features.

Mattermost or Slack?

Both have channels, threads, direct messages and integrations. Slack runs only on Slack’s servers, while Mattermost runs where you deploy it, and its incoming webhooks accept Slack’s format, so many Slack integrations work unchanged.

Can I move from Slack to Mattermost?

Yes. Mattermost’s migration tools, mmetl and mmctl import, bring users, channels, message history, direct messages, threads and files over from a Slack export. Slash commands do not come over.

Does Mattermost have mobile apps?

Yes, for iOS and Android, and desktop apps for Windows, macOS and Linux. With Team Edition, push notifications go through Mattermost’s Test Push Notification Service, which is free but comes with no guarantees.

How many users can Mattermost Team Edition have?

Up to 250 active users: it warns at 200, and at 250 it refuses to create or activate more. A team that outgrows it moves to a paid plan.

Do Mattermost calls work with this template?

Not as it is. Calls send their audio and video over port 8443, which this template does not publish; text chat, files and integrations work in full.

How much memory and disk does Mattermost need?

Mattermost takes about 300 MB of memory with Postgres for a small team, and its database and files grow with the messages and uploads. On Pethost the Starter plan is enough for it, with room for other apps beside it.

Mattermost Docker Compose file

The template is this compose.yaml and the variables written into the project’s .env as it is created. Pethost runs the file as it is written.

Containers: proxy (caddy:2.11-alpine), mattermost (mattermost/mattermost-team-edition:12.0), postgres (postgres:17-alpine).

Volumes, in the nightly backup: config, data, logs, plugins, client-plugins, db.

services:
  # A new Mattermost makes whoever signs up first its System Admin. So the page is served through
  # this small Caddy, which answers only once the administrator exists: at its start it waits for
  # Mattermost, and while Mattermost says it has no accounts, it signs the administrator up with
  # the email, username and password given, as that first account. A refusal stops it, says so in
  # its log, and is tried again at its next start.
  proxy:
    image: caddy:2.11-alpine
    restart: unless-stopped
    environment:
      ADMIN_EMAIL: ${ADMIN_EMAIL}
      ADMIN_USERNAME: ${ADMIN_USERNAME}
      ADMIN_PASSWORD: ${ADMIN_PASSWORD}
    command:
      - sh
      - -c
      - |
        set -e
        mattermost=http://mattermost:8065
        echo "waiting for Mattermost"
        until client=$$(wget -qO- "$$mattermost/api/v4/config/client?format=old" 2>/dev/null); do sleep 2; done
        case "$$client" in
          *'"NoAccounts":"true"'*)
            json() { printf '%s' "$$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }
            body=$$(printf '{"email":"%s","username":"%s","password":"%s"}' \
              "$$(json "$$ADMIN_EMAIL")" "$$(json "$$ADMIN_USERNAME")" "$$(json "$$ADMIN_PASSWORD")")
            if ! wget -qO /dev/null --header 'Content-Type: application/json' --post-data "$$body" "$$mattermost/api/v4/users"; then
              echo "Mattermost refused the administrator: an email address, a username of letters, digits, dots, dashes and underscores, and a password of 8 characters at least are what it takes" >&2
              exit 1
            fi
            echo "the administrator $$ADMIN_USERNAME is made"
            ;;
        esac
        exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
    configs:
      - source: caddy
        target: /etc/caddy/Caddyfile
    # The image's own directories, which a proxy without certificates does not use.
    tmpfs:
      - /config
      - /data
    depends_on:
      - mattermost

  mattermost:
    image: mattermost/mattermost-team-edition:12.0
    restart: unless-stopped
    environment:
      MM_SQLSETTINGS_DRIVERNAME: postgres
      MM_SQLSETTINGS_DATASOURCE: postgres://mattermost:${POSTGRES_PASSWORD}@postgres:5432/mattermost?sslmode=disable&connect_timeout=10
      MM_SERVICESETTINGS_SITEURL: ${URL}
      # Only the proxy reaches Mattermost, and it says who the client is.
      MM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER: X-Forwarded-For
    volumes:
      - config:/mattermost/config
      - data:/mattermost/data
      - logs:/mattermost/logs
      - plugins:/mattermost/plugins
      - client-plugins:/mattermost/client/plugins
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: mattermost
      POSTGRES_USER: mattermost
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mattermost -d mattermost"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 30s

configs:
  caddy:
    content: |
      {
        admin off
        auto_https off
      }

      :8065 {
        reverse_proxy mattermost:8065
      }

volumes:
  config:
  data:
  logs:
  plugins:
  client-plugins:
  db:

More in Social and community