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:
... 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 
Dockerfileto build the actual server container - We need to create a 
config.jsonfile - And a 
docker-compose.ymlfile 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-certificatesandopensslso that we can access https resources and APIs - We want the container to run with a non-root account (hence the 
mattermostuser) - 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/dataand/mattermost/postgresdirectories 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:
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: 
DriverNameshould bepostgresandDataSourceis 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.envfile, and thepostgres_containerfor the name that you gave to your container in thedocker-compose.ymlfile (mattermost-postgresin my example) - EmailSettings: If you want to have notifications, you need to put a working SMTP configuration here (in 
EnableSMTPAuth,SMTPUsername,SMTPPassword,SMTPServerandSMTPPort, and also setSendEmailNotificationstotrue, and fill inFeedbackName,FeedbackEmailandReplyToAddress) 
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:
🎉