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.

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
sudo 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.

sudo 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:

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

Time to start mongodb container:

docker run -v "/srv/rocketchat-mongodb:/data/db" \
  -v "/srv/rocketchat-mongodb-backup:/data/backup" \
  --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.

docker run --name rocketchat --link db -p "127.0.0.1:3000:3000" \
  --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):

0 */6 * * * root /usr/bin/docker exec -i rocketchat-mongodb \
  /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:

sudo a2enmod proxy
sudo a2enmod proxy_wstunnel
sudo a2enmod proxy_http
sudo a2enmod ssl
sudo a2enmod rewrite
sudo 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):

<VirtualHost *:80 >
	ServerName "chat.bglug.it"
	ServerAdmin "info@bglug.it"
	UseCanonicalName Off

	<Location />
		Order allow,deny
		Allow from all
	</Location>

	RewriteEngine On
	RewriteCond %{HTTP:Upgrade} =websocket [NC]
	RewriteRule /(.*) ws://localhost:3000/$1 [P,L]
	RewriteCond %{HTTP:Upgrade} !=websocket [NC]
	RewriteRule /(.*) http://localhost:3000/$1 [P,L]

	ProxyPassReverse / http://localhost:3000/
</VirtualHost>

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

sudo a2ensite chat.bglug.it.conf
sudo 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

deb 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:

sudo apt install certbot python-certbot-apache

Now you need to require a new certificate:

certbot 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:

<VirtualHost *:443>
	ServerName "chat.bglug.it"
	ServerAdmin "info@bglug.it"

	UseCanonicalName on
	SSLStrictSNIVHostCheck on

	SSLEngine on
	SSLCertificateFile /etc/letsencrypt/live/chat.bglug.it/cert.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/chat.bglug.it/privkey.pem
	SSLCertificateChainFile /etc/letsencrypt/live/chat.bglug.it/chain.pem

	SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite 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
	SSLHonorCipherOrder on
	SSLCompression off
	SSLOptions +StrictRequire

	<Location />
		Order allow,deny
		Allow from all
	</Location>

	RewriteEngine On
	RewriteCond %{HTTP:Upgrade} =websocket [NC]
	RewriteRule /(.*) ws://localhost:3000/$1 [P,L]
	RewriteCond %{HTTP:Upgrade} !=websocket [NC]
	RewriteRule /(.*) http://localhost:3000/$1 [P,L]

	ProxyPassReverse / http://localhost:3000/
</VirtualHost>

<VirtualHost *:80 >
	ServerName "chat.bglug.it"
	ServerAdmin "info@bglug.it"
	UseCanonicalName Off

	RewriteEngine On
	RewriteCond %{HTTPS} off
	RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
</VirtualHost>

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

Tell apache to reload config:

sudo service apache2 reload

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

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