Introduction
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
Pros:
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
Cons:
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
Requirements
From DriveTrust’s side there have been a few requirements:
1. Integration with our existing applications on the server
2. Running on the subdomain chat.drivetrust.eu
3. SSL
4. Running within docker
5. Being a capable production deployment
Implementation
Prerequisites
1. Docker & Docker Compose
2. DNS A record pointing to domain/subdomain. (In our case chat.drivetrust.eu ) and server with a dedicated IP
3. jwilder nginx proxy and jwilder letsencrypt nginx proxy companion
Both are needed to reverse proxy the domain https://chat.drivetrust.eu to a docker container which is located on a different port. Because we don’t want to have some URL like chat.drivetrust.eu:9097 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 \ jwilder/nginx-proxy docker run --detach \ --name nginx-proxy-letsencrypt \ --volumes-from nginx-proxy \ --net nginx-net \ --volume /var/run/docker.sock:/var/run/docker.sock:ro \ --env "DEFAULT_EMAIL=YOUR_EMAIL_ADDRESS" \ jrcs/letsencrypt-nginx-proxy-companion
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 https://github.com/mattermost/mattermost-docker.git 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_PASSWORD=YOUR_DATABASE_PASSWORD --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_PASSWORD=YOUR_DATABASE_PASSWORD --env MM_DBNAME=mattermost --env MM_SERVICESETTINGS_SITEURL="https://chat.drivetrust.eu" --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 mattermost_app:latest
Replace YOUR_DATABASE_PASSWORD with the database password.
Replace MM_SERVICESETTINGS_SITEURL with your URL
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 "VIRTUAL_HOST=chat.drivetrust.eu" --env "LETSENCRYPT_HOST=chat.drivetrust.eu" --env "LETSENCRYPT_EMAIL=roman.prytkov@drivetrust.eu" --env APP_HOST=mattermost-docker_app_1 --env MATTERMOST_ENABLE_SSL=true --net nginx-net --expose 9097 --volume /etc/nginx/certs/chat.drivetrust.eu:/cert:ro --volume /etc/localtime:/etc/localtime:ro mattermost_web:latest
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!