Mattermost Server Docker Installation Tutorial

Home Mattermost Server Docker Installation Tutorial


This tutorial covers how to setup mattermost, an open-source and free slack alternative with docker on a domain or subdomain with SSL. The deployment, which results from this tutorial is production ready.

Background: Why Mattermost?

DriveTrust started as a small team, back then slack has been a good solution. However, we grew and with 10 people we have reached our 10K message limit for slack quiet quick. Now paying 7,50€ / user / month seemed to expensive for a comparably simple chat application, so we started looking for better alternatives.

Mattermost Pros & Cons


1. free & self hosted.

2. A close to 1:1 clone of Slack, it has its own Android & iOS application

3. Has an export feauture from Slack, so the migration is quiet simple


1. Currently no guest user feature support

2. During migration private messages are not exported, as well we have not managed to export all the files


From DriveTrust’s side there have been a few requirements:

1. Integration with our existing applications on the server

2. Running on the subdomain

3. SSL

4. Running within docker

5. Being a capable production deployment



1. Docker & Docker Compose

2. DNS A record pointing to domain/subdomain. (In our case ) and server with a dedicated IP

3. jwilder nginx proxy and jwilder letsencrypt nginx proxy companion
Both are needed to reverse proxy the domain to a docker container which is located on a different port. Because we don’t want to have some URL like for production.
The second container automatically generates free SSL certificates for each subdomain you run with the nginx proxy.

0. Setup reverse proxy and SSL

This part refers to the above-mentioned containers. Once docker has installed the running of the containers is straight forward. This is straight from the official tutorial from Github
with one minor modification.

docker network create nginx-net

Before getting started with the servers and the reverse proxy we need to create a docker network to which will attach the nginx-proxy, the letsencrypt proxy ssl and the mattermost containers. Once the network is created we run the following two commands:

 docker run --detach \
    --name nginx-proxy \
    --publish 80:80 \
    --publish 443:443 \
    --net nginx-net \
    --volume /etc/nginx/certs \
    --volume /etc/nginx/vhost.d \
    --volume /usr/share/nginx/html \
    --volume /var/run/docker.sock:/tmp/docker.sock:ro \

 docker run --detach \
    --name nginx-proxy-letsencrypt \
    --volumes-from nginx-proxy \
    --net nginx-net \
    --volume /var/run/docker.sock:/var/run/docker.sock:ro \

Now you should have the reverse proxy setup!

Mattermost installation

The official mattermost tutorial deploys mattermost as a docker service. This has not been suitable for us since we were looking to integrate with our existing Nginx Proxy Server. That’s why took apart the docker-compose.yml and rebuild everything from scratch. In total we will have three different docker containers, one for database, one for the app and one for the web application.

Step 1: create the local volume directories where the data will be stored:

mkdir -pv /srv/mattermost/volumes/app/mattermost/{data,logs,config,plugins,client-plugins} <br>
chown -R 2000:2000 /srv/mattermost/

Step 2: get the official mattermost git repo:

git clone 
cd mattermost

Step 3: a )Build the database container.

cd db 
docker build -t mattermost_db 

That should build the database container.

b) Run the container

docker run --detach
 --name mattermost-docker_db_1 
 --restart unless-stopped
 --env POSTGRES_USER=mmuser
 --env POSTGRES_DB=mattermost
 --net nginx-net
 --volume /srv/mattermost/var/lib/postgresql/data:/var/lib/postgresql/data

Replace YOUR_DATABASE_PASSWORD with a proper database password. Please note that we add the container to nginx-net network to integrate with the reverse proxy.

Step 4: a) Build the mattermost app container

Here we need to add –build-arg edition=team to build the team edition of mattermost.

b) Run the container

docker run --detach
 --name mattermost-docker_app_1 
 --restart unless-stopped
 --env MM_USERNAME=mmuser
 --env MM_DBNAME=mattermost
 --net nginx-net
 --env DB_HOST=mattermost-docker_db_1
 --volume /srv/mattermost/app/config:/mattermost/config:rw
 --volume /srv/mattermost/app/data:/mattermost/data:rw
 --volume /srv/mattermost/app/logs:/mattermost/logs:rw 
 --volume /srv/mattermost/app/plugins:/mattermost/plugins:rw
 --volume /srv/mattermost/app/client-plugins:/mattermost/client/plugins:rw
 --volume /etc/localtime:/etc/localtime:ro

Replace YOUR_DATABASE_PASSWORD with the database password.
Note that the container has as well been added to the nginx-net network
Note that –-env DB_HOST actually requires an IP address of the database. However, since our database is as the app on the nginx-net network we can just pass the database container name (mattermost-docker_db_1) as host and docker does the domain name resolution automatically

Step 5: a) Build the web container

cd web 
docker build -t mattermost_web 

b) Run the container:

docker run --detach
 --name mattermost_web
 --restart always
 --env "" 
 --env "" 
 --env ""
 --env APP_HOST=mattermost-docker_app_1 
 --net nginx-net
 --expose 9097
 --volume /etc/nginx/certs/ 
 --volume /etc/localtime:/etc/localtime:ro 

Replace VIRTUAL_HOST, LETSENCRYPT_EMAIL, LETSENCRYPT_HOST with your domain. The APP_HOST is the containername of the mattermost app build in 4. It’s the same principle of DNS as with the mattermost database and mattermost app.

That’s it. Now you should be able to see the login screen on the domain of your choice!