Serverless Ruby with Docker and Apache OpenWhisk

Justin Halsall
May 8, 2018 · 7 min read

Update 2018/9/14: Apache OpenWhisk launched Native support for Ruby. This following article is still relevant for languages and Ruby version that don’t have native support.

In this article we are going to get our Ruby scripts running in a Serverless environment using Apache OpenWhisk’s native support for Docker actions. And we’ll host them on IBM Cloud’s managed OpenWhisk instance: IBM Cloud Functions.

Ruby is a language that excels in allowing us to write quick short scripts that make our life easier. Serverless is a great way to (not have to) manage these scripts and autoscale them. Unfortunately no Serverless platforms actually support Ruby out of the box.

My favorite thing about the Apache OpenWhisk serverless platform (apart from it being open source) is that it also supports any type of Docker container as a serverless action. We can go crazy running exotic languages in a serverless environment! Or we just easily add support for our Ruby scripts!

Image for post
Image for post
OpenWhisk’s architecture. The natively supported languages get executed in Docker “invokers”. In our case we’ll use our very own Docker container running Ruby!

Understanding how OpenWhisk’s Docker Actions work

To get Docker Actions to work there are a couple components we need to implement:

  • We’ll need a Docker Image containing a webserver bound to 0.0.0.0 and exposed via port 8080.
  • An endpoint accepting POST /init.
    And responding with status 200 and the text “OK”.
    This endpoint is called the first time an action is invoked and is useful if you need to compile or setup anything to before /run is called.
  • An endpoint accepting POST /run.
    This is where the magic happens, all Serverless actions are invoked via this endpoint. OpenWhisk will forward any set parameters as the “value” argument in JSON via the POST body.
    The cURL equivalent of an invoked action:

With these simple components we should be able to build any Docker container and use it as an OpenWhisk Serverless action.

Getting Started

Now that we have some of the theory down lets get coding!

Prerequisites

Install docker. Install docker-compose. Download the wskdeploy cli. Create a Docker Hub account. Create an IBM Cloud account (we’ll be using IBM Cloud Functions because it’s easy & free, but we can use any other managed OpenWhisk here if you’d like).

Setup

In these next couple steps we are going to create the bare minimum we’ll need to create our Docker container + Ruby script. Once were done with the setup we can deploy it to a serverless environment and test it out.

First we are going to need a folder structure like the following listed below.

I like using docker-compose’s cli over docker’s cli as it makes life a lot easier but if you are more comfortable with docker’s cli feel free to omit “docker-compose.yml" in your folder structure.

Let’s create the action.rb with our Ruby script. We are using Sinatra as our web server framework here since Sinatra is dead simple to use. Towards the bottom of this file is where we’ll normally insert our serverless code. In this example we will be hosting a super simple Hello World script.

Then we need to create the Dockerfile to get everything running.

And now we can create our docker-compose.yml file just so we can use docker-compose’s easy to use CLI:

Important: We are going to push our docker image to Docker Hub to allow us to pull it back into OpenWhisk. Make sure you rename juice10 to your Docker Hub username and openwhisk-ruby to the name of Docker Hub repo you want to store your project in.

Boom! Setup’s done! That wasn’t too hard!

Building our container

It’s time to build our docker container. (Output listed below, yours may differ. Look out for any errors.)

Let’s get our container running:

If everything is well we should get an output similar to what I listed above.

Testing our action

In another terminal window let’s simulate an OpenWhisk call to this action.

If all is well our response should be as above.

Now lets pass in a name into the action:

Push to Docker Hub

Your output the same?! Ok great! Now we verified it’s working locally, it’s time to push it to Docker Hub. Switch back to your first terminal window and lets push our image to Docker Hub.

Deployment

Now that it’s pushed to docker hub we can pull it in to OpenWhisk.

Let’s use wskdeploy. Download the wskdeploy cli to the folder if you haven’t already. Choose the one that works for your OS.

wskdeploy is a great tool for deploying any serverless actions to OpenWhisk. It uses a manifest.yaml file to figure out what OpenWhisk instance it needs to deploy to and what actions, files and docker instances it needs to use for the deployment. There are many of deploying our serverless actions, another good one is using the Serverless framework or the IBM Cloud cli.

Get your key, host and namespace for OpenWhisk from the IBM Cloud Functions API Key page. Add these to the credential:, apiHost: andnamespace: parameters in manifest.yaml.

You’ll also have to add your docker-hub-username/repo-path-name to the docker: parameter in the same file.

Now lets deploy it to IBM Cloud Functions using wskdeploy.

Testing our action for real

Now let’s invoke it to make sure it works!

Head over to your list of actions in OpenWhisk.

Image for post
Image for post

Select on your action and click the “Invoke” button to execute your action.

Image for post
Image for post
Image for post
Image for post

And you should see a response like this:

If you run the action a second time we’ll notice the action’s time going down from aprox. 400ms to 4ms. This is the dreaded ‘cold start’ that you always hear everyone talking about.

The very first time you run your action it might take up to 30 seconds on top of the 400ms to build your Docker image behind the scenes. Don’t worry that only happens once and won’t be seen again as part of the dreaded ‘cold start’.

Now if you changed the input to {"name": "friend"} you should get a response like this:

Excellent! In a couple of easy steps you where able to create a serverless action on OpenWhisk, hosted on IBM Cloud Functions. All from your own Docker container running your favorite language. Well done!

Bonus

Public endpoints

To open our action up to the public we can select “Endpoints” from the menu, select “Enable as Web Action”, hit the “Save” button and then your serverless action will become available for anyone to access.

Image for post
Image for post

Try out mine like:

Inspiration

Rob Allen created a PHP runtime for OpenWhisk and before he did that he wrote a similar article to this one on how to get PHP running in OpenWhisk with Docker. Now let’s make Ruby a first class citizen in the Serverless world!

Performance Notes: Webrick vs Thin

I made two versions of this action, here are the pros and cons of each:

Server: webrick Docker base image:ruby:alpine

  • Pro: Docker image is super small
  • Pro: Docker build time is super quick
  • Pro: Cold starts and first invocations are super quick
  • Neutral: actions execute in 3–6ms.
  • Con: ERROR Errno:ECONNRESET: Connection reset by peer @ io_fillbuf errors litter your OpenWhisk logs. The actions work but these errors are a little annoying.

Server: thin Docker base image: ruby:2.5

  • Con: Docker image is slightly bigger
  • Con: Thin needs native extensions to build, that takes a little while
  • Con: Cold starts and first invocations take a little longer
  • Pro: Actions execute a lot faster 2–3ms.
  • Pro: No errors, the logs are clean

Apache OpenWhisk

Apache OpenWhisk is a serverless cloud platform that…

Thanks to remko de knikker

Justin Halsall

Written by

Founder, MC, Public Speaker and Full Stack Web Developer. Founder of @RecordOnce, former Developer Advocate at @IBMCloud. Co-founder of @AMSxTech

Apache OpenWhisk

Apache OpenWhisk is a serverless cloud platform that executes code in response to events

Justin Halsall

Written by

Founder, MC, Public Speaker and Full Stack Web Developer. Founder of @RecordOnce, former Developer Advocate at @IBMCloud. Co-founder of @AMSxTech

Apache OpenWhisk

Apache OpenWhisk is a serverless cloud platform that executes code in response to events

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store