Scott Hanselman

Running and F# with FAKE in Azure Web Apps with Git and the Deploy Button

April 27, 2015 Comment on this post [9] Posted in Azure | Open Source
Sponsored By

I was told by some lovely folks in the F# community that there is a nice web framework called Best name ever, eh? Suave is a clean, lightweight, and very F#y (pronounced F-Sharp-ie, I say) in its syntax.

Frameworks like this do well when they are easy to deploy, especially for Hello World. I always find that if a framework can quickly and easily give me a sense of accomplishment I'll be more likely to stick with it. I like to "fall into the pit of success."

I wanted to see if I could make Suave on Azure work easily as well. With the help of Steffen Forkman and the encouragement of the F# community (who have felt historically that support for F# in Visual Studio and Azure has been lacking) I put this little proof of concept together. I used the HttpPlatformHandler that is available in Azure Web Apps now by default, along with a basic Kudu Deployment Script from my Ruby/Middleman post.

Most of the F# community uses a NuGet alternative called Paket that is more F#-friendly. There's also a tiny Paket.Bootstrapper so I could curl things down, then run Paket like this, as part of an Azure Web App deployment. This script modified from Steffen:

@echo off

mkdir .paket
REM TODO - might want to do an IF EXISTS *or* a SHA check
curl -L --insecure -o .paket\paket.bootstrapper.exe

.paket\paket.bootstrapper.exe prerelease
if errorlevel 1 (
exit /b %errorlevel%

.paket\paket.exe restore
if errorlevel 1 (
exit /b %errorlevel%

Then we need web.config to tell Azure Web Apps (IIS8+) to start FAKE to get F# and Suave going. Note the use of %HOME%, full paths and the %HTTP_PLATFORM_PORT%:

<?xml version="1.0" encoding="UTF-8"?>
<remove name="httpplatformhandler" />
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
<httpPlatform stdoutLogEnabled="false" stdoutLogFile="fake.log" startupTimeLimit="20" processPath="%HOME%\site\wwwroot\packages\FAKE\tools\FAKE.exe"
arguments="%HOME%\site\wwwroot\build.fsx port=%HTTP_PLATFORM_PORT%">
<environmentVariable name="WhateverYouLike" value="GoesHere"/>

I added logging but it's off by default. You can use it to debug if you have issues, as the FAKE.exe output will go into a series of log files. You can then access them with the Kudu debug console.

I like running "azure site log tail YOURSITE" with the Azure Cross Platform command line. It lets me see the deployment and output as it happens.

FAKE and F# in Azure Web Apps

Here is Steffen's build.fsx:

// --------------------------------------------------------------------------------------
// FAKE build script
// --------------------------------------------------------------------------------------

#r @"packages/FAKE/tools/FakeLib.dll"

open System
open System.IO
open Fake

Environment.CurrentDirectory <- __SOURCE_DIRECTORY__

// Step 2. Use the packages

#r "packages/Suave/lib/net40/Suave.dll"

open Suave // always open suave
open Suave.Http.Successful // for OK-result
open Suave.Web // for config
open Suave.Types
open System.Net

let port = Sockets.Port.Parse <| getBuildParamOrDefault "port" "8083"

let serverConfig =
{ defaultConfig with
bindings = [ HTTP IPAddress.Loopback port ]

startWebServer serverConfig (OK "Hello World! It's on Azure Websites. <a href=''>So easy to setup. Just click Deploy.</a>")

I just added the Azure Deploy button to my like this. This is markdown, of course, but could be HTML

[![Deploy to Azure](](

And you can try this yourself by visiting the repository here and pressing Deploy to Azure, or hit it here:

Hopefully this is a decent clear start towards easily deploying F# Web Apps to Azure via Git, and/or the Deploy Button.

Your thoughts?

Sponsor: Big thanks to the folks over at Grape City for sponsoring the feed this week. GrapeCity provides amazing development tools to enhance and extend application functionality. Whether it is .NET, HTML5/JavaScript, Reporting or Spreadsheets, they’ve got you covered. Download your free trial of ComponentOne Studio, ActiveReports, Spread and Wijmo.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
April 27, 2015 21:36
This is pretty amazing, thanks for the write up.

I looked at Azure websites a few days back, discovered "httpPlatformHandler" and I thought that would be a nice way to do it, but I had no idea how to actually make it work... So thanks a lot for putting the sample together. It is a super useful starting point that the F# folks can start from to build some amazing & fun things :-)

I might have more thoughts later, but for now, it's just big thanks!
April 28, 2015 13:56
Thanks for this Scott!
April 28, 2015 18:11
I do believe Suave needs an anti-CSRF mechanism. There seems to be an open issue about a CORS and CSRF combinator requirement. I wouldn't know how to do such a thing. Maybe a qualified person reading this could contribute?
April 28, 2015 22:15
Now I only need to learn F# syntax :-)
April 29, 2015 5:02
Wow. This is pretty impressive. I'm not much on F# to be honest, but I really like how you integrated this in with Azure. Great information and well done. I like the polish you put into the solution...
April 29, 2015 10:37
This is great! May I suggest a Hanselminutes episode on the subject?
April 30, 2015 18:27
Wow, this is really awesome. Because I'm more familiar with OWIN I tried creating a Web App from a self-hosted OWIN app. Unfortunately it's not allowed to open the assigned port (see for more details). Any ideas?
May 08, 2015 20:26
To put a little more meat on these bones, I'm attempting a merge of this project with Jon Canning's Todo Backend. The franken-repo is here:

Unfortunately I'm bumping into unresolved FSharp.Targets issues so I may have to start again from scratch.

As a proof-of-concept I did manage to add the deploy button to this MVC repo without a hitch:

[sorry struggling with the a@href markup, or maybe a buggy preview block.]
May 23, 2015 21:50
@Andrew Webb:

I've written a Hawk library for Suave which takes care of CSRF (and replay attacks) for you -- that's what we're using at Logibit. All our apps expose an API and JavaScript calls that API with Hawk.Browser.

We'd love to get contributors for the CSRF-feature. Try your wings! =)


Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.