Running Suave.io and F# with FAKE in Azure Web Apps with Git and the Deploy Button
I was told by some lovely folks in the F# community that there is a nice web framework called Suave.io. 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
cls
mkdir .paket
REM TODO - might want to do an IF EXISTS *or* a SHA check
curl https://github.com/fsprojects/Paket/releases/download/1.2.0/paket.bootstrapper.exe -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"?>
<configuration>
<system.webServer>
<handlers>
<remove name="httpplatformhandler" />
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<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%">
<environmentVariables>
<environmentVariable name="WhateverYouLike" value="GoesHere"/>
</environmentVariables>
</httpPlatform>
</system.webServer>
</configuration>
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.
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 = [ HttpBinding.mk HTTP IPAddress.Loopback port ]
}
startWebServer serverConfig (OK "Hello World! It's Suave.io on Azure Websites. <a href='https://github.com/shanselman/suavebootstrapper'>So easy to setup. Just click Deploy.</a>")
I just added the Azure Deploy button to my Readme.md like this. This is markdown, of course, but could be HTML
[![Deploy to Azure](http://azuredeploy.net/deploybutton.png)](https://azuredeploy.net/)
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.
About Newsletter
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: https://github.com/KuduApps/WebAppWithFSharpLibrary
[sorry struggling with the a@href markup, or maybe a buggy preview block.]
I've written a Hawk library for Suave which takes care of CSRF (and replay attacks) for you
https://github.com/logibit/logibit.hawk/ -- 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! =)
Henrik
Comments are closed.
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!