Last week I spent a lot of time trying to deploy an F# ASP.NET Core app (a Giraffe app, specifically) to Azure because the information to complete all the steps was scattered in several places. So I'm writing this hopefully it will save the pain to others :)
The following steps are mostly taken from this guide and it's only necessary to do them once:
- Create an account in Azure (or use an existing one)
- Create a resource group (or use an existing one)
- Create an app service plan (not sure if you can reuse an existing plan, we'll be using a free plan here)
- Create a webapp with a given name, linked to the plan and resource group
- Assign a username and a password for deployment
- Get the URL for git deployment
- Add a
web.config
to your app
The first 4 steps can be done using the Azure portal (in which case 3 and 4 are combined) or using the Azure CLI according to the guide:
resourcegroup=<Replace with desired resource group name>
webappname=<Replace with desired web app name>
# Create a resource group.
az group create --location westeurope --name $resourcegroup
# Create an App Service plan in FREE tier.
az appservice plan create --name $webappname --resource-group $resourcegroup --sku FREE
# Create a web app.
az webapp create --name $webappname --resource-group $resourcegroup --plan $webappname
The next 2 steps I only managed to do using the Azure CLI:
username=<Replace with desired deployment username>
password=<Replace with desired deployment password>
# Set the account-level deployment credentials
az webapp deployment user set --user-name $username --password $password
# Configure local Git and get deployment URL
az webapp deployment source config-local-git --name $webappname --resource-group $resourcegroup --query url
Write down the URL. The last step for the preparation is to add a web.config
file to your app. This may be obvious for ASP.NET developers, but it took me a couple of hours until I found this issue and realized I was missing it. Create a web.config
file next to the .fsproj
with contents similar to the following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments="Server.dll" stdoutLogEnabled="false" stdoutLogFile="logs/stdout" />
</system.webServer>
</configuration>
ATTENTION: Note you may have to change
Server.dll
to match the name of your app assembly.
And make sure your .fsproj
contains a tag like the following within ItemGroup
:
<None Include="web.config" CopyToOutputDirectory="PreserveNewest" />
Now we are ready to deploy our app! When using GIT for deployment, the guides I have found suggest to commit your repo as is and let Azure build the app for you app. However we won't do that for two reasons: firstly I couldn't manage to make it work (maybe because F#?), and secondly your build script may include other steps besides building the ASP.NET Core project (in my case, compiling a Fable app for frontend, for example) and I don't know how to tell Azure to run those. Because of this, we are going to create an ad hoc repo for every deployment just to push the .NET assemblies and other files we may need. Find below the script I'm using for this (it's bash but the commands can be easily addapted to your build process):
GITURL=<Replace with the URL you wrote down before>
rm -rf deploy
dotnet publish -c Release src/Server -o ../../deploy
# Do here other build steps like running `yarn build`
# to put your minified frontend files in /deploy/public
pushd deploy
git init
git remote add origin $GITURL
git add -A
git commit -m "Update app"
git push origin master
popd
I hope this is useful to you and saves you time :) If you spot any mistake please comment below or send a PR (can you send PRs to gists?).
I just learned that it's possible to deploy by simply pushing a zip file. This may be more convenient in our case because we are deploying binary files that are ready to use, which means we don't need source control nor Kudu performing builds (in fact, I learned about this way because Kudu started to mess around with my deployments using git). For this we only need to edit the script above in the following way:
USER=<username>
APPNAME=<appname>
ZIPURL=https://$USER@$APPNAME.scm.azurewebsites.net/api/zipdeploy
rm -rf deploy
dotnet publish -c Release src/Server -o ../../deploy
# Do here other build steps
pushd deploy
zip -r deploy.zip .
curl -X POST -u $USER --data-binary @deploy.zip $ZIPURL
popd
Note the format of the URL, it should be the same as the previous GIT url except for the zipdeploy
part. The only inconvenience of this script is you have to type the password every time. If you have it in an environmental variable (say PASS
) you can change the curl
command to:
curl -X POST -u $USER:$PASS --data-binary @deploy.zip $ZIPURL
This info was a lifesaver for me. Thanks! One note that might help Windows users: zip isn't 'a thing' on Windows. I ended up using this line in my bash script:
...as I had 7zip installed.