Ship Serverless Functions to your Docker Swarm with OpenFaaS
Functions as a Service is a really neat way of implementing serverless functions with Docker. See how to deploy a FaaS function to a remote Docker Swarm!
Open Functions as a Service or OpenFaaS (lead by Alex Ellis) is a really neat way of implementing serverless functions with Docker. You can build out functions in any programming language and then deploy them to your existing Docker Swarm.
In this post we’ll look at an experimental CLI for making that even easier
Below is a quick example of how easy this is to do.
How it works
This diagram gives an overview of how the OpenFaaS function package, the Docker image, and the faas-cli deploy
command fit together.
To deploy a function onto an OpenFaaS stack, you firstly must write the function itself. This is really easy and you can do it in any language which runs inside Docker (i.e. all of them). At the current time, the OpenFaaS CLI supports Python and Node, so for this example we’ll use Python.
My very simple fib function is written in Python:
def fib(n):
if n <= 1: return n
else: return fib(n-1) + fib(n-2)
def handle(st):
n = int(st)
output = []
for i in range(n):
output.append(str(fib(i)))
print(', '.join(output))
Building the function package
The way OpenFaaS runs the function is by running this inside Python:
from function import handler
handler.handle(stdin)
When you build a function with the OpenFaaS CLI, what it’s doing is packaging up your function (handler.py
) and building out the parts for Docker to run the container.
To build the package, simply run:
$ faas-cli build \
--image=developius/faas-fib \
--name=faas-fib \
--handler=./sample/faas-fib \
--lang=python
The options mean:
build
- we want to build a function--image=developius/faas-fib
- the Docker image to build--name=faas-fib
- the name of our function--handler=./sample/faas-fib
- which handler to use--lang=python
- use the Python template
Here is an example package for our faas-fib
function, located inside faas-cli
’s build
directory:
$ tree build/faas-fib/
build/faas-fib/
├── Dockerfile
├── function
│ ├── handler.py <-- called by index.py
│ └── requirements.txt
├── index.py <-- Docker runs this
└── requirements.txt
1 directory, 5 files
The package includes everything to allow Docker to run our function - Dockerfile
, index.py
and handler.py
Deploying the function
Now that our function is built, we need to deploy it. Before we do this however, we must push our function to the hub.
$ docker push developius/faas-fib
Now for the deploy! This can be done with one command:
$ faas-cli \
deploy \
--image=developius/faas-fib \
--name=faas-fib \
--lang=python \
--gateway=http://faas-example.com:8080 \
--handler='index.py'
The options:
deploy
- we want to deploy our function-image
- the image from the hub we want to deploy-name=faas-fib
- what we want to call our function-lang=python
- which language to use-gateway
- this is the URL to our remote FaaS gateway-handler='index.py'
- which file to call with the stdin
When you run this command, the function will be deployed to the remote Docker Swarm. How cool is that?
Testing
The final thing to do is to test your function deployed successfully. You can do this via the FaaS UI or via curl
.
Or, via curl:
$ curl -d "10" http://faas-example.com:8080/function/faas-fib
0, 1, 1, 2, 3, 5, 8, 13, 21, 34
Recap
In this post we’ve seen how to package and deploy a function using the OpenFaaS framework. We’ve looked at how to write a function, how to build it into a function package and deploy it to a remote Docker Swarm. Pretty neat stuff.
I’ve built a number of other functions and hope to expand this to include more soon. I wrote a function to shorten URLs, using a service I built, which received a PR from Richard Gee to merge in an armhf Dockerfile for use on Raspberry Pies. This was a big milestone for me as I’ve never accepted a PR for one of my projects before!
Props to Alex Ellis for creating such an awesome tool, I look forward to participating in the development of FaaS in the future. It’s worth noting that FaaS is currently considered experimental but you can expect more language templates amongst some other neat features. First… learn Go. 🙈