Friday, 17 March 2017

ASP.NET Core app deployed to Pivotal Cloud Foundry

This post will show you how to write your first ASP.NET Core application on macOS or Linux and push it to Pivotal Cloud Foundry without having to PUBLISH it for deployment.

Before getting started you will need the following

1. Download and install .NET Core
2. Visual Studio Code with the C# extension.
3. CF CLI installed


Note: Assumes your already logged into Pivotal Cloud Foundry and connected to Pivotal Web Services (, the command below shows I am connected and targeted

pasapicella@pas-macbook:~$ cf target
API endpoint:
API version:    2.75.0
Org:            apples-pivotal-org
Space:          development

1. Create new project

pasapicella@pas-macbook:~/pivotal/software/dotnet/dotnet-core-mvc$ dotnet new mvc --auth None --framework netcoreapp1.0
Content generation time: 278.4748 ms
The template "ASP.NET Core Web App" created successfully.

2. Restore as follows

pasapicella@pas-macbook:~/pivotal/software/dotnet/dotnet-core-mvc$ dotnet restore
  Restoring packages for /Users/pasapicella/pivotal/software/dotnet/dotnet-core-mvc/dotnet-core-mvc.csproj...
  Generating MSBuild file /Users/pasapicella/pivotal/software/dotnet/dotnet-core-mvco/obj/dotnet-core-mvc.csproj.nuget.g.props.
  Generating MSBuild file /Users/pasapicella/pivotal/software/dotnet/dotnet-core-mvc/obj/dotnet-core-mvc.csproj.nuget.g.targets.
  Writing lock file to disk. Path: /Users/pasapicella/pivotal/software/dotnet/dotnet-core-mvc/obj/project.assets.json
  Restore completed in 1.09 sec for /Users/pasapicella/pivotal/software/dotnet/dotnet-core-mvc/dotnet-core-mvc.csproj.

  NuGet Config files used:

  Feeds used:

3. At this point we can run the application and see what it looks like in a browser

pasapicella@pas-macbook:~/pivotal/software/dotnet/dotnet-core-mvc$ dotnet run
Hosting environment: Production
Content root path: /Users/pasapicella/pivotal/software/dotnet/dotnet-core-mvc
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

Now to prepare this demo for Pivotal Cloud Foundry we need to make some changes to he generated code as shown in the next few steps

4. In Visual Studio Code, under the menu item “File/Open” select the “dotnet-core-mvc” folder and open it. Confirm all messages from Visual Studio Code.

The .NET Core buildpack configures the app web server automatically so you don’t have to handle this yourself, but you have to prepare your app in a way that allows the buildpack to deliver this information via the command line to your app

5. Open "Program.cs" and modify the Main() method as follows adding "var config = ..." and ".UseConfiguration(config)" as shown below
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

namespace dotnet_core_mvc
    public class Program
        public static void Main(string[] args)
            var config = new ConfigurationBuilder()

            var host = new WebHostBuilder()


6. Open "dotnet-core-mvc.csproj" and add the following dependency "Microsoft.Extensions.Configuration.CommandLine" as shown below
<Project Sdk="Microsoft.NET.Sdk.Web">


    <PackageReference Include="Microsoft.AspNetCore" Version="1.0.4" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.0.3" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.0.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.0.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="1.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.0.1" />


7. File -> Save All

8. Jump back out to a terminal windows, you can actually restore from Visual Studio Code IDE BUT I still like to do it from the command line

pasapicella@pas-macbook:~/pivotal/software/dotnet/dotnet-core-mvc$ dotnet restore

9. Deploy to Pivotal Cloud Foundry as follows, you will need to use a unique name so replace "pas" with your own name that should do it.

$ cf push pas-dotnetcore-mvc-demo -b -m 512m

** Output **

pasapicella@pas-macbook:~/pivotal/software/dotnet/dotnet-core-mvc$ cf push pas-dotnetcore-mvc-demo -b -m 512m
Creating app pas-dotnetcore-mvc-demo in org apples-pivotal-org / space development as

Using route
Binding to pas-dotnetcore-mvc-demo...

Uploading pas-dotnetcore-mvc-demo...
Uploading app files from: /Users/pasapicella/pivotal/software/dotnet/dotnet-core-mvc
Uploading 208.7K, 84 files
Done uploading

Starting app pas-dotnetcore-mvc-demo in org apples-pivotal-org / space development as
Creating container
Successfully created container
Downloading app package...
Downloaded app package (675.5K)
ASP.NET Core buildpack version: 1.0.13
ASP.NET Core buildpack starting compile
-----> Restoring files from buildpack cache
-----> Restoring NuGet packages cache
-----> Extracting libunwind
       libunwind version: 1.2
-----> Installing .NET SDK
       .NET SDK version: 1.0.1
-----> Restoring dependencies with Dotnet CLI

       Welcome to .NET Core!
       The .NET Core tools collect usage data in order to improve your experience. The data is anonymous and does not include command-line arguments. The data is collected by Microsoft and shared with the community.
       You can opt out of telemetry by setting a DOTNET_CLI_TELEMETRY_OPTOUT environment variable to 1 using your favorite shell.
       You can read more about .NET Core tools telemetry @
       A command is running to initially populate your local package cache, to improve restore speed and enable offline access. This command will take up to a minute to complete and will only happen once.
       Decompressing 100% 16050 ms
-----> Buildpack version 1.0.13
       Learn more about .NET Core @ Use dotnet --help to see available commands or go to


       Expanding 100% 13640 ms
         Restoring packages for /tmp/app/dotnet-core-mvc.csproj...
         Installing Microsoft.Extensions.Configuration 1.0.0.
         Installing Microsoft.Extensions.Configuration.CommandLine 1.0.0.
         Generating MSBuild file /tmp/app/obj/dotnet-core-mvc.csproj.nuget.g.props.
         Writing lock file to disk. Path: /tmp/app/obj/project.assets.json
         Restore completed in 2.7 sec for /tmp/app/dotnet-core-mvc.csproj.

         NuGet Config files used:

         Feeds used:

             2 package(s) to /tmp/app/dotnet-core-mvc.csproj
       Detected .NET Core runtime version(s) 1.0.4, 1.1.1 required according to 'dotnet restore'
-----> Installing required .NET Core runtime(s)
       .NET Core runtime 1.0.4 already installed
       .NET Core runtime 1.1.1 already installed
-----> Publishing application using Dotnet CLI
       Microsoft (R) Build Engine version 15.1.548.43366
       Copyright (C) Microsoft Corporation. All rights reserved.

         dotnet-core-mvc -> /tmp/app/bin/Debug/netcoreapp1.0/dotnet-core-mvc.dll
       Copied 38 files from /tmp/app/libunwind to /tmp/cache
-----> Saving to buildpack cache
       Copied 850 files from /tmp/app/.dotnet to /tmp/cache
       Copied 19152 files from /tmp/app/.nuget to /tmp/cache
-----> Cleaning staging area
       Removing /tmp/app/.nuget
ASP.NET Core buildpack is done creating the droplet
Exit status 0
Uploading droplet, build artifacts cache...
Uploading droplet...
Uploaded build artifacts cache (359.9M)
Uploaded droplet (131.7M)
Uploading complete
Successfully destroyed container

0 of 1 instances running, 1 starting
1 of 1 instances running

App started


App pas-dotnetcore-mvc-demo was started using this command `cd .cloudfoundry/dotnet_publish && dotnet dotnet-core-mvc.dll --server.urls${PORT}`

Showing health and status for app pas-dotnetcore-mvc-demo in org apples-pivotal-org / space development as

requested state: started
instances: 1/1
usage: 512M x 1 instances
last uploaded: Fri Mar 17 03:19:51 UTC 2017
stack: cflinuxfs2

     state     since                    cpu    memory          disk           details
#0   running   2017-03-17 02:26:03 PM   0.0%   39.1M of 512M   302.7M of 1G

10. Finally invoke the application using the URL which can be determined by the output at the end of the PUSH above or using "cf apps"

More Information

No comments: