How to solve the "listen tcp :80: bind: permission denied" error in Docker
We’ve all been there. You do everything correct - you set your container to run as non …
This post will walk you through the key things you should know when running a 64 bit node application in Azure App Service for Windows. HUGE shoutout to Marie Hoeger from Microsoft for helping provide official guidance for this.
First, I do want to point out the obvious - you may not actually need 64 bit (x64) support for your web app. Scott Hanselman has a great post on showing you the memory consumption differences between x86 (32 bit) and x64 here. Now, his post is about 5 years old and things have changed in technology, though the heart of his post is probably right - you may not actually need x64 support within your Windows web app and I encourage you to weigh the pros/cons to see if you actually need it. If so, this post will walk you through the official way to wire everything up.
I have a web app that truly does require x64 support because one of the package dependencies is Lovell’s Sharp, which is a high performance image processesing module. Perhaps you have experience with this same module after following Chris Tjoumas’ blog walk through, “Creating a Ghost Blog on Azure App Service”, which uses a neat project from Yannick Reekmans - only, I discovered it doesn’t work quite right without x64 support. In fact, even this blog - which is based on the popular Ghost blogging platform - uses it by default, and my custom Ghost Azure Storage Adapter also uses it. I don’t beleive Sharp has supported x86 in quite some time (since 0.11.4 as is noted in this GitHub issue), but I never noticed it until someone reached out and asked for help with my storage adapter in, specifically, Windows App Service.
There are few posts online you can find that will walk you through hacks of how to get things to work, but I reached out to the product group to get the official answer.
There are 3 main configurations you need for x64 Windows App Service support:
WEBSITE_NODE_DEFAULT_VERSION
== ~10
.
Note: The tilde is not a typo and needs to be there.Once you have these configurations applied, you should be able to support x64 bit architecture. In fact, you can test your settings by using Kudu. Try this - log into your Azure Portal, navigating to your web app, scrolling down to Console (under Development Tools) on the left hand side. Within console type, node -p "process.arch"
. Assuming you performed the 2.5 steps above, you should now see x64
returned.
You could even do an additional check and type where node
to see both Program Files (x86) and (Program Files) ((for x64)) listed.
Note: If you had an app that was previously configured with some workarounds, clear them up, and redeploy using the new settings - any 500 errors should be resolved.
Now, because I’m a huge fan of #noclickyclicky I setup an ARM template to create everything for me; this includes the app service plan and the web app with full x64 support. You can do this in an ARM template by setting the following two properties:
siteProperties
- specifically the "use32BitWorkerProcess": false,
property, which will tell your App Service Config to use x64 instead. If you’re curious, Azure Docs does have a good template reference I used to get the following settings here."siteProperties": {
"netFrameworkVersion": "v4.7",
"use32BitWorkerProcess": false,
"httpsonly": true,
"webSocketsEnabled": true,
"alwaysOn": true,
"requestTracingEnabled": true,
"httpLoggingEnabled": true,
"logsDirectorySizeLimit": 40,
"detailedErrorLoggingEnabled": true,
"remoteDebuggingEnabled": true
}
You can then call this property by using the web config resource for your Microsoft.web/sites
resource. Here’s the relevant snippet:
{
"apiVersion": "2018-11-01",
"name": "web",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('siteName'))]"
],
"properties": "[variables('siteProperties')]"
},
An example of how you would declare a Microsoft.Web/sites resource with the web config resource can be found here - specifically, line 148, which references siteProperties on lines 83-94.
WEBSITE_NODE_DEFAULT_VERSION
property. The app settings template reference doc is here.{
"name": "appsettings",
"type": "config",
"apiVersion": "2018-11-01",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('siteName'))]",
],
"properties": {
"WEBSITE_NODE_DEFAULT_VERSION": "~10"
}
},
You can see how this is then referenced, in full context, on GitHub here (note line 194) where I set the WEBSITE_NODE_DEFAULT_VERSION app setting.
To test all this out, I forked the repo Chris used in the blog post I mentioned above and updated the one click deployment to stand up a Windows App Service Plan, Windows Web Site (with x64 support), Application Insights, and a storage account. I added my Ghost Azure Storage adapter to the repo and ran a one-click-deploy - it worked! I could tell for sure I was installing x64 node packages by looking at the logs - previously I would see node modules referenceing ia32
support and now I see the expected win32-x64
package architecture.
Or, if you’re like me and you enjoy playing with the command line, you could go back over to your Kudu console and type one of the following commands:
# faster command
cat node_modules/sharp/package.json | grep version
or
# slower command
npm list | grep sharp
At the time of this blog post the latest version of Sharp is 0.25.2, which is exactly what Kudu reports. Excellent.
If you want to give it a try yourself, head on over to my repo and hit the one-click-deploy to Azure button!