Migrating a self-hosted manual deployment of Rocket.Chat to a deployment based on docker-compose without losing data

Docker and docker-compose provides an amazing way to quickly setup complicated applications that depends on several separate components running as services on a network. This is evident in the amount of time and effort docker-compose spare when deploying a certain web-app like Rocket.Chat, the open-source business communication platform that provides many features such as persistent chat rooms (channels) organised by topic, private groups, and direct messaging.

In a previous article, I described a method of how to use docker and docker-compose to quickly deploy a new instance of Rocket.Chat. But, what if you are already using a self-hosted version of Rocket.Chat that you have installed manually on a Linux server or using snap? What can you do to move your old setup to a modern docker based setup that is easy to maintain, has better up-time?

As the title suggests, in this article I describe the steps I took to migrate a self-hosted manual deployment of Rocket.Chat to a self-hosted deployment based on docker-compose deployment without losing data.

The major part of the migration is actually just moving Mongo server to a deployment of Mongo server based on docker-compose. If that is not necessary because you are already using a dedicated Mongo server or a managed Mongo service, then your task is easier, and the plan below will not work for you as it covers subjects beyond your need, namely the subject of migrating a Mongo database to a database in a Mongo deployment based on docker-compose.

The Plan

  1. Downtime: The first step would be to stop the running Rocket.Chat server, the goal is to prevent users from adding new content such as messages and photos, status update, new channels etc. to the database during the migration.
  2. Backup: Then we will create a backup of the Rocket.Chat Mongo database. If Rocket.Chat is the only consumer of the Mongo server, then we will simply create a backup of the entire Mongo server. The goal is to keep a backup in case something went wrong, and also to populate the database with old data if needed.
  3. Setup: Now it is time to setup the new Rocket.Chat deployment based on docker-compose.
  4. Restore: The final step would be to restore the database from the backup you have created earlier.
  5. Cleanup: cleanup the old deployment. Stop the old Rocket.Chat server.

The Steps

Downtime

The first step would be to stop the running Rocket.Chat server, the goal is to prevent users from adding new content such as messages and photos, status update, new channels etc. to the database during the migration.

So, let us stop the running Rocket.Chat service and the running http reverse proxy service. In my case, that translates to:

service stop nginx
service stop rocketchat

Backup

Then we will create a backup of the Rocket.Chat Mongo database. If Rocket.Chat is the only consumer of the Mongo server, then we will simply create a backup of the entire Mongo server. The goal is to keep a backup in case something went wrong, and also to populate the database with old data if needed.

If that is not necessary because you are already using a dedicated Mongo server or a managed Mongo service, then you could skip this step all together and move to the next step.

To backup the entire Mongo server use the following command on the Mongo server hosting the rocketchat Mongo database.

mongodump --archive --gzip > 2022.07.27_rocketchat_mongo_server.dump.archive.gzip

The command will dump all databases available on the Mongo server, archive and gzip them and write the result in the file called 2022.07.27_rocketchat_mongo_server.dump.tar.gz. The file will reside on the filesystem where you have initiated the command. It might be still necessary to move the backup file later to the new server where the docker-compose based deployment of Rocket.Chat will be. Or you might want to keep it in a safe place as part of your infrastructure backups.

Setup

Now it is time to prepare the new server that will host the Rocket.Chat deployment based on docker-compose. I recommend using the process described in this article. Just make sure to point the old domain name to the new server. This means that you might have to wait for the TTL seconds defined in the current A or AAAA records of the DNS settings of the domain to expire before the new A or AAAA records to be valid.

Once you finish the setup, try to access your new deployment of Rocket.Chat, that will trigger the standard Setup Wizard.

Here is the catch. You have to finish the Setup Wizard before restoring the old database, because your new Rocket.Chat installation needs to be registered with the Rocket.Chat company servers. Once the registration is complete you can proceed to restoring the database as described in the next paragraph.

Restore

Now that Rocket.Chat is running with docker-compose, we still want to regain all the old settings, messages, content, channels that were on the old rocket.chat installation.

Then let’s do the following:

docker-compose -f docker-compose.yaml down
docker exec -i mongo sh -c 'mongorestore --archive --gzip < 2022.07.27_rocketchat_mongo_server.dump.archive.gzip'
docker-compose up -d

Done. Now, access the website, login and rediscover your workspace…

Cleanup

Before considering the task done, it is important to do some house-keeping

Delete the old deployment

Store the Mongo backup in a secure manner according to your Organization policies or delete it if it was not going to be needed

On the new server running docker-compose, make sure to remove any docker containers that has existed. For that you can use:

docker-compose prune

Conclusion

I this articles I discussed the steps needed to migrate a self-hosted manual deployment of Rocket.Chat to a deployment based on docker-compose without losing data. The article discussed the case where the Mongo server is also self-hosted on the same machine and also needs to be migrated to a docker-composed managed deployment. There are many other cases where that is not the case, but in all those cases the steps mentioned above would generally still work. You will have to adapt the steps according to your needs.