8

I have a Web API service that I'm deploying to my various environments (using Octopus Deploy). It is supposed to do various tasks on startup, e.g. run any migration scripts required by Entity Framework Code First, and some background tasks managed by Hangfire. Trouble is, the web site only wakes up the first time someone makes a call to it. I want it to run as soon as I've deployed it. I could do it manually just by pointing a web browser at the API's home page, but that requires me to remember to do that, and if I'm deploying to multiple tentacles, that's a major PITA.

How can I force the web site to start up automatically, right after it's been deployed?

Shaul Behr
  • 33,989
  • 61
  • 233
  • 360

4 Answers4

13

In the control panel under turn windows features on or off, Under "Web Server (IIS) | Web Server | Application Development", select "Application Initialization".

In IIS, on the advanced settings for the Application Pool, "Start Mode" should be set to "AlwaysRunning".

In IIS, on the advanced settings for the site, "Preload Enabled" should be set to "true".

A new deployment will cause it to start again (possibly after a short delay).

Shaul Behr
  • 33,989
  • 61
  • 233
  • 360
Daniel
  • 721
  • 1
  • 4
  • 9
8

You can use the Application Initialization Module for this, as many answers have mentioned, but there are a couple of benefits to dropping in a PowerShell step to your deployment...

  1. It can warm up your site
  2. It can act like a very basic smoke test
  3. If it fails, the deployment is marked as failed in Octopus

I use this PowerShell script to warm up and check websites after deployment.

Write-Output "Starting"

If (![string]::IsNullOrWhiteSpace($TestUrl)) {
    Write-Output "Making request to $TestUrl"

    $stopwatch = [Diagnostics.Stopwatch]::StartNew()
    $response = Invoke-WebRequest -UseBasicParsing $TestUrl -MaximumRedirection 0
    $stopwatch.Stop()

    $statusCode = [int]$response.StatusCode

    If ($statusCode -ge 200 -And $statusCode -lt 400) { 
        Write-Output "$statusCode Warmed Up Site $TestUrl in $($stopwatch.ElapsedMilliseconds)s ms"

        $stopwatch = [Diagnostics.Stopwatch]::StartNew()
        $response = Invoke-WebRequest -UseBasicParsing $TestUrl -MaximumRedirection 0
        $stopwatch.Stop()

        $statusCode = [int]$response.StatusCode
        Write-Output "$statusCode Second request took $($stopwatch.ElapsedMilliseconds)s ms"
    } Else {
        throw "Warm up failed for " + $TestUrl
    }
} Else {
    Write-Output "No TestUrl configured for this machine."
}

Write-Output "Done"
Fenton
  • 206,497
  • 63
  • 356
  • 369
1

Use a powershell script to make a call to localhost or the specific machine being deployed to post deploy. The other option would to use the Application Initialization Module.

brianfeucht
  • 734
  • 8
  • 20
0

You will need to perform following steps -

  1. Enable automatic start-up for Windows Process Activation (WAS) and World Wide Web Publishing (W3SVC) services (enabled by default).

  2. Configure Automatic Startup for an Application pool (enabled by default).

  3. Enable Always Running Mode for Application pool and configure Auto-start feature

For step3, you’ll need a special class that implements the IProcessHostPreloadClient interface. It will be called automatically by Windows Process Activation service during its start-up and after each Application pool recycle.

public class ApplicationPreload : System.Web.Hosting.IProcessHostPreloadClient
{
    public void Preload(string[] parameters)
    {
        //Write code here to kick off the things at startup.
    }
}

Complete process in detail is documented here on Hangfire. http://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html

Yogi
  • 7,598
  • 2
  • 39
  • 56