Mattermost installation using Docker

Notice : despite the application quality, using it without licenses is barely viable. Why that, you ask? Because despite the two roles provided by the opensource (free) version – admin and regular user – none of those can prevent any user to update and even archive public channels. If you plan to grow a friends and family community, good luck preventing to put everything upside-down! For this reason, I highly recommend you to use Rocket.Chat instead, for which I will write a similar article.

This post will try to best describe the way to deploy a Mattermost app using Docker, PostgreSQL and Centos Stream 8. This documentation is meant to be really easy to understand and apply, only two containers are going to be deployed: DB and APP.

Network consideration

First, we are going to create a dedicated network to put our two containers, this way we are isolating the whole Mattermost architecture from the rest of the world. A more production-ready approach would require segregating the DB from the APP, and add a reverse proxy at the front.

# Create our mattermost dedicated network using Bridge mode
docker network create --driver bridge mattermost-net

# To see your networks
[supertanker@docker ~]$ docker network ls
 NETWORK ID     NAME                 DRIVER    SCOPE
 e2f6f37df707   bridge               bridge    local
 b1f6b243e90a   host                 host      local
 ddaac33f0860   network-mattermost   bridge    local
 2b0615c84b42   none                 null      local

PostgreSQL container

# Get the image from the repository
docker pull postgres
# Create a new volume on the host, in order to persist data.
docker volume create mattermost-vol-db
# Spin up the container, including the network and volume we have created above:
docker run --detach --restart unless-stopped -v mattermost-vol-db:/var/lib/postgresql/data --network mattermost-net --name mmt-db-01 -e POSTGRES_PASSWORD=y5g9Z24%SDcwi7u^2gcH*T%5aJz7Z postgres

–detach will put the container in the background while –restart unless-stopped will start the container at host startup or if it crashes.

Your container should be now up and running in the background, here some basic though useful commands:

# Check if your container is running
docker container ls

# Check if data were actually created (sudo is required):
sudo ls /var/lib/docker/volumes/mattermost-vol-db/_data/

# Check the allocated IP address:
docker network inspect mattermost-net

Now we need to connect to our container in order to create our mattermost database

# Connect to the container
docker exec -it mmt-db-01 bash

# Then to PostgreSQL
psql -U postgres

# According to Mattermost documentation, create the DB
CREATE DATABASE mattermost WITH ENCODING 'UTF8' LC_COLLATE='en_US.UTF-8' LC_CTYPE='en_US.UTF-8' TEMPLATE=template0;

# Create a DB user
CREATE USER mmuser WITH PASSWORD 'ApassWordWithoutspecialChars';

# Grant the user access to the Mattermost database
GRANT ALL PRIVILEGES ON DATABASE mattermost to mmuser;

# Exit
\q

# Quit the container using CTRL+P then CTRL+Q

Additionally but it should be mandatory when running in production, we need to think about backink up the database. To do so, the following command will create a full dump on the host temp directory

docker exec -t mmt-db-01  pg_dumpall -c -U postgres | gzip > /tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz

Up to you to use that command with a cron task or whatever suits you, in order to backup your Mattermost DB regularly.

Mattermost application container

Create a directory called mattermost, this folder will be use to create our custom image only.

Create a file called Dockerfile with the following content

FROM alpine:3.12
 # Some ENV variables
 ENV PATH="/mattermost/bin:${PATH}"
 ARG PUID=1000
 ARG PGID=1000
 ARG MM_PACKAGE="https://releases.mattermost.com/5.35.2/mattermost-5.35.2-linux-amd64.tar.gz?src=docker"
 # Install some needed packages
 RUN apk add --no-cache \
   ca-certificates \
   curl \
   libc6-compat \
   libffi-dev \
   linux-headers \
   mailcap \
   netcat-openbsd \
   xmlsec-dev \
   tzdata \
   wv \
   poppler-utils \
   tidyhtml \
   && rm -rf /tmp/*
 # Get Mattermost
 RUN mkdir -p /mattermost/data /mattermost/plugins /mattermost/client/plugins \
   && if [ ! -z "$MM_PACKAGE" ]; then curl $MM_PACKAGE | tar -xvz ; \
   else echo "please set the MM_PACKAGE" ; fi \
   && addgroup -g ${PGID} mattermost \
   && adduser -D -u ${PUID} -G mattermost -h /mattermost -D mattermost \
   && chown -R mattermost:mattermost /mattermost /mattermost/plugins /mattermost/client/plugins
 USER mattermost

 # Healthcheck to make sure container is ready
 HEALTHCHECK --interval=30s --timeout=10s \
   CMD curl -f http://localhost:8065/api/v4/system/ping || exit 1

 # Configure entrypoint and command
 COPY entrypoint.sh /
 ENTRYPOINT ["/entrypoint.sh"]
 WORKDIR /mattermost
 CMD ["mattermost"]
 EXPOSE 8065 8067 8074 8075

# Do not add Volumes, it was making the container unable to see changes on volumes files...

Replace the value ARG PUID= and ARG PGID= by the ID of the supertanker user, to get it, run the following command

id supertanker

Create a file called entrypoint.sh with the following content

#!/bin/sh
 if [ "${1:0:1}" = '-' ]; then
     set -- mattermost "$@"
 fi
 exec "$@"

Update its permissions

chmod 755 entrypoint.sh

Build the custom image

docker image build . --tag mmt-app

Eventually, create our container using our custom image

docker run --detach --restart unless-stopped -v mattermost-vol-app:/mattermost --network mattermost-net -p 8065:8065 -p 8067:8067 -p 8074:8074 -p 8075:8075 --name mmt-app-01 mmt-app

Our container is now running, however, as we didn’t set the PostgreSQL user, password and DB, you should see the following logs:

docker logs mmt-app-01
{"level":"error","ts":1623228282.1595657,"caller":"sqlstore/store.go:294","msg":"Failed to ping DB","error":"dial tcp 127.0.0.1:5432: connect: connection refused","retrying in seconds":10}

Stop the container

docker container stop mmt-app-01

Go to its volume (using a sudo enabled user)

cd /var/lib/docker/volumes/mattermost-vol-app/_data/config/

Edit the file called config.json and fix the following line according to your DB server

"DataSource": "postgres://mmuser:passwordWithouSpecialChars@mmt-db-01/mattermost?sslmode=disable\u0026connect_timeout=10"

Start the container

docker container start mmt-app-01

And eventually, enjoy the view: http://yourserverip:8065/

Leave a Reply