Fix React-Redux routing issues with Windows App Services
Create a web.config file with the following structure and make sure it gets deployed in your wwwroot
.
<?xml version="1.0"?>
<configuration>
<location path="index.html">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
</system.webServer>
</location>
<system.webServer>
<staticContent>
<!-- Serve json files -->
<remove fileExtension=".json" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<!-- Serve fonts, too -->
<remove fileExtension=".woff" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
</staticContent>
<rewrite>
<rules>
<rule name="React Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
An alternative web.config
template is here.
Don’t show .html extension for static *.html sites
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RewriteURL" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="{R:1}.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
– via Stack Overflow
Configure Web Apps using rich/nested objects
Aka how do you go from defining a rich configuration section in your appsettings.Development.json
file to configuring it in the web app’s Configuration
blade.
If you’re using Windows web apps, then you just need to use the “:” (colon) character to define nested key structures. If you’re on Linux, then you need to use “__” (double underscore). Arrays are supported in both cases, but you’ll need to manually specify the indexes in the key name i.e. MyConfiguration__ClientEvents__0
or MyConfiguration:ClientEvents:0
.
For example:
{
"MyConfiguration": {
"ClientId": "marco",
"ClientSecret": "polo",
"ClientEvents": [
"SimulationStarted",
"SimulationEnded"
],
}
}
Will be configured in a Linux web app’s Configuration
blade as:
[
{
"name": "MyConfiguration__ClientId",
"value": "marco",
"slotSetting": false
},
{
"name": "MyConfiguration__ClientSecret",
"value": "polo",
"slotSetting": false
},
{
"name": "MyConfiguration__ClientEvents__0",
"value": "SimulationStarted",
"slotSetting": false
},
{
"name": "MyConfiguration__ClientEvents__1",
"value": "SimulationEnded",
"slotSetting": false
}
]
See also the wiki on injecting configuration objects in your services/controllers to see how you can access these values in your code.
– via StackOverflow
Unable to save app service configuration (or anything, really), due to “Deny Public Network Access” policy
Even though you’re using a VNET and have enabled private endpoints.
In my case, I could see that "publicNetworkAccess": null
in the service’s JSON view, which means the public network access is dynamically set based on the networking settings. Guessing the policy doesn’t check for this dynamic setting, I’ve set manually publicNetworkAccess
as Disabled
. Saving the app service configuration worked afterwards 😬.
az webapp config set --name <function_name> --resource-group <resource_group> --generic-configurations '{"publicNetworkAccess":"Disabled"}'
Deploy a SvelteKit app to a Linux plan App Service
Gosh, this was harder than it needed to be. The idea is that, for Node apps, Azure expects a package.json
to exist in wwwroot, otherwise things will not work. Ideally with a "type": "module"
. Maybe also with a "start": "node /home/site/wwwroot/"
script.
Here’s what I did:
- Created a Node-based web app.
- Updated my
package.json
to include a"start": "node /home/site/wwwroot/"
script. Alternatively, in the Azure Portal, set theConfiguration -> General Settings -> Startup command
tonode /home/site/wwwroot/
- Updated my GitHub action to include said
package.json
in mybuild
directory. It would have probably been better to create a new one from scratch, but by the time I got to this step I just wanted things to work.
# Kinda like this:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install deps & Build
run: |
npm install
npm run build
cp ./package.json ./build/
working-directory: myapp-web
- name: Deploy to Azure App Service
uses: azure/webapps-deploy@v2
with:
app-name: '<myapp-name>'
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: './myapp-web/build'
- For some reason, the app will start real slow. So activate
Configuration -> General Settings -> Always On
. - Debug by checking
https://<myapp-name>.scm.azurewebsites.net/
– specifically,Site wwwroot
andhttps://<myapp-name>.scm.azurewebsites.net/api/vfs/LogFiles/"
Some references:
- https://learn.microsoft.com/en-us/azure/app-service/configure-language-nodejs?pivots=platform-windows#run-gruntbowergulp
- https://learn.microsoft.com/en-us/answers/questions/970391/package-json-issue-while-deploying-a-node-api-on-a
- https://gist.github.com/0gust1/1fc3c461ace390df556b2231b7284e70
Swap deployment slots while deploying with GitHub Actions
- name: Azure Login (webapp)
uses: azure/login@v1.1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy to web app
uses: azure/webapps-deploy@v2
with:
app-name: 'xxx'
slot-name: 'xxx'
images: 'xxx'
- name: Health check
uses: jtalk/url-health-check-action@v1.2
with:
url: https://xxx/health
max-attempts: 2
retry-delay: 5s
- name: Azure Swap Slots
uses: azure/CLI@v1
with:
inlineScript: |
az webapp deployment slot swap --slot xxx --name xxx --resource-group xxx
– via Reddit