Hosting Static Websites in Azure Blob Storage with Azure Functions Proxies
In serverless architectures, it’s common to build your website as a SPA, meaning that you only need static website hosting. A common choice for this is Amazon S3, but if you have an Azure subscription, you may be wondering if you can use Azure Blob Storage instead.
Well, if you create a Blob Storage Account, and make a container and set it’s blobs to be publicly accessible, then you can navigate to your site by visiting a URL like: https://mystorageaccount.blob.core.windows.net/mycontainer/index.html
And this works just fine, but there are a few key limitations you need to be aware of.
First of all, although you can point a custom domain at an Azure Blob Storage account, you can’t upload your own SSL certificate. This is the top requested feature for Azure Blob Storage, and Microsoft’s response indicates they do intend to resolve this as a high priority.
Second of all, we’d rather not need to specify index.html explicitly, but Azure Blob storage doesn’t have default document support. This is another highly requested feature and so hopefully Microsoft will also address this soon, along with removing the need to specify the container name in the URL.
And there are a few other features that are desirable for a static website host, such as the ability to serve a custom 404 page.
So in its current state, Azure Blob Storage isn’t ideal for hosting a static website.
Fortunately, there is now a workaround available in the shape of Azure Functions proxies. What you can do is create an Function App and give it a proxy that passes on requests to Blob Storage.
Let’s see how to do that. In our function app, because it’s still in preview, we need to explicitly enable proxies:
And I’ll create two proxies. The first, will redirect the base URL to the index.html
in my static hosting blob container:
And the second will forward every additional request for any other path directly to the blob container. That’s achieved with the special {*restOfPath}
syntax which matches any path.
With that in place, I now can directly access my static website by visiting the URL of the function app.
What’s more, Azure Function apps support custom domains, so I can go in and configure some domain name I own to point at the function app.
Azure Function Apps also allow you to upload SSL certificates, so as well as solving the default document issue, and removing the need for the container name in the path, this also is a way to use HTTPS on custom domains. So with Azure Functions proxies you can work around most of the major limitations of static hosting on Azure Blob Storage.
Obviously you will pay for a function execution for each file that’s requested, but remember that you get 1 million free function executions a month, so you may not end up paying anything for most websites.
Comments
worked a treat!
Maringa ManguyuYou are a legend (among cheapskates like me)
rorz0rGood stuff.. thank you!! just to point for others out its {*restOfPath} (with asterisk) in the Route Template and {restOfPath} (w/o asterisk) in the Backend Url. I glanced over that difference and used {*restOfPath} for both and wasted a few cycles wondering why I was getting "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable"
Wayne MasseyHi, great read. Do you have a sugestion to implement a custom 404? now I get a blognotfound returned from my blog storage. Like to handle that to my custom <blob>/404.html
Ronald Nieuwenhuisthe good news is that at BUILD they showed a feature for custom default and 404 pages in blob storage. It think might still be in preview/beta, but this is something we're very close to now
Mark HeathDo you have any thoughts on benefits / trade-offs of using an Azure Function Proxy vs an Azure CDN now that hosting static websites on Azure storage is generally available?
Daniel O'Brienhttps://azure.microsoft.com/en-us/blog/static-websites-on-azure-storage-now-generally-available/
I've not tried that yet, but it's probably a better solution for a real-world website. The proxies approach I show here is OK, but can suffer from cold-start issues which might be an issue with some websites.
Mark HeathJust to be clear - the Static Website feature just buys you the default document and 404 redirect. You still need an Azure Function Proxy or Azure CDN to get SSL with a custom domain. So just curious if you recommend one over the other.
Daniel O'BrienWith function proxies, its a nice simple, self-contained solution, but with the down-side of potential cold start issues. With the CDN, you're possibly paying a bit more, but you've presumably got faster performance especially if your website visitors are worldwide. So it's a tradeoff you need to choose based on your website requirements.
Mark HeathGot it - thanks for the information! Very helpful blog post and am enjoying your PluralSight courses!
Daniel O'BrienI have implemented a ReactJS site hosted using the method above and we can get the site to be served via the proxy. The issue we have is we are using OAuth Authentication and the URL Redirect for OAuth provider adds a "/redirect" route to our path. What seems to be happening is that the "/redirect" path is being interpreted as a blob path and we get "Blob not found" has anyone run into this and/or a resolution?
Karim KamekaI solved it by adding error page as index.html in the static website section. Are you still facing this issue
Chandan BCool! Can you please elaborate on what type of Azure storage account we need for this? (General purpose v1, v2, ....)?
Olivereither is fine
Mark Heath