A simple Mattermost Docker installation

I was trying to setup a full instance of Mattermost recently and decided to use an existing Docker host so that I can test it out and easily rebuild / tinker with it.

The official documentation states that there is a community-driven repository that offers just that, Mattermost on Docker:

mattermost/mattermost-docker
Dockerfile for mattermost in production. Contribute to mattermost/mattermost-docker development by creating an account on GitHub.

... but the README greats us with a warning message:

The current state of this repository doesn't work out-of-the box since Mattermost server v5.31+ requires PostgreSQL versions of 10 or higher.

Mattermost being a Go application backed by a PostgreSQL server, I figured that this should not be overly difficult to achieve on its own, so I opened up a terminal and created a simple compose file to deploy it easily.

Structure

  • We need a Dockerfile to build the actual server container
  • We need to create a config.json file
  • And a docker-compose.yml file to setup the database along the server, and bind them together

The Dockerfile is pretty straightforward. We start for a relatively stable debian Buster:

FROM debian:buster

ENV version=5.34.2

# Install the PHP extensions we need
RUN set -eux; \
	apt-get update; \
	apt-get install -y --no-install-recommends \
	ca-certificates \
	openssl \
	curl \
	gnupg

RUN apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
	rm -rf /var/lib/apt/lists/*

# Get release
ADD https://releases.mattermost.com/${version}/mattermost-${version}-linux-amd64.tar.gz /

RUN tar -xzf /mattermost-${version}-linux-amd64.tar.gz
RUN mv /mattermost /opt/.

RUN rm -rf /mattermost-${version}-linux-amd64.tar.gz

# Add correct configuration
COPY config.json /opt/mattermost/config/config.json

# Set up a system user and group called mattermost that will run this service, and set the ownership and permissions.
RUN useradd --system --user-group mattermost
RUN chown -R mattermost:mattermost /opt/mattermost
RUN chmod -R g+w /opt/mattermost

USER mattermost:mattermost

VOLUME /opt/mattermost/data

CMD ["/opt/mattermost/bin/mattermost"]

Key points here are:

  • We need ca-certificates and openssl so that we can access https resources and APIs
  • We want the container to run with a non-root account (hence the mattermost user)
  • We want to expose the Mattermost data in a volume

You need a .env file to hold the env vars for the PostgreSQL database

POSTGRES_USER=mmuser
POSTGRES_PASSWORD=a_strong_password
POSTGRES_DB=mattermost

And a docker-compose.yml file to hold all this together:

version: '3.7'

services:
  mattermost-postgres:
    container_name: mattermost-postgres
    image: postgres:13.2-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
      PGDATA: /mattermost/postgres
    volumes:
       - postgres:/mattermost/postgres
    networks:
      - mattermost
    restart: unless-stopped

  mattermost-server:
    container_name: mattermost-server
    build:
      context: ./
    image: mattermost-server:latest
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - data:/opt/mattermost/data
    networks:
      - mattermost
    ports:
      - "127.0.0.1:8066:8065"
    restart: unless-stopped
    depends_on:
      - mattermost-postgres
    ulimits:
      nofile: 49152

networks:
  mattermost:

volumes:
  postgres:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: /mattermost/postgres
  data:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: /mattermost/data

On the host, you need to have the /mattermost/data and /mattermost/postgres directories available.

The config.json file that is referenced in the Dockerfile is a copy/paste of the standard Mattermost configuration that you can find here:

https://github.com/mattermost/mattermost-docker/blob/master/contrib/aws/app/mattermost/config/config.json

The main keys to update are:

  • ServiceSettings > SiteURL: You want to put your domain name here, with the https:// part, ex: https://mattermost.my_domain.com
  • SqlSettings > DriverName and DataSource: DriverName should be postgres and DataSource is your full connection string which should be along those lines: postgres://mmuser:[password]@[postgres_container]:5432/mattermost?sslmode=disable&connect_timeout=10
    Don't forget to change your password for the one that you setup in your .env file, and the postgres_container for the name that you gave to your container in the docker-compose.yml file (mattermost-postgres in my example)
  • EmailSettings: If you want to have notifications, you need to put a working SMTP configuration here (in EnableSMTPAuth, SMTPUsername, SMTPPassword, SMTPServer and SMTPPort, and also set SendEmailNotifications to true, and fill in FeedbackName, FeedbackEmail and ReplyToAddress)

Protip for these keys:

  • FileSettings > Directory
  • PluginSettings > Directory and ClientDirectory

You want to put absolute directories in here, instead of relative ones, it should work better (ex /opt/mattermost/plugins instead of ./plugins)

Start up

Now that you're all set, you can:

Build the server container

With docker compose build mattermost-server

Start the app

With docker compose up -d

You should be able to visit 127.0.0.1:8066 on your Docker host to assess that everything runs fine.

Reverse proxy

So far, the Mattermost instance is only available locally on your Docker host (we specifically requested it to with "127.0.0.1:8066:8065" in the ports section of the docker-compose.yml). But we have mattermost.my_domain.com waiting for us, so let's reverse proxy it !

On the host

If you already have a web server on the host that serves some other containers to the public web, it's easy to use it to reverse proxy the Mattermost app.

I'm mainly using Caddy nowadays, and it's as easy as using this configuration:

mattermost.my_domain.com {
    reverse_proxy 127.0.0.1:8066
}

Via another container

We could also use Traefik (See the docker images here) to reverse-proxy the 8065 port of the mattermost-server container to the world.

This is quite easy to do and I'll leave that as an exercise for the reader.


Once you have the server and the proxy up and running, you should be able to access the instance, create the system account if not done before, and start using Mattermost:


🎉