title: ASP.NET Core 2.0 Web App Deployment and Hosting
body: <p><strong>Enviroment</strong></p>
  
  <p>My local dev environment is a Windows 10 PC using Visual Studio 2017.</p>
  
  <p>NOTE: At the moment I can only access my web server via cpanel. However, if the hosting provider cannot provide adequate support for an ASP.NET Core 2.0 app, then I will look at changing to a dedicated server, where I have full access to the server and IIS.</p>
  
  <p><strong>My Requirement/Project</strong></p>
  
  <p>I've been developing an ASP.NET Web Application that targets the .NET Core 2.0 framework, and the app is working fine with localhost and IIS express.</p>
  
  <p>Now that the app is completed, I need to deploy and host, which feels like a daunting task that will add years to my age in a matter of days and weeks.</p>
  
  <p>I've read about users who've waded thru a multitude of articles, blogs, MS docs, stackoverflow etc. trying (often unsuccessfully) to deploy on both Intranet and Internet. Now I feel like publishing and deploying with .net core seems like a total mass of confusion.</p>
  
  <p>My current website was developed by an external party - a Wordpress site using PHP. I want to replace this site with my ASP.NET Core2.0 Web application.</p>
  
  <p>The root of my current site is "httpdocs", where I have some subfolders with image files that I need to reference from other apps. I'm not sure if these can stay as is, or if I need to migrate them to a new folder where the ASP.NET Web app resides.
  I don't have access to the server directly, I can only access via cpanel.</p>
  
  <p>The app requires https, and below I've included my Startup.cs and Program.cs files.</p>
  
  <p>I've outlined the steps and considerations I think are involved in the deployment and hosting. Can anyone who's had previous experience with this please help with my questions, or advise me of anything I've missed or other things that I should address?</p>
  
  <p><strong>Startup.cs</strong></p>
  
  <pre><code>public class Startup
  {
      public Startup(IConfiguration configuration)
      {
          Configuration = configuration;
      }
  
      public IConfiguration Configuration { get; }
  
      // This method gets called by the runtime. Use this method to add services to the container
      public void ConfigureServices(IServiceCollection services)
      {
          try
          {
              services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                  .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =&gt;
                  {
                      options.ExpireTimeSpan = new TimeSpan(90, 0, 0, 0);
                      options.LoginPath = new PathString("/Home/Index/");
                      options.AccessDeniedPath = new PathString("/Home/Index/");
                      options.LogoutPath = new PathString("/Home/Index/");
                      options.Validate();
                  });
  
              services.AddMvc();
              services.AddAntiforgery();
              services.Configure&lt;MvcOptions&gt;(options =&gt;
              {
                  options.Filters.Add(new RequireHttpsAttribute());
              });
          }
          catch (Exception ex)
          {
              gFunc.ProcessError(ex);
          }
      }
  
      // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
  // I've added a StaticFiles option that aims to make a directory called "SamadhiFiles" publically available
  // so that I can use "http://mysite.net.au/samadhifiles/myPic.png
      public void Configure(IApplicationBuilder app, IHostingEnvironment env)
      {
          try
          {
              app.UseMvc();
              app.UseStaticFiles(new StaticFileOptions
              {
                  FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "SamadhiFiles")),
                  RequestPath = "/SamadhiFiles"
              });
              app.UseAuthentication();
  
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
                  app.UseBrowserLink();
                  app.UseStatusCodePages();
              }
              else
              {
                  app.UseExceptionHandler("/Home/Error");
              }
  
      // this code is to enable redirection of http to https
              var options = new RewriteOptions().AddRedirectToHttps();
              app.UseRewriter(options);
  
              app.UseMvc(routes =&gt;
              {
                  routes.MapRoute(
                      name: "default",
                      template: "{controller=Home}/{action=Index}/{id?}");
              });
          }
          catch (Exception ex)
          {
              gFunc.ProcessError(ex);
          }
      }
  }
  </code></pre>
  
  <p><strong>Program.cs</strong></p>
  
  <pre><code>public class Program
  {
      public static void Main(string[] args)
      {
          BuildWebHost(args).Run();
      }
  
      public static IWebHost BuildWebHost(string[] args) =&gt;
          WebHost.CreateDefaultBuilder(args)
              .UseStartup&lt;Startup&gt;()            
              .UseIISIntegration()
              .UseKestrel()
              .Build();
  }
  </code></pre>
  
  <p>UseIISIntegration() tells ASP.NET that IIS will be working as a reverse proxy in front of Kestrel. This also specifies some settings around which port Kestrel should listen on, forwarding headers, and other details.
  UseKestrel() registers the IServer interface for Kestrel as the server that will be used to host the application.</p>
  
  <p>I'm note sure if I need to change anything here, or just use the deafult options.</p>
  
  <p>I've read: Microsoft recommends using IIS with any public facing site for ASP.NET core hosting. IIS provides additional levels of configurability, management, security, logging, and many other things.
  One of the big advantages to using IIS is the process management. IIS will automatically start your app and potentially restart it if a crash were to occur. If you were running your ASP.NET Core app as a Windows Service or console app, you would not have that safety net there to start and monitor the process for you.</p>
  
  <p><strong>launchSettings.json</strong></p>
  
  <p>Do I need to make changes to the contents of this file before publishing? Or does this get changed automatically when publishing the app to a folder?
  For example, do I need to change the ENVIRONMENT to "Production", or the applicationUrl to my website domain?</p>
  
  <pre><code>{
    "iisSettings": {
      "windowsAuthentication": true,
      "anonymousAuthentication": true,
      "iisExpress": {
        "applicationUrl": "https://localhost:44301/",
        "sslPort": 44376
      }
    },
    "profiles": {
      "IIS Express": {
        "commandName": "IISExpress",
        "launchBrowser": true,
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
        }
      },
      "CanvasWeb": {
        "commandName": "Project",
        "launchBrowser": true,
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
        },
        "applicationUrl": "http://localhost:61900/"
      }
    }
  }
  </code></pre>
  
  <p><strong>web.config (for ASP.NET Core)</strong></p>
  
  <p>The web.config file should define how IIS starts up my ASP.NET Core process. For example, I want to enable output logging by setting stdoutLogEnabled=true and I might also want to change the log output location as configured in stdoutLogFile.</p>
  
  <p>IIS configuration is influenced by the  section of web.config for those IIS features that apply to a reverse proxy configuration.</p>
  
  <p>In my ASP.NET Core2 project, there is currently no "web.config" file. Will this file appear when I publish my app?</p>
  
  <p><strong>Publish to a folder</strong></p>
  
  <p>When deploying from Visual Studio, the dotnet publish step happens automatically before the files are copied to the deployment destination.</p>
  
  <p>The publish folder contains .exe and .dll files for the app, its dependencies, and optionally the .NET runtime. In addition to .exe and .dll files, the publish folder for an ASP.NET Core app typically contains configuration files, static assets, and MVC views.</p>
  
  <p>A .NET Core app can be published as self-contained or framework-dependent app. If the app is self-contained, the .dll files that contain the .NET runtime are included in the publish folder. If the app is framework-dependent, the .NET runtime files aren't included because the app has a reference to a version of .NET that's installed on the server.</p>
  
  <p>As I'm installing for IIS on Windows server, I believe I should use the default deployment model, which is framework-dependent.</p>
  
  <p><strong>Process Manager</strong></p>
  
  <p>An ASP.NET Core app is a console app that must be started when a server boots and restarted if it crashes. To automate starts and restarts, a process manager is required.
  I know I could use Apache on Linux, but in this case I need to use IIS as my current site is a Windows server.</p>
  
  <p><strong>Setting up a reverse proxy</strong></p>
  
  <p>A scenario that requires a reverse proxy is when you have multiple applications that share the same IP and port running on a single server. That doesn't work with Kestrel directly because Kestrel doesn't support sharing the same IP and port between multiple processes. When you configure Kestrel to listen on a port, it handles all traffic for that port regardless of host header. A reverse proxy that can share ports must then forward to Kestrel on a unique IP and port.</p>
  
  <p>According to MS, there are other reasons for using a reverse proxy server. For example, it simplifies load balancing and SSL set-up. Only your reverse proxy server requires an SSL certificate, and that server can communicate with your application servers on the internal network using plain HTTP.</p>
  
  <p><strong>Install .NET Core Windows Server Hosting Bundle</strong></p>
  
  <p>I've read that before I deploy my application, I need to install the .NET Core hosting bundle for IIS on the hosting machine. This will install the .NET Core runtime, libraries, and the ASP.NET Core module for IIS.
  After installing it, you may need to do a "net stop was /y" and "net start w3svc" to ensure all the changes are picked up for IIS.</p>
  
  <p>I can only access my web server via cpanel, so I think my hosting provider will need to do this.</p>
  
  <p><strong>SSL Certificate</strong></p>
  
  <p>Because I'm using https, I believe that I'll need to purchase an SSL certificate and have it installed in IIS.</p>
  
  <p><strong>IIS Setup - Create Application in IIS</strong></p>
  
  <p>I can only access my web server via cpanel, so I think this will also need to be done by my hosting provider.</p>
  
  <ol>
  <li>Create a new IIS Application Pool. You will want to create one under the .NET CLR version of “No Managed Code“. Since IIS only works as a reverse proxy, it isn’t actually executing any .NET code.</li>
  <li>Create your new application under your existing IIS Site, or create a new IIS site. Either way, you will want to pick your new IIS Application Pool and point it at the folder you copied your ASP.NET publish output files to.</li>
  </ol>