Funtainers: The Beauty of Running Containers as Functions

“Serverless Doesn’t Actually Mean That There Are No Servers. It Just Means That You Don’t Have To Deal With Them Anymore,” so the saying goes.
At the last Serverlessconf, we saw the rise of serverless usage and this time around, that rise is no less impressive.
I had the honor of being a keynote speaker at the conference and chose to speak about this sharp change in the world of developers and DevOps, from managing to containers and microservice development to that of functions and serverless.
If we take a second to look back at the past 20 years, the evolutionary graph shows us just how far we’ve come. We’ve quickly evolved from managing physical servers to virtual machines, and now are evolving from running on containers to running functions.

When Docker broke out, Linux containers became so easy to use that they quickly went mainstream. They became a truly useful tool for helping developers build, ship, and run. We started developing microservices in a very comfortable way and understood that development doesn’t have to be so hard anymore.
Along came Amazon Web Services’ Lambda in 2014 — a service that allowed users to run code without managing or even thinking about servers. The implicit promise with Lambda, forget about containers and start building functions. The big question is how these two concepts connect. Is there a conflict between these two technological mutations or is there a way to actually merge these technologies in miraculous fashion?
To answer this question, let’s first start by talking about the barriers that exist when adopting serverless technologies, the advantages of containers, and everything in between.
The Barriers to Getting Started with Serverless
1. A Dramatic Shift in Development Methodology
Change is never easy. In order to utilize functions, we need to start with tiny building blocks, even tinier than microservices — essentially micro-microservices. This means that we’ll have to develop even more services.
2. Utilizing Different Interfaces
If we want to use Spotinst Functions, Lambda, or Azure Functions, we need to match or code to that specific template or signature. Here’s an example of what I mean:
We can see Amazon’s interface in white, Google’s in blue, and Azure’s in yellow. That means that every cloud responds a little bit differently to your code, making it harder to adopt it in any standardized fashion
3. Changing the Way and Thought Process Behind Deployment
We are used to a world of containers and VMs, techniques like blue/green deployment and health checks, or deploying a new version in a step-by-step fashion. Functions demand that we deal with a slightly different reality. And again, change is never easy.
4. Dependencies — Relying on Third Parties
When we run code on a VM or container, we know that all of our dependencies for running our code will be found on the server that the code runs on. In the new serverless world, we’ll need to pack our code and its dependencies into one ZIP so that our serverless provider can run the function. In addition, we are limited to just 50MB (including any dependencies!), making it even harder to run complex code in a single function.
Functions do bring a lot of advantages, but they are held back by obstacles that aren’t so simple to solve. But what if we could take all of the benefits of containers and apply them to our functions?
To answer this, let’s dive a bit deeper to look at the underlying technology behind AWS Lambda – how does this magic we call Serverless computing really work?
It’s actually quite simple:
- We upload our code (with its dependencies).
- The Functions provider (Lambda, in this example) takes our code and injects it into a container.
- The container runs the function on a server, and Lambda spits back the output.
What if we skip Step 2, creating a situation where the input of the function is actually a container so that our Functions provider takes our container and just runs that?
We call this process of running containers as functions “Funtainers.” This allows us to take all of the advantages that come with running a container and combine them with all of the advantages of running a function. Advantages like high availability, no-ops, and serverless computing, all running atop the Containers we’ve grown so familiar with in recent years.
It seems that Funtainers, or containers-as-functions, is a concept that is growing at an incredibly fast pace, with three large projects taking advantage of this new phenomenon:
- IBM OpenWhisk
- Our own Spotinst Functions
- OpenFaas.
With all of these platforms come incredible benefits:
- No programming language limitations, unlike other FaaS products.
- No worries about dependencies or ZIP files (everything is packed into the container).
- No more vendor lock-in; run your Funtainer on any platform and move it whenever.
- No need to worry about the different FaaS code interfaces.
So how does this actually work?
- Write your code.
- “Pack” it into a container.
- Build a Dockerfile that includes all of the required installations for our container to run.
- Upload your container to Hub.
- Create a function, replacing the input code with the DockerHub/ContainerName.
- Run the function.

An example of a Dockerfile that runs C on a container.

An example Funtainer, where the input isn’t code, but a container.
In other words, this whole seismic shift is happening whether we like or not. When, not if, is the real question, as to when Functions will become the way most companies run code.
But this change doesn’t have to be scary. It doesn’t mean that we need to shift the entire way we recently learned to run our code (on Containers) and learn something new. Running containers as functions (Funtainers) can allow us to easily ride this wave and enjoy the benefits of both containers and functions together.