With Azure Functions, you don’t need to care how to run your serverless functions. But what to do, if you want to care and run it by yourself? This post describes how to run your Azure Functions application on own infrastructure with Docker.
Introduction to Azure Functions
Azure Functions provide easy way how to run serverless functions (small pieces of code) in Azure. You can run your C#/Javascript/F#/Java/Python function with HTTP/DB/queue/file trigger integration. Sample Function:
[FunctionName("Function2")]
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "ping/")]HttpRequestMessage req,
ILogger log
)
{
log.LogInformation("Function 2 - I am OK!");
return req.CreateResponse(HttpStatusCode.OK, "pong");
}
Dev environment
Microsoft created nice cross-platform environment for developers. You are able to develop and debug Azure Functions on Windows/Linux/Mac with Visual Studio (Code).
For testing and debugging you can use Azure Functions Core Tools
(func.exe/func).
To install AFCT via npm use command:
npm i -g azure-functions-core-tools --unsafe-perm true
But this dev environment requires connection strings to Azure Storage for writing metadata about functions (locks, timers or even log outputs from functions) – variables AzureWebJobsStorage and AzureWebJobsDashboard in local.settings.json file.
You have two options:
- Azure Storage Emulator – service, which emulates Azure’s Storage API (usually is installed with Azure SDK) and can be installed on any Windows computer.
In that case use for both variables value:"UseDevelopmentStorage=true"
++ no costs
−− dependency on Windows, stability (especially for concurrent clients) - Azure Storage – straightforward solution: just create another Storage in Azure and use it for development.
++ easy configuration, same behavior as production
−− you have to be online with connection to Azure to run and debug your function
Microsoft’s (production) runtime environment
For production Azure Functions apps Microsoft created more runtime environments. When you deploy your Function to Azure, you can choose between Windows and Linux runtime. Both runtime are available as Docker container image on GitHub.
But they have same issue as dev environment – they needs connection strings to Azure Storage for writing metadata about functions (locks, timers or even log outputs from functions) – variables AzureWebJobsStorage and AzureWebJobsDashboard in local.settings.json file.
So how can I run production server on own infrastructure totally without connection to Azure?Answer: You can’t, at least for now.
Depedency to Azure Storage is too much strong at the moment.
Introducing Vasek’s AF Host Docker image
But you can get close to that. For this purpose I created my custom runtime Docker image for Azure Functions applications – to have better experience with applications deployed on own infrastructure.
This image is based on Microsoft’s official docker runtime image, but with some modifications – e.g. redirected logs to console, exit code for Docker,…
So result is, that for runtime you need only Azure Storage Account for metadata (AzureWebJobsStorage).
Installation
Easy – instead of official docker image use for runtime my image vjirovsky/vaseks-af-host:{runtimelanguage}-{version}
FROM vjirovsky/vaseks-af-host:dotnet-2.0
Sample project based on Vasek’s AF Host image
FROM microsoft/dotnet:2.1-sdk AS installer-env
COPY src/ /src/
RUN cd /src/SampleFunctionApp && \
mkdir -p /home/site/wwwroot && \
dotnet publish *.csproj --output /home/site/wwwroot
FROM vjirovsky/vaseks-af-host:dotnet-2.0
ENV AzureWebJobsStorage="---YOUR-STORAGE_CONNECTION_STRING---"
COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]
You can find out sample project on GitHub.
Sample run (of app sample-app)
docker run -p 8080:80 -it sample-app:latest


Source code
Source code of Vasek’s Azure Functions Host runtime is available on GitHub.
Removing dependency on Azure totally
I have ideas how to remove this dependency, but it’s a lot of work – so reach me out please, to know how many people would use it.
Would totally take advantage of independency from Azure Storage