Contents

[BgLUG] slack to rocket.chat migration

Intro

I’m part of the local LUG (Linux Users Group) and despite our association is not exactly a startup (founded in 2001 if I remember well) we’re not organized like we would want to be. Bu we’re trying!

In fact, among other things, we move away from “closed source” services like slack (a very powerful chat service, with tons of users around the globe) because our goal is to support Open Source Software.

Entering rocket.chat, an open source alternative to slack. And the good news is: it’s great! It has everything we possibly need: mobile apps (android and iOS), desktop apps (linux, OSX and windows), bots, private groups, APIs, integration with other services… and Slack import :)

The installation was very fast, if you follow the proposed way: a docker container.

Prerequisite: docker

If you don’t know what a docker container is, then it’s time to join BgLUG and come to one of our wednesday’s sessions. Docker is a way to pack together an application and all its dependencies, so it’s easy to deploy onto other servers.

Let’s see how it is to install docker on a debian/ubuntu machine.

1sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
2sudo apt-add-repository 'deb https://get.docker.io/ubuntu docker main'

The second line adds the repository to the system, while the first line acquires the key used to verify the packages.

1sudo apt update && apt install lxc-docker

This will update the packages list and install docker.

Installing containers

Docker apps are “shipped” in containers, an instance of an app. In this case we need two apps: rocket.chat and mongodb (the database rocket.chat relies on). Let’s start with the latter, with a small modification: we want the data accessible from outside, so we create the storage (and backup) directories:

1sudo mkdir -p /srv/rocketchat-mongodb /srv/rocketchat-mongodb-backup

Time to start mongodb container:

1docker run -v "/srv/rocketchat-mongodb:/data/db" \
2  -v "/srv/rocketchat-mongodb-backup:/data/backup" \
3  --name db --restart=always -d mongo:3.0 --smallfiles

That’s all. The DB container will start and store data on the specified directory. The backup directory is not really needed now, we will use it with an external cron job to dump DB data periodically.

1docker run --name rocketchat --link db -p "127.0.0.1:3000:3000" \
2  --env "ROOT_URL=https://chat.bglug.it" --restart=always -d rocket.chat

This pretty much cover the rocket.chat container. With the –link we connect the two conainers. With –env we specify the final root URL of this installation. With -p we expose the default 3000 port on the local interface, which is not reachable from the internet, but we-ll manage it in the next chapter.

Backup cronjob

Since this is a VPS, which has already got its backup solution, we want to export the whole db every once in a while. So we added a new cronjob, via a dedicated cron file (/etc/cron.d/rocketchat-mongodb-backup):

10 */6 * * * root /usr/bin/docker exec -i rocketchat-mongodb \
2  /usr/bin/mongodump -o /data/backup

Whith this command, every 6 hours we execute a command inside the container; this command will dump all the DB contents to the container’s /data/backup. We can find this dump in /srv/rocketchat-mongodb-backup.

Apache reverse proxy (temporary)

As I said before, the rocket.chat container is not accessible directly from the net, we’ll use apache as a reverse proxy to achieve also SSL support. We could use nginx but this server already has set apache as the web server listening to port 80 and 443.

We need a temporary apache configuration serving our domain and essentially allowing us to enable https (see the following step).

We now need to enable some apache modules:

1sudo a2enmod proxy
2sudo a2enmod proxy_wstunnel
3sudo a2enmod proxy_http
4sudo a2enmod ssl
5sudo a2enmod rewrite
6sudo service apache2 restart

And now a brand new configuration file for our host (let’s put it in /etc/apache2/sites.available/chat.bglug.it.conf):

 1<VirtualHost *:80 >
 2    ServerName "chat.bglug.it"
 3    ServerAdmin "[email protected]"
 4    UseCanonicalName Off
 5
 6    <Location />
 7        Order allow,deny
 8        Allow from all
 9    </Location>
10
11    RewriteEngine On
12    RewriteCond %{HTTP:Upgrade} =websocket [NC]
13    RewriteRule /(.*) ws://localhost:3000/$1 [P,L]
14    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
15    RewriteRule /(.*) http://localhost:3000/$1 [P,L]
16
17    ProxyPassReverse / http://localhost:3000/
18</VirtualHost>

We can now enable this site and commit all the changes to apache:

1sudo a2ensite chat.bglug.it.conf
2sudo service apache2 reload

Let’sencrypt SSL certificate

Let’s face it, HTTPS is going to be a requirement for every HTTP service in the next few months, so it’s better to implement it from day-0.

We need the certbot client.

If you’re on debian jessie, you need to enable the backports: add this to a new file named /etc/apt/sources.list.d/backports.list

1deb http://ftp.debian.org/debian jessie-backports main

In ubuntu you don’t need to add the new repo because the certbot client is already available for you. Install certbot as usual:

1sudo apt install certbot python-certbot-apache

Now you need to require a new certificate:

1certbot certonly --apache -d chat.bglug.it

This command will tell the certbot client to require a new certificate for chat.bglug.it using the apache method. The certificate files will be stored in /etc/letsencrypt/live/chat.bglug.it/

One more thing: let’sencrypt certificates expires in 3 months, and the package comes with free cronjob for renewal…

Apache reverse proxy (final)

Now that we have a certificate, we can modify the apache configuration (/etc/apache2/sites.available/chat.bglug.it.conf) to enable HTTPS:

 1<VirtualHost *:443>
 2    ServerName "chat.bglug.it"
 3    ServerAdmin "[email protected]"
 4
 5    UseCanonicalName on
 6    SSLStrictSNIVHostCheck on
 7
 8    SSLEngine on
 9    SSLCertificateFile /etc/letsencrypt/live/chat.bglug.it/cert.pem
10    SSLCertificateKeyFile /etc/letsencrypt/live/chat.bglug.it/privkey.pem
11    SSLCertificateChainFile /etc/letsencrypt/live/chat.bglug.it/chain.pem
12
13    SSLProtocol all -SSLv2 -SSLv3
14SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
15    SSLHonorCipherOrder on
16    SSLCompression off
17    SSLOptions +StrictRequire
18
19    <Location />
20        Order allow,deny
21        Allow from all
22    </Location>
23
24    RewriteEngine On
25    RewriteCond %{HTTP:Upgrade} =websocket [NC]
26    RewriteRule /(.*) ws://localhost:3000/$1 [P,L]
27    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
28    RewriteRule /(.*) http://localhost:3000/$1 [P,L]
29
30    ProxyPassReverse / http://localhost:3000/
31</VirtualHost>
32
33<VirtualHost *:80 >
34    ServerName "chat.bglug.it"
35    ServerAdmin "[email protected]"
36    UseCanonicalName Off
37
38    RewriteEngine On
39    RewriteCond %{HTTPS} off
40    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
41</VirtualHost>

The Virtualhost directive for port 80 now is redirecting everything to HTTPS.

Tell apache to reload config:

1sudo service apache2 reload

And now enjoy your new (SSL-enabled) rocket.chat!

Our is at: https://chat.bglug.it, join us!