DEV Community

Cover image for Deploy mattermost to a docker swarm with secrets
Lakshman Anumolu
Lakshman Anumolu

Posted on

Deploy mattermost to a docker swarm with secrets

I deployed mattermost to a docker swarm using docker secrets, while the process was smooth, I had to make some modifications to original mattermost-docker source to achieve desired goal. This article describes the following:

  • Deploy mattermost on a single node swarm (e.g. on digitalocean) and publish under a subdomain.
  • Pass secrets to the stack.
  • Enable plugins upload.
  • Configure mattermost for email notifications using gmail's smtp server.

Before presenting details, here are the final products:

username: test
password: test1234
  • Docker images:

 * https://hub.docker.com/repository/docker/acrlakshman/mattermost-team
 * https://hub.docker.com/repository/docker/acrlakshman/mattermost-prod-db

Deploy mattermost onto a single node swarm

I found few articles that describe deploying mattermost in kubernetes, single click app on digitalocean. While there are other ways to install, I wanted to deploy it myself on my digitalocean server space, which helps me learn few things along the way and may be contribute to the project. Here are the steps:

# ssh to server
ssh <user>@<public ip>
# Prepare swarm
docker swarm init --advertise-addr <public-ip>
# Clone the repository to your desired location
git clone https://github.com/acrlakshman/mattermost-docker
# Prepare volumes
cd mattermost-docker
mkdir -p volumes/app/mattermost/logs
mkdir -p volumes/app/mattermost/data
mkdir -p volumes/app/mattermost/config
mkdir -p volumes/app/mattermost/plugins
mkdir -p volumes/app/mattermost/client_plugins
sudo chown -R 2000:2000 ./volumes/app/mattermost
# create secrets to store database (postgresql) details
echo "database_user" | docker secret create mm_db_user -                       echo "database_password" | docker secret create mm_db_password -                       echo "database_name" | docker secret create mm_db_name -
# deploy stack
docker stack deploy -c docker-stack.yml mm

We now have a stack mm created that manages three services, mm_app, mm_db, mm_visualizer.

watch docker service ls

Alt Text

While I have not presented the technical details above, some modifications are made to original mattermost-docker in order to use credentials via docker secrets. entrypoint.sh scripts for both mattermost-docker/app/ and mattermost-docker/db/ are changed and are custom built to use in this stack. A slightly modified version of Basilio Vera's script is used in this work which helped in expanding secrets and assign them to environment variables.

Point subdomain to mattermost instance

Webserver: nginx
CDN: cloudflare
OS: Debian

Mattermost app now runs in docker and listens to host port at 7070. I have used nginx as a proxy webserver on Debian. Here are the details:

cd /etc/nginx/sites-available

# Create a file with <sub.domain.com>
# In my case this is mattermost.lakshmananumolu.com
sudo vim <sub.domain.com>

# My <sub.domain.com> has the following
server {
  listen 80;
  listen [::]:80;
  server_name <sub.domain.com> www.<sub.domain.com>;
  return 301 https://<sub.domain.com>$request_uri;
}

map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}

server {
  # SSL configuration
  listen 443;
  listen [::]:443;

  ssl     on;
  ssl_certificate <path-to>/<domain.com>.pem;
  ssl_certificate_key <path-to>/<domain.com>.key;
  ssl_session_timeout 5m;
  ssl_prefer_server_ciphers on;

  server_name <sub.domain.com> www.<sub.domain.com>;
  include hhvm.conf;

  location ~ /api/v[0-9]+/(users/)?websocket$ {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_set_header Connection "upgrade";

    client_max_body_size 50M;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
    proxy_set_header X-Frame-Options SAMEORIGIN;
    proxy_buffers 256 16k;
    proxy_buffer_size 16k;
    proxy_read_timeout 600s;
    proxy_pass http://127.0.0.1:7070;
  }

  location / {
    # First attempt to serve request as file, then
    # as directory, then fall back to displaying a 404.
    gzip on;
    proxy_set_header X-Forwarded-Ssl on;

    client_max_body_size 50M;
    proxy_set_header Connection "";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Frame-Options SAMEORIGIN;
    proxy_buffers 256 16k;
    proxy_buffer_size 16k;
    proxy_read_timeout 600s;
    proxy_pass http://127.0.0.1:7070;
  }
}

# enable this site.
sudo ln -s /etc/nginx/sites-available/<sub.domain.com> /etc/nginx/sites-enabled/<sub.domain.com>

# restart nginx.
sudo service nginx restart

I used cloudflare as CDN, from where I obtained ssl certificate and key, that are used in nginx configuration above.

Mattermost initial configuration and enable plugins upload

Subdomain now points to mattermost instance. At this point we can create a new account and remember the credentials. Role of this user is System Admin.

At this point we can change mattermost config file to enable uploads for plugin. Edit volumes/app/mattermost/config/config.json to

sudo vim <mattermost-repo-clone>/volumes/app/mattermost/config/config.json

# Search and set `EnableUploads` to true.
PluginSettings {
  ...
  "EnableUploads": true,
  ...
}

Execute docker stack deploy… that will restart mattermost app.

docker stack deploy -c docker-stack.yml mm

Plugins can now be uploaded to mattermost instance.

System Console -> Plugin Management

Alt Text

SMTP Email setup

Mattermost has excellent documentation for this settings, I used that webpage to configure SMTP. Minor detail that I followed to get it to work with gmail is included here.

System Console -> Environment -> SMTP

SMTP Server: smtp.gmail.com
SMTP Server Port: 587
Enable SMTP Authentication: true
SMTP Server Username: <gmail address>
SMTP Server Password: <Generated app password with 2-factor authentication ON>
Connection Security: STARTTLS

For SMTP Server Password, I did the following

  • I have 2-factor authentication enabled for my gmail account.
  • Visit Google account settings -> Security -> App passwords
    • Generate an app password and use that for SMTP Server Password in mattermost.

Visualizer

Above docker deployment comes with visualizer, which can be viewed on port 7071. For my mattermost installation here is the visualizer.

Extras

For extra installations such as pgadmin4 alongside above services, please refer to team-extras branch (https://github.com/acrlakshman/mattermost-docker/tree/team-extras).

Some plugins

References

Top comments (0)