Running a Hubot in the Kubernetes cluster — part 1

Lukasz Lenart
SoftwareMill Tech Blog
4 min readJan 17, 2020

--

The very first option to setup and run your own Hubot is Heroku. There is a whole section in Hubot’s documentation how to do it. This is a very easy and straightforward solution, yet it’s true as far as you are running just Hubot and you don’t have any other services to maintain.

In a modern company, consolidating your services and resources on one platform reduces maintenance and operations costs, not to mention better knowledge sharing inside the IT department. You do not need to hire multiple specialists to support each platform, you just need one YAML developer ;-)

Photo by Franki Chamaki on Unsplash

Background

Some time ago we started moving all our dispersed services into a Kubernetes cluster (aka k8s), which is running on the Google Cloud Platform. As this requires some changes to the application itself, it is not just devops work.

We are already running two Hubot instances on Heroku and as there are plans to start using another bot, I decided that it’s a good opportunity to setup everything on our k8s cluster and learn how to migrate the other bots to the same platform.

This post is addressed to Devops people as well as to ordinary developers like me. After reading through all the parts you will gain knowledge how to setup any application on the k8s cluster.

Prerequisite

I assume you have your own k8s cluster running, also you have access to Jenkins which is running on the same cluster or at least it has the Kubernetes plugin installed. These are the required steps before moving forward. If you miss them, please hire some Devops guy to setup everything for you :)

Now you need to install the following tools locally on your box:

  • Docker — you must be able to run a docker command and docker-compose as well
  • Helm v3.0 — a package manager for k8s
  • Kubectl — a cli tool to control k8s cluster

Having said that, the very last thing is your Hubot instance which, I assume, you have been already using and running on Heroku or so.

Brain

One of the core changes to our Hubot instance, which is running on Heroku right now, is to start using MySQL instead of Redis to store Hubot’s brain. Setting up a MySQL instance on k8s is very easy comparing to a Redis cluster. Also Hubot already supports MySQL by using hubot-mysql-brain package, so the solution looks easy. Just please remember to export current Hubot’s brain :)

Dockerize

The very first step of running any application in k8s cluster is to dockerize it. There are already a few ready to use images, but I do prefer creating my own image using a Dockerfile. Below is an example I’m using right now to run all our bots:

Hubot is written in Coffeescript which compiles to a plain JavaScript, which means it’s a Node.js based application — that’s why I started with node as a base image. Then I added a few useful packages, configured a proper Timezone and defined a user — Devops will like that ;-)

Then I copied all Hubot’s related folders and finally exposed port 8080 as a default port used by Hubot’s express backend — this is needed if you want to use advanced Slack API.

You can build and test the image locally by using the commands below:

docker build -t bob-the-bot .docker run -it --rm bob-the-bot

You will see your bot is running yet it’s missing a lot of configuration. Let’s use docker-compose.yaml instead to setup the whole environment properly.

docker-compose

Using docker-compose.yaml allow us to setup not just Hubot’s image but also run a MySQL instance that can be used by the Hubot. As I mentioned earlier, setting up a MySQL instance on a k8s cluster is very easy. Before starting doing this it’s a good practice to have tested everything locally. Thus, that means I must configure the bot to start using hubot-mysql-brain instead of Redis. Please follow the instruction on this page on how to do it.

Having the bot ready to use MySQL you can use the below docker-compose.yaml to test all the pieces:

Just a few things need to be explained. First, MYSQL_URL is a url used by hubot-mysql-brain to connect to the MySQL instance, HUBOT_SLACK_TOKEN and HUBOT_SLACK_VERIFICATION_TOKEN are two envs specific to your local env — they will be passed directly from your env to the running instance of the Hubot’s image.

Second, depend_on defines a dependency on the MySQL image, which means that the MySQL container must be started first and then the Hubot’s container can be launched. I have used an official MySQL image from the Docker Hub.

The final step is to initialise the MySQL instance as it’s required by hubot-mysql-brain. To do this I have used an external SQL script to create a new database and table . To run the script you must define a command section with a proper volume:

command: --init-file /data/application/init.sql
volumes:
- .:/data/application/

The SQL script looks like this:

Test

Right now we can test everything together, assuming you have set Slack tokens in your env you can run the bot:

docker-compose build
docker-compose up

You should notice that MySQL instance has started and the init script was loaded:

[Note] Execution of init_file '/data/application/init.sql' started.
[Note] Execution of init_file '/data/application/init.sql' ended.

Then the bot itself was started and connected with Slack:

INFO Logged in as @bob in workspace SoftwareMill
INFO Connected to Slack RTM

Now we are ready to become a YAML developer and deploy our bot into a Kubernetes cluster.

--

--

OSS enthusiast, ASF committer, Apache Struts lead, developer, husband and father and biker :-)