21
rocketchat with mongo 5
rocketchat is a slick chat server that you can deploy yourself. if you're looking to include live chat in your next project or are just looking for a roll-your-own slack replacement, it's a good candidate.
in this fly-over we will be deploying rocket chat backed by mongodb 5.0 on an ec2 t2.micro running ubuntu 20.04 and we'll be putting it behind an nginx reverse proxy so we can serve easily over ssl.
this is going to be on an ec2 t2.micro running ubuntu 20.04. for the detail-oriented, that's ami-03d5c68bab01f3496
.
ensure that you have a public ip address. if you plan on this being used in production, an elastic ip is highly recommended.
the default disk size for t2.micros is 8gb. this is slim at the best of times, but rocket and mongo eat up disk space, so we're going to give ourselves a 20gb disk.
we will also want to have a domain name pointing to our ec2, so fire up route53 and do that, and port 3000 open on our firewall. we will close this port later.
ec2 micros only come with one gig of ram out of the box and no swap partition, which is fine for hello-world calibre stuff, but rocketchat wants ram. so, first thing is to get a swapfile up and running.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
here we create an empty file 2 gigs in size using fallocate
, lock its permissions down then deploy it as memory swap. you can see the effects immediately with free -h
.
obviously, we want our swap file to persist after reboot, so will add it to the 'file system table' (called 'fstab'). open up /etc/fstab
as root in your favourite text editor and drop this line at the bottom:
/swapfile none swap sw 0 0
there are some necessary prerequisites for rocket and mongo. the big one here is build-essentials
which includes gcc
and make
and other similar tools.
sudo apt update
sudo apt install curl build-essential graphicsmagick
at the time of writing, the latest version of rocketchat is 4.02. this requires node
12.22.1, so we will install the latest node from 12.x.
curl -sL 'https://deb.nodesource.com/setup_12.x' | sudo bash -
sudo apt update
sudo apt install nodejs
once done you can check with
node --version
the official docs say rocketchat 4.02 works with mongodb 4.0. however, on first run you will prompted to upgrade mongo. we could do that, or we could just install mongo 5.0 right away.
mongo is quite demanding of system resources, so we will need to be increasing our ec2's system limits later if mongo is going to run, but first, we will do the install
wget -qO - <https://www.mongodb.org/static/pgp/server-5.0.asc> | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] <https://repo.mongodb.org/apt/ubuntu> focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
sudo apt update
sudo apt install mongodb-org
mongo is installed from a custom source, so here we load the gpg key and create the necessary source file. then it is a simple matter of update and install.
once we have mongodb installed, there's some simple configuration
sudo sed -i "s/^# engine:/ engine: wiredTiger/" /etc/mongod.conf
sudo sed -i "s/^#replication:/replication:\n replSetName: rs01/" /etc/mongod.conf
if you look at the official rocketchat docs, you will notice that the mongo engine they specify is mmapv1
. that's deprecated in mongodb 5.0, so we will be using wildTiger
instead.
as previously mentioned, mongo needs an increase in our ec2's system limits if it's going to run well (or at all). most notably, we're going to be bumping up the maximum number of files usable by the mongodb
user.
first, we will increase our file-max. as root, using the editor of your choice, open /etc/sysctl.conf
and paste this at the bottom of the file.
fs.file-max = 200000
then run
sudo sysctl -p
next, we're going to modify the soft and hard per-user limits for the user that runs mongodb. for this we will edit, as root, the file /etc/security/limits.conf
and add, at the bottom:
mongodb soft nproc 200000
mongodb hard nproc 200000
mongodb soft nofile 200000
mongodb hard nofile 200000
mongodb soft memlock 2048
mongodb hard memlock 2048
that's a large "number of files" (nofile) and "number of processes" (noproc)!
then, we will update the pluggable authentication module (pam) to actually read these limits. to do this, edit, as root, /etc/pam.d/common-session
and add, at the bottom:
session required pam_limits.so
and that's it. we have given the user that runs mongo expanded resource access so our db doesn't fall over on start.
let's start up the mongodb daemon.
sudo systemctl enable mongod.service
sudo systemctl restart mongod.service
to see the product of our success, we can check its status
sudo systemctl status mongod.service
at long last, we are actually ready to install rocket chat.
there are a few steps to this process:
- download the source tarball
- install the dependencies with npm
- put the executable where we want it
- create a user to run rocketchat, and then
- configure systemd so we can run it as a daemon
first we're going to download the 'latest' version of rocketchat (4.0.2 at this writing) and untar it.
curl -L https://releases.rocket.chat/latest/download -o /tmp/rocket.chat.tgz
cd /tmp/
tar xzf rocket.chat.tgz
now that we have the source on disk, we install the dependencies.
cd /tmp/bundle/programs/server
npm install
this, of course, will take some time.
the offical docs imply that the executable should live in /opt
. many people much smarter than i have waged war over /opt
vs. /usr/local/bin
and, while i do have opinions, it is probably better to stick with the 'canonical' decision, if for no other reason than to make the official documentation easier to use. 'opt' it is
sudo mv /tmp/bundle /opt/rocket.chat
here we create user and group 'rocketchat' and then give that user ownership of our rocketchat executable. it is certainly possible to run rocketchat as the 'ubuntu' user, but it is not a good idea. let's make the user, group and assign ownership of the executable:
sudo useradd -M rocketchat
sudo usermod -L rocketchat
sudo chown -R rocketchat:rocketchat /opt/rocket.chat
rocketchat is a service in the same way that, say, nginx
is, so we want to be able to run it as a daemon in the same way. doing this involves creating a fairly straight forward systemd
configuration file.
as root, create and edit the file /lib/systemd/system/rocketchat.service
in that file paste:
[Unit]
Description=The Rocket.Chat server
After=network.target remote-fs.target nss-lookup.target nginx.service mongod.service
[Service]
ExecStart=/usr/bin/node /opt/rocket.chat/main.js
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=rocketchat
User=rocketchat
Environment=MONGO_URL=mongodb://localhost:27017/rocketchat?replicaSet=rs01 MONGO_OPLOG_URL=mongodb://localhost:27017/local?replicaSet=rs01 ROOT_URL=<PUBLIC_URL> PORT=3000
[Install]
WantedBy=multi-user.target
don't save yet!
there are things you will need to change:
-
PUBLIC_URL: this is on the
Environment
line. you will need to put in the url you intend to serve rocketchat on here and specify the port 3000. ie.http://rocket.example.ca:3000
. note that this ishttp
nothttps
, and don't forget to add the:3000
port at the end. - Description: it's not mandatory to change this, but it's nice to have something more personal than the factory defaults
you may also want to confirm that your node
bin actually lives in /usr/bin/node
and edit accordingly.
once you have made the necessary changes, save your systemd file.
we're very close to being able to start rocketchat, but first we need to start mongodb replicating with:
mongo --eval "printjson(rs.initiate())"
now all we have to do is enable and start the rocketchat daemon:
sudo systemctl enable rocketchat
sudo systemctl start rocketchat
to confirm that we're running on all four wheels, check the status:
sudo systemctl status rocketchat
now that rocketchat is up and running and serving on port 3000, we can go and edit all of its configurations using the web interface.
navigate to the url you set as ROOT_URL
above, ie http://rocket.example.ca:3000
and follow the instructions.
this is also an excellent time to discover if you have port 3000 open on your firewall!
we're successfully serving rocketchat now, but it's not... satisfying. obviously we will want our chat to use ssl and use the standard 443 port, not 3000. to accomplish this, we're going to put together a proxy with nginx.
we're going to use nginx for proxying, so the first step is to install it:
sudo apt update
sudo apt install nginx
easy!
this is a little harder. using the editor of your choice, as root, create and edit the file etc/nginx/sites-available/001-rocketchat.conf
then add to it:
# Upstreams
upstream backend {
server 127.0.0.1:3000;
}
# HTTPS Server
server {
listen 80;
server_name your_hostname.com;
# You can increase the limit if your need to.
client_max_body_size 200M;
error_log /var/log/nginx/rocketchat.access.log;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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 https;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
don't save yet!
you will see on line 10 server_name your_hostname.com;
. change your_hostname.com
to the hostname you set in ROOT_URL
minus the port, ie rocket.example.ca
. now save
now we are going to enable this nginx configuration by making a symlink in sites-enabled
:
cd /etc/nginx/sites-enabled/
sudo ln -s ../sites-available/001-rocketchat.conf
we can confirm that our configuration is good thusly:
sudo nginx -t
you should see an 'Ok' message.
once we have a good configuration, we restart nginx and begin serving:
sudo systemctl restart nginx.service
we're now serving through our proxy on old-fashioned http, but we would really prefer to be using ssl.
to accomplish this, we're going to use the EFF's certbot
tool to get a free signed certificate and install it.
first, we install the certbot
tool. this is delivered as a snap:
sudo snap install core; sudo snap refresh core
sudo snap install certbot --classic
once certbot is installed, getting a signed certificate is simple.
sudo certbot --nginx
we will be asked for our email and to accept the terms and conditions, and then prompted to choose which site we want to install ssl for. we only have one site, so that's easy!
once certbot
is done, we can inspect, if we choose, our nginx configuration at etc/nginx/sites-available/001-rocketchat.conf
and see the changes certbot
has made.
certbot certificates are only good for three months. fortunately, it is straightforward to set up auto-renewal. we'll do that with:
sudo certbot renew --dry-run
that's it. we can now navigate to our rocketchat install at our ROOT_URL
on https, ie https://rocket.example.ca
and troll whoever is there.
21