Scott Hanselman

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

April 27, '15 Comments [11] 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 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.

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 = [ 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.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Monday, 27 April 2015 17:36:12 UTC
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!
Tuesday, 28 April 2015 09:56:28 UTC
Thanks for this Scott!
Chris Keenan
Tuesday, 28 April 2015 14:11:14 UTC
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?
Andrew Webb
Tuesday, 28 April 2015 18:15:19 UTC
Now I only need to learn F# syntax :-)
Arthur
Wednesday, 29 April 2015 01:02:40 UTC
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...
Wednesday, 29 April 2015 06:37:10 UTC
This is great! May I suggest a Hanselminutes episode on the subject?
Thursday, 30 April 2015 14:27:07 UTC
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 http://stackoverflow.com/questions/29936226/run-self-hosted-owin-application-in-azure-web-apps for more details). Any ideas?
Johannes Egger
Wednesday, 06 May 2015 02:27:53 UTC
It means this package price flavored balsamic vinegar for you.
It restores your nervous system or blood pumps can choose an alternative
to male enhacement pill affects the male reproductive system.
Bioperine helps in improving size of the best pharmacy so far.

If you take false proportioning.
Friday, 08 May 2015 16:26:57 UTC
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: https://github.com/simra/suavebootstrapper

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.]
Rob
Friday, 15 May 2015 00:04:37 UTC
Do you think these would operate with butternut squash alternatively of the sweet potato?
Saturday, 23 May 2015 17:50:48 UTC
@Andrew Webb:

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.

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