Hosting your Static Website inside Azure Functions
Image by https://undraw.co/

Hosting your Static Website inside Azure Functions

Azure Functions

Summary:

Azure Storage now supports static website hosting which ease the hosting of Single Page Application (SPA) applications. That approach has multiple shortcomings:

  1. No support HTTPS with a custom domain
  2. No support for naked domain name
  3. No support for multiple custom domain names

Using Azure Functions as a proxy for the Azure Storage static website will enable these scenarios.

TLDR: Check the sample on GitHub.

 Ingredients:

 Directions:

⏲️ Preparation👨‍🍳 Ready In
15 minutes30 minutes
  1. Create a new Azure Functions app:
    1. In Visual Studio, select New > Project from the File menu.
    2. In the New Project dialog, select Installed, expand Visual C# > Cloud, select Azure Functions, use "StaticWebsiteProxy" for the Name of your project, and click OK
      Create a New Azure Functions Project
      Create a New Azure Functions Project
    3. In the following dialog, select Azure Functions v2 (.NET Core) and the Empty function. Press OK.
      Select an Empty Function
      Select an Empty Function
  2. Add new file inside the project, by right clicking on the project in the Solution Explorer and going to Add > New Item...
    Add New Proxy File
    Add New Proxy File
  3. Edit project launch settings, by right clicking on the project in the Solution Explorer and going to Properties.
    Change Application Arguments
    Change Application Arguments
  4. Add the following Application Arguments : 
    host start --pause-on-error
  5. In the Add New Item dialog, select Installed, expand Visual C# Items, select Javascript JSON Configuration File, use "proxies.json" for the Name of your file, and click Add
    Create New Proxies.json File
    Create New Proxies.json File
  6. Open the newly added proxies.json file and overwrite the content with the following and save the file.
    {
      "$schema": "http://json.schemastore.org/proxies",
      "proxies": {
        "all": {
          "debug":false,
          "disabled":false,
          "matchCondition": {
            "methods": [ "GET", "POST", "HEAD", "OPTIONS", "PUT", "TRACE", "DELETE", "PATCH", "CONNECT" ],
            "route": "/{*all}"
          },
          "backendUri": "http://%STORAGE_HOST%/{all}",
          "requestOverrides": {
          },
          "responseOverrides": {
            "response.headers.FUNCTION-PROXY": "true"
          }
        }
      }
    }
    
    1. Notes
      1. %STORAGE_HOST% will be taken from the Application Settings.
      2. The response header FUNCTION-PROXY is only added to confirm that the response properly went through the proxy. It can be removed in your own project.
  7. Open the host.json file and overwrite the content with the following and save the file.
    {
      "version": "2.0",
      "extensions": {
        "http": {
          "routePrefix": "",
          "maxOutstandingRequests": 200,
          "maxConcurrentRequests": 100,
          "dynamicThrottlesEnabled": true
        }
      }  
    }
  8. Open the local.settings.json file and overwrite the content with the following and save the file.
    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsDisableHomepage": "True",
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "STORAGE_HOST": "www.luckenuik.net",
        "APPINSIGHTS_INSTRUMENTATIONKEY": ""
      },
      "Host": {
        "LocalHttpPort": 7073,
        "CORS": "*"
      }
    }
    
    1. STORAGE_HOST is currently using www.luckenuik.net but should be replaced by the host name of an Azure Storage account with static website hosting enabled with file deployed in the $web container.
  9. Go in the Solution Explorer, select the proxies.json file and change the Copy to Output Directory action to Copy if newer.
    Copy to Output Directory set to Copy if newer
    Copy to Output Directory set to Copy if newer
  10. Start your Azure Function application by pressing F5. If you are running Azure Functions for the first time, the following dialogs might appear:
    1. Azure Functions CLI tools download dialog, wait for the download to complete, this is mandatory to run your app.
      Downloading Azure Functions CLI Tools
      Downloading Azure Functions CLI Tools
    2. Windows Security Alert dialog. Check both "Private networks" and "Public networks" and press "Allow Access".
      Windows Security Alert
      Windows Security Alert
  11. To see your Razor Pages hosted in Azure Functions, navigate your browser to: http://localhost:7073
  12. Make sure the application works as expected and then stop it.
  13. The application will now be manually published to a new Azure Functions App hosted on Azure.
  14. In order to publish the newly created web site, right-click on the project name in the Solution Explorer and select "Publish": 
    Configuration Publication
    Configuration Publication
  15. From the "Pick a publish target" dialog, select "Create New" and check "Run from package file". Press Publish.
    Publication Settings
    Publication Settings
  16. Select your Function App name and create a new Resource Group, a new Hosting Plan and a new Storage Account. Press Create and wait for resource to be created.
    Create App Service
    Create App Service
  17. Once the resources have been created, the publish will start.
    Publishing Function
    Publishing Function
    1. If you get the following dialog, simply press Yes.
      Update Functions Version on Azure
      Update Functions Version on Azure
  18. Make sure that local Application Settings are properly propagated to the cloud.
    1. Check deployment application settings by clicking Manage Application Settings in th Publish screen.
      Configure Application Settings For Publication
      Configure Application Settings For Publication
    2. Press Insert value from local for all settings that were added to the local.settings.json file and were not published to the cloud.
      Validate Remote Application Settings
      Validate Remote Application Settings
  19. Click on the Site URL and browse your newly deployed Function. 
    1. If you encounter any error, configure Application Insights to see the logs of the Function. Make sure you added the APPINSIGHTS_INSTRUMENTATIONKEY key into the local.settings.json. Configure your publish application settings with the Application Insights instrumentation key and configure the Remote value with the value from the newly created Application Insights.
      Configure Application Settings For Publication
      Configure Application Settings For Publication
      Configure Application Insights Instrumentation Key
      Configure Application Insights Instrumentation Key
    2. Publish your application again and start troubleshooting.


 References:

 

Comments