Deploy Mattermost on Dokku
Mattermost started as an open-source Slack alternative, like Gitlab for GitHub, and as such has been adopted by a lot of organizations because you can self-host it for free (although you have to pay for your own servers and you’re responsible for the maintainance and updates).
Dokku is a single-server self-hosted PaaS. Think of Heroku, but open-source and on your own server. It’s very useful because it deals with all the intricacies of building and serving multiple Web apps on the same server to let you focus on what matters: the development of the app itself. You just describe how to build the app (or Dokku detects it) and git push
it and Dokku deploys it for you. Apps are deployed as Docker containers behind an nginx server that does the routing. Dokku has tons of plugins to link the apps to various databases (Postgres, ElasticSearch, etc) and customize the front-end routing to add Let’s Encrypt certicates, HTTP Auth, etc.
At Bixoto, we use Mattermost for our internal chat, and Dokku to deploy most of our websites. Our own Mattermost is deployed on its own server for historical reasons: we started using Mattermost before Dokku. Recently, we had to deploy a new Mattermost instance for an project we have with another company. Now that we use Dokku for virtually every project and have some experience with it, we decided to deploy Mattermost on it.
This is made easier by the fact that Mattermost already supports a Docker-based deployment.
Initial git repository
First, create a new git repository:
git init mattermost && cd mattermost
Create a Dockerfile
with the Mattermost version you want to deploy:
FROM mattermost/mattermost-team-edition:7.8.2
Here, we use Mattermost 7.8.2, which is the latest LTS release at the time of this writing. The Dockerfile
doesn’t contain anything because everything is already described in Mattermost’s Docker image.
Note: having a repo associated with an app gives a place to store the documentation for that app. You can also avoid altogether creating such repo by running dokku git:from-image $APP_NAME mattermost/mattermost-team-edition:7.8.2
directly on the server.
Dokku app
Note: in this post we assume you already installed Dokku on your server. If it’s your first time with it, follow the official documentation to install it. Be aware that Dokku uses nginx and configures it all by itself; as such it doesn’t support other non-Dokku websites served from that same server. If you already have some website on your server, avoid installing Dokku on it because it will break.
To make the commands in this tutorial easier to copy/paste, we’ll set two variables in the shell. SSH onto the server you installed Dokku on, and set these variables:
APP_NAME=my-mattermost DOMAIN=chat.example.com
These are example values; change them to what you want. The APP_NAME
is used to name the app in Dokku. Don’t use spaces or any character that could be interpreted by the shell. The DOMAIN
is the domain from which the app will be served. Edit your DNS zone to point it to your Dokku server.
Then, create the app:
dokku apps:create $APP_NAME
And configure its domain:
dokku domains:add $APP_NAME $DOMAIN dokku config:set --no-restart $APP_NAME DOMAIN=$DOMAIN
The second command is needed because Mattermost needs a DOMAIN
environment variable to know which domain it’s served under.
Persistent storage
We need to have persistent storage so the data is kept between app deployments. You wouldn’t want to lose all the messages every time you update Mattermost!
Create Mattermost’s persistent storage directories and mount them on the app:
for d in config data logs plugins client/plugins bleve-indexes; do volume="/var/lib/dokku/data/storage/$APP_NAME/$d" sudo mkdir -p "$volume" sudo chown -R 2000:2000 "$volume" dokku storage:mount $APP_NAME "$volume:/mattermost/$d" done
This uses Dokku’s standard location for persistent storage directories. It sets the ownership to 2000:2000
because that’s what Mattermost requires.
Database
Create the Postgres database and link it:
dokku postgres:create $APP_NAME-db dokku postgres:link $APP_NAME $APP_NAME-db
By default Dokku exports the connection string as the environment variable DATABASE_URL
, but Mattermost doesn’t read it, so we need to tweak the config so it knows how to connect to the database:
# Get the Postgres URL PG_URL="$(dokku config:get $APP_NAME DATABASE_URL)" # Configure the app database config dokku config:set --no-restart $APP_NAME MM_SQLSETTINGS_DRIVERNAME=postgres MM_SQLSETTINGS_DATASOURCE="$PG_URL?sslmode=disable&connect_timeout=10"
Last configuration
At this point, we can also configure the timezone Mattermost should use:
# Change "Europe/Paris" to whichever timezone you want dokku config:set --no-restart $APP_NAME TZ=Europe/Paris
Mattermost supports a lot more configuration variables. Check their documentation for more info.
Deployment
It’s now time to make the first deployment of our app! In your local git repository, commit your files (there should be the Dockerfile
we created earlier and maybe a README.md
for your own documentation):
git commit -m "initial commit"
Now, push it to your Dokku server. If you haven’t done it already, configure Dokku to allow SSH access. Then, in your ~/.ssh/config
file (create it if it doesn’t exist), add an entry for Dokku:
Host dokku-deploy User dokku Hostname <the IP of your server>
This adds an alias called dokku-deploy
for dokku<the IP of your server>
. Now, use this alias to add your server as a remote for your app:
git remote add dokku dokku-deploy:$APP_NAME
$APP_NAME
is the name of the app you created earlier.
Now that you’re all set, push:
git push dokku main
You should see the output of the build and your Mattermost instance should now be deployed! It’s not yet usable, so check the next step to fix the last things.
Post-Deployment
SSL certificate
Let’s add a SSL certificate for our app:
dokku letsencrypt:enable $APP_NAME dokku letsencrypt:cron-job --add $APP_NAME dokku config:set $APP_NAME MM_SERVICESETTINGS_SITEURL=https://$DOMAIN
Fix the ports mapping
If the app is not accessible yet, it’s very likely because Dokku didn’t correctly detect the ports exposed by the app. Let’s fix that:
dokku proxy:ports-clear $APP_NAME dokku proxy:set $APP_NAME http:80:8065 https:443:8065
You should now be able to access your Mattermost instance at https://<your domain>
!
Local access
Mattermost has a mmctl
tool that you can use to run admin commands on the instance, such as creating users and resetting passwords. By default, it requires an authentication, but you can enable a “local” mode that gives you unauthenticated access through a UNIX socket that only users with direct access to the server can use.
- Edit
/var/lib/dokku/data/storage/$APP_NAME/config/config.json
to set"EnableLocalMode"
totrue
- Restart the app:
dokku ps:restart $APP_NAME
Then use dokku enter $APP_NAME
to enter in the running container, and use mmtl --local <command>
. See the official docs for more info.