Posted by & filed under aws, DevOps, Docker.

When you read about Hubot you read about HerokuHeroku seems to be the defacto hosting environment for Hubot, so much that even Hubot‘s own documentation makes reference to hosting it on Heroku — mainly because it can be setup in a snap and is free as long as you keep your usage levels on the low side.

Since we have most of our infrastructure in AWS, we wanted to keep our Hubot there. A t2.micro instance is cheap and powerful enough for the light work required of our robot. We decided to launch a Multi-container Docker environment in Elastic Beanstalk and run a container for Hubot and a separate container for it’s brain: Redis.

In this scenario, we’re not using Elastic Beanstalk for its scaling capabilities. We’re only using it for the ease at which you can launch multiple Docker containers and link them together. This setup will not scale horizontally without replacing the Redis container with Elasticache or another hosted Redis service.

Create a Multi-Container Elastic Beanstalk application

Launch the Elastic Beanstalk console and create a new application. Setup a “web server” environment and choose Multi-container Docker as the predefined configuration.

Screen Shot 2015-10-07 at 8.31.18 AM

Continue through the Elastic Beanstalk wizard and adjust any settings as needed. If you haven’t setup a Docker environment in Elastic Beanstalk yet, pay close attention to the instance and service role selection. Failing to complete that step and not creating the necessary permissions will prevent Elastic Beanstalk from properly managing your ECS cluster.

To get your environment up and running as quickly as possible, choose the “Sample application” at the deployment screen. We launch all of our Elastic Beanstalk environments in their own VPCs, so choose the setting most appropriate for you. Once you’re happy with the options you’ve set, launch your environment.

While your environment is launching, you can begin to build the Docker image for Hubot:

We use this Dockerfile to fetch dependencies, generate our Hubot, and then configure him with the “slack” adapter (for communicating with Slack) and give him a name. These settings can also be configured at runtime when executing bin/hubot.

Once the Dockerfile has been modified (or not) to suite your needs, let’s create the files our Dockerfile needs to complete the build.

external-scripts.json: See the “scripting” section here for a description.

package.json: Add npm packages here that should be installed at build time.

  "name": "hubot",
  "version": "0.0.0",
  "private": true,
  "description": "A simple helpful robot for your Company",
  "dependencies": {
    "hubot": "^2.16.0",
    "hubot-diagnostics": "0.0.1",
    "hubot-google-images": "^0.2.2",
    "hubot-google-translate": "^0.2.0",
    "hubot-help": "^0.1.1",
    "hubot-maps": "0.0.2",
    "hubot-pugme": "^0.1.0",
    "hubot-redis-brain": "0.0.3",
    "hubot-rules": "^0.1.1",
    "hubot-scripts": "^2.16.2",
    "hubot-shipit": "^0.2.0",
    "hubot-slack": "^3.3.0"
  "engines": {
    "node": "0.10.x"
} This will be executed by ECS to start Hubot


bin/hubot --adapter slack

With these files created, let’s run the build:

> docker build -t myhubot .

If you see any errors, double check the Dockerfile for spelling errors and make sure all the filenames match.

Once your build completes successfully, you can run a test to make sure Hubot starts:

> docker run --rm -it myhubot bin/hubot

After several seconds you should see some INFO logging to screen and no significant errors.

Now you can push your Hubot image to your private Docker registry (i.e. premium DockerHub account,, custom registry, etc.)

We can now create a file that’s used to describe our containers to be launched by Elastic Beanstalk:

    "AWSEBDockerrunVersion": 2,
    "authentication": {
        "bucket": "[AUTH_BUCKET]",
        "key": "[DOCKERCFG]"
    "containerDefinitions": [
            "name": "redis",
            "image": "redis:latest",
            "essential": true,
            "memory": 256,
            "mountPoints": [
                    "sourceVolume": "awseb-logs-redis",
                    "containerPath": "/var/log/redis"
            "name": "hubot",
            "image": "[YOUR_REGISTRY/HUBOT]",
            "links": [
            "essential": true,
            "memory": 256,
            "mountPoints": [
                    "sourceVolume": "awseb-logs-hubot",
                    "containerPath": "/var/log/hubot"
            "command": [

Be sure to replace [AUTH_BUCKET], [DOCKERCFG], and [YOUR_REGISTRY/HUBOT] with your own. See the “authentication” section here for details. In addition to launching your Hubot container, we’re also launching a Redis container and linking to the Hubot container. Since we’re using the default Redis configuration, there’s no need to store that image in your own registry unless you need to make significant changes.

Next, we need to update the Elastic Beanstalk environment with some environment variables. Access your environment in the Elastic Beanstalk console, click the “Configuration” link in the left panel and then visit the “Software configuration” section. Add the REDIS_URL variable with a value of redis://redis:6379. If you’re going to be connecting to Slack, you’ll need to also supply HUBOT_SLACK_TOKEN which you can retrieve by activating Hubot as an integration inside Slack.

Save your environment variable changes and click “Dashboard” from the left panel to return to the main environment page. Once your environment has finished updating, click “Upload and deploy”. Upload your file as your application and provide a version number. Click “Deploy” and monitor the console for any error messages.

With any luck, you’ll have Hubot up and running inside ECS and can begin writing scripts to interact with him. To add new scripts, just modify the Dockerfile to add them to the appropriate location, rebuild the image and push it to your registry, and finally deploy the file once again.

Leave a Reply

Your email address will not be published. Required fields are marked *