Serving a small static Site from Azure Functions

This is something I keep reinventing from scratch, and that I thought was worthy of posting a note about given that the Functions runtime is now in v4 and function proxies are deprecated (even though you can enable them again).

To be perfectly candid, it bugs me a lot that a small function app doesn’t have the bare minimum to serve up one HTML file and a handful of bundled resources by itself instead of having to resort to Azure CDN or a storage account, which just add to the amount of moving parts and add far too much complexity for small things.

So here’s what I did today while building a small PoC app:

  1. Set AzureWebJobsDisableHomepage: true in settings.json

  2. Created an index function with these bindings in function.json, so it has effectively no route and spits out binary data:

# These are shorthand for the JSON entries
bindings[0].route: "{default:maxlength(0)?}"
bindings[0].dataType: "binary"
  1. Created a static function that responds to bindings[0].route: "static/{*file}", with the same dataType.

  2. Set extensions.http.routePrefix: "" in host.json to remove the /api prefix.

  3. Fished out an old function I had that essentially uses fs and mime-types to send out a context.res.body: fs.readFileSync(file, null) after sorting out the full path and the content-type, and added that to both index and static.

Bam, you can now serve index.html and static assets that get deployed with your functions.

I then carried on to write the rest mostly unhindered, although it was and I keep forgetting to await some of the APIs I’m calling.

The gist of things is that I’m only doing this in this way because , for all its foibles, is still relatively quick to iterate upon.

Actually, let me rephrase that. is actually much slower than to iterate on for API development due to things not failing and spitting out undefined all over the place, but I just can’t get the confusingly named v2 programming model of the v4 Azure Functions runtime to work for me, and I really wanted to do this test I just did.

Also, my usual default of building a container and deploying it would be overkill for this scenario.

A Note On This Note

Something that saddens me a bit is that I am really losing faith in Azure Functions as a “rapid” programming model because every time I go back to it after a while everything I had done needs updating (editor extensions, runtime, code, dependencies, ways to configure basic settings, the works).

It’s just easier to go build and slap a binary behind caddy, or pack it into an ersatz container and push it to an Azure Container Instance. I can even pack all my static assets into the binary1.

Which is what I will probably be doing from now on for prototypes2, as long as they don’t involve too much JSON handling (which is still easier to do in dynamic languages).


  1. And I know the thing will work and be easily maintainable for several years, simply because it has much fewer moving parts. ↩︎

  2. Before you ask, I don’t use piku at work because it’s not sanctioned (as in I never bothered to ask, but perhaps I should). ↩︎

This page is referenced in: