Running Azure Functions in a Docker Container: A Beginner’s Guide

Derek Fernandez
FAUN — Developer Community 🐾
8 min readApr 17, 2019

--

The main goal of this tutorial is to provide the audience with sufficient background to enable -and encourage- them to take their first steps in the usage of these tools. No previous technical knowledge will be assumed. This tutorial intends to guide readers through the process of installation and implementation of an Azure Function in a Docker Container.

A Brief Introduction to the Technologies

Azure Functions is a serverless compute service that enables you to run code on-demand without having to explicitly provision or manage infrastructure. Azure Functions Runtime runs on .NET Core, which means it’s cross-platform.

Here are, among many others, some of the most remarkable Azure Functions’ features:

Intuitive, browser-based user interface — You can write code in the easy-to-use web interface or use your favorite development tool to build and debug.

Variety of programming languages — The developer has the freedom to choose the programming language of his/her choice. The service accepts a variety of programming languages like C#, F#, Node.js, Python, PHP or Java.

Compute-on-demand — This delivery model ensures that computing resources are available to the users as per their demand. It is the user’s enterprise or cloud service provider that usually maintains these resources. The user doesn’t have to worry about provisioning or managing them anywhere, but rather, focus on their business logic.

Azure Functions’ Official YouTube Channel Features Overview

Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and ship it all out as one package. By doing so, thanks to the container, the developer can rest assured that the application will run on any other machine regardless of any customized settings that machine might have.

In a way, Docker is a bit like a virtual machine. But unlike a virtual machine, rather than creating a whole virtual operating system, Docker allows applications to use the same kernel as the system that they’re running on and only requires applications be shipped with things not already running on the host computer.

For developers, it means that they can focus on writing code without worrying about the system that it will ultimately be running on. It also allows them to get a head start by using one of thousands of programs already designed to run in a Docker container as a part of their application.

Fine but.. why using them together?

Despite the consumption plan being a superb way to host your Function App, bringing all the benefits of serverless, Docker Containers open the door to hosting in a lot more environments than were previously possible. This combo gives you the flexibility to easily deploy and run your microservices either in the cloud or on-premises.

Microsoft already provides some Docker base images for hosting Azure Functions. In some situations, you might as well want to use a custom image. It comes handy when your functions need a specific language version or require a specific dependency or configuration that isn’t provided within the built-in image.

Installation

If your environment is already setted up, you should want to skip this part.

NOTE: If you use Windows as your OS, you might want to know that Docker will just run on 64 bits Win 10 64 Pro or Enterprise Edition. This is because it uses Hyper-V and, while some older versions have Hyper-V, their implementations lack critical features for Docker to work. If you don’t meet this requirement don’t worry, you can still use Docker by downloading Docker Toolbox.

Step-by-step Installation

1 — Download Docker from here. You will need to sign-up to gain access to the download link. Once the .exe is downloaded, execute it and follow the steps of the setup wizard. If you are on Linux, you might want to check this site, where you will find a step-by-step guide for your distro.

2 — Install .NET Core 2.x SDK from here.

3 — Install Node.js (includes npm) from here.

4 — If you are on Windows, all you have to do is to open cmd and run:

npm install -g azure-functions-core-tools

This will install the Core Tools package in your system.

For another OS, step 4 might be slightly different. For more details, you can check this site.

Once we have our environment ready, it’s time for action.

Creating our first app

First of all, you will need to create a folder (or use an existing one). This folder is where we will create our Function App.

1 — From cmd, go to the folder you just created. Once inside, run this command:

func init --docker

This command will prompt you for which worker runtime you want -choices are currently .NET, Node or Python-.

Image 1.1

I will choose dotnet for writing my function in C#, so option no. 1 is my pick. Depending on your pick, there’s a different base image used.

Once an option has been picked, your function will be initialized by creating all the files needed in the path where you ran the command mentioned. So, if you check the folder’s content, you should see that some files have been added.

Image 1.2

Because of including the — docker option, a Dockerfile (see picture above) is also generated for the project. This file is used to create a custom container in which to run the project.

Now everything is ready, let’s create our function by running the following command in the same path:

func new

Now, you should see something like the following output:

Image 1.3

Here, you will have to choose a template first, then write your function’s name and that’s all, your function is created!

For this tutorial, I picked option no. 2 which is an Http Trigger template.

NOTE: If you are on Windows, the output and selection method might be slightly different.

Before going further, let’s take a second to see what did the template create for us.

Image 1.4

By default, the template creates a function that requires a function key when making requests. To make it easier to test the function, you need to update the function to allow anonymous access. The way that you make this change depends on your functions project language.

In this case, we are using C#. So what we need to do, is to change AuthorizationLevel from Function to Anonymous. It should look like this:

Image 1.5

If you chose another language, the implementation might be different but the concept is the same, you must change AuthorizationLevel to Anonymous.

Now you can call the function without having to supply the function key. Note that the function key is never required when running locally, but it will be if you try to run it, for example, in a Docker Container.

We have already seen that the template creates a default function but, if you want to code your own function, you can do it by just modifying the <functionName>.cs file (mine is HttpTriggerExample.cs).

I’ve coded a Fortune Cookie program. You can check this repository to follow my example or even clone it if you want to. I’d suggest you to code your own function to have a better overview of what you’ve done.

When your function is ready, head once again over the command-line and write:

docker build -t <imageName> .

Don’t forget to replace <imageName> with the name you want to give to your image.

The output should be something like this:

Image 2.1

You can verify that everything went ok by running this command

docker images

and checking that the image you’ve just built is there, as shown in the picture below.

Image 2.2

We are almost over! Now, all we have to do is to run the image we’ve just created. To achieve this, we have to run the following command:

docker run  -p <port> <imageName>

Here’s an example of how should it look like:

Image 2.3

And that’s all. With the custom image running in a local Docker container, verify the function app and container are functioning correctly by browsing to http://localhost:8080 (or localhost:<port> if you chose any other port). If everything went fine, you should see this screen:

Image 3.1

Lastly, if you followed my example, you can test your function in the local container using the following URL:

http://localhost:8080/api/httptriggerexample?name=Derek

NOTE: You may have to change the port, image name, or path-params depending on your past decisions.

Here’s a screenshot of my function running in the container:

Image 3.2

And that’s all. I really hope you enjoyed this tutorial and had fun while learning something new just like I did.

Thanks for reading and have a nice day.

Reminder: Here is the example I worked with while writing this tutorial.

--

--