Deploying and hosting ASP.NET Core applications

This page covers hosting requirements and basic deployment scenarios for the ASP.NET Core live site application. For hosting requirements of the Xperience administration application (running ASP.NET Web Forms), see System requirements.

Hosting requirements

  • ASP.NET Core Runtime for .NET 6 or newer installed on the hosting machine.
  • A hosting environment supporting .NET 6 or newer.
  • Hosting plan parameters:
    • Minimum: 4 GB memory (RAM), 200 MB database size
    • Recommended: 8 GB memory, 1 GB database size

Note: The recommended hosting parameters depend on the scale and implementation details of each project. Very large or heavily trafficked websites may have significantly higher requirements. For virtual hosting servers, the listed values refer to the memory capacity available for your web application, not the server’s overall resources.

Publishing and deploying projects

This section describes a basic publishing and deployment process for Xperience ASP.NET Core applications.

  1. Set up a hosting environment and publishing process for the project. For details, refer to Microsoft’s documentation for your chosen hosting method and platform (on-premise Windows or Linux server, Azure, Docker, etc.): Host and deploy ASP.NET Core

    Handling Xperience-specific static files

    Carefully consider the impact your chosen publishing process may have on static files synchronized between the live site and administration applications. These resources – media library files, smart search indexes, etc. – stored in the ~/SiteCodeName folder in live site application’s root directory are synchronized with the connected administration application using the web farms feature.

    The publishing process must account for these files and ensure they remain consistent with the rest of the environment, especially when publishing the application to production deployments. Otherwise, you may encounter missing images, broken search functionality and other issues on the live site. For example, you can use the content staging feature to ensure that your development and production environments remain synchronized. Alternatively, set up your publishing process so that it does not modify the ~/SiteCodeName folder on the target deployment.

  2. Deploy your Xperience database. You can choose between the following approaches:

    1. Restore a database backup on your hosting SQL server, and manually update the connection string of both projects.
      – OR –
    2. Install a new database on your hosting SQL server and use the Xperience Export/import feature to transfer the site:
      1. Delete the connection string from the configuration files of the live site and administration projects.
      2. Open the Sites application on your local development instance and click Export site () next to the site that you want to deploy.
      3. Go through the Site export wizard.
        • The system saves the export package into the <administration project>\CMS\CMSSiteUtils\Export folder.
      4. Copy the exported package into the <administration project>\CMS\CMSSiteUtils\Import folder on the hosting server.
      5. Open the administration interface of the deployed project in a browser.
      6. Create a new Xperience database on your hosting SQL server.
      7. At the end of the Database installation wizard, choose to import your existing site (from the previously exported package).
      8. Copy the new connection string from the web.config of the deployed administration project into the configuration file of your live site project.

    Database server time zones

    If possible, use the same time zone for both your local environment and the production server hosting your database. Otherwise you may encounter time shift problems with the deployed data, for example in the settings of scheduled tasks.

    If you cannot synchronize the time zones, we recommend that you verify and reconfigure the timing settings of scheduled tasks after the deployment.

  3. (Optional) See Hosting configuration notes for additional configuration you should consider for the hosting environment.

Publishing the project’s site folder

The project’s site folder is used to store static files from media libraries and other site-specific files. It is by default located in the root of the project on the filesystem (~/<SiteCodeName>). Since the folder is not by default included in the project, it is not published when running dotnet publish.

To include the contents of the folder when publishing, add the following snippet into the Core project’s .csproj file:




<ItemGroup>
  <Content Include="SiteFolderName\**">
    <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
  </Content>
</ItemGroup>


Hosting configuration notes

Automating application start

The Xperience ASP.NET Core application runs as a standard console application. The application’s hosting environment needs to ensure the application starts after the server reboots, the application is restarted (e.g., via the administration application in System -> General -> Restart all web farm servers), or an unexpected error that causes the application to crash occurs.

Automating starts and restarts is typically done using process managers such as Internet Information Services for Windows-based servers, or Nginx for Linux. Refer to the Microsoft documentation for guides on how to configure process managers based on your hosting environment.

Handling errors during application initialization

The Xperience ASP.NET Core integration package does not provide any support for error handling or recovery from errors that occur during application initialization. If an error occurs during the initialization process (e.g., the application’s database experiences an outage), the hosting environment needs to ensure application recovery. For example, by terminating the application and attempting a restart during subsequent requests.

Refer to Microsoft documentation sources for recommended ways of handling error recovery during application initialization under various hosting types.

For example, when hosting the application under Internet Information Services (IIS) servers, you can use the CaptureStartupErrors web host configuration option:

Program.cs



using Microsoft.Extensions.Hosting;

...

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder
                        .UseIISIntegration()
                         // When set to false, errors during startup result in the host exiting (the process terminating)
                        .CaptureStartupErrors(false)
                        .UseStartup<Startup>();
                });


Enabling static web assets in non-Development local environments

The Xperience application must have static web assets enabled to correctly load script files and other resources. When running Xperience locally (e.g., using the built-in Visual Studio IIS Express server), static web assets are enabled by default in the Development environment. However, if you are using a different environment, e.g., by setting ASPNETCORE_ENVIRONMENT to a different value in the Properties/launchSettings.json file, you need to enable static web assets – call UseStaticWebAssets on IWebHostBuilder in Program.cs.

Program.cs



using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

...

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder
                        .UseIISIntegration()
                        .UseStaticWebAssets() // Enables static web assets
                        .UseStartup<Startup>();
                });


Hosting the application under a virtual directory outside of IIS

If you wish to host the Core application in a virtual directory outside of an IIS server, you need to manually configure the application’s base virtual path:

  1. Add the UsePathBase middleware to the application’s middleware pipeline. Pass the full path from the server root to the application’s virtual directory, including the leading ‘/’ character, as the method’s argument.

    • We recommend adding this middleware to the pipeline as soon as possible. For the earliest possible inclusion into the pipeline, use a startup filter:

      AddVirtualDirectoryToBasePathStartupFilter.cs
      
      
      
        public class AddVirtualDirectoryToBasePathStartupFilter : IStartupFilter
        {
            public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
            {
                return builder =>
                {
                    // Sets the root-relative application path to '<ServerRoot>/app'
                    builder.UsePathBase("/app");
                    next(builder);
                };
            }
        }
      
      
        
  2. Set the ApplicationPath property of the SystemContext class to the same path you provided to the UsePathBase middleware. Set the value at the beginning of the application’s Configure method, before other Xperience-specific middleware sensitive to this configuration is run.

    Application's startup class
    
    
    
     using CMS.Base;
     ...
    
     public void Configure(IApplicationBuilder app, IConfiguration configuration)
     {
         // Sets the root-relative application path to '<ServerRoot>/app'
         SystemContext.ApplicationPath = "/app";
         ...
     }
    
    
     

The application is now configured to run in the specified virtual directory.

Known issues

Images resized via the API not displaying on the live site

On some deployments (Windows Server Core or Nano, specific Linux distributions), you may encounter an issue where resized images (e.g., from media libraries) do not render.

This is caused by a missing implementation of the GDI+ library (not included by default on some distributions).

On Linux, you need to manually install the missing library:




sudo apt-get install libgdiplus


Affected Windows distributions do not have a clean workaround. We recommend switching to a distribution that contains an implementation of the GDI+ library (gdiplus.dll) by default.

Linux deployments

Filesystem behavior and limitations

This section applies from Kentico Xperience Hotfix 13.0.10 onwards. In previous versions, Linux deployments contained filesystem-related issues that prevented certain features from working correctly.

Hotfix 13.0.10 introduced a new approach for detecting absolute and relative paths on Unix-like filesystems. Since both relative and absolute paths on Unix-like filesystems begin with a forward slash (‘/’), Xperience cannot determine whether a path segment is absolute or relative. For example, this is important when determining the location of media library content, or in general whenever it is necessary to prepend relative path fragments with the physical path to the web application.

By default, the system uses the following process to detect the path type:

  1. The system receives a path fragment. For example: /media/mediagallery/image.jpg
  2. If the path is prefixed with the physical path to the web application (stored in the SystemContext.WebApplicationPhysicalPath property), the path is treated as absolute. If not, the system checks whether the first two folders in the path exist on the filesystem starting from the root (taking the first two folders produced the least false positives during extensive testing). For the example above, the system tests for the existence of: /media/mediagallery
  3. If the first two folders in the path do not exist, the path is treated as relative. If the first two folders exist, the path is treated as absolute.

You can override this behavior by adding the CMSUnixRootedPathPrefixes configuration key to the Core application. Adding the key disables the process described above. Instead, the key needs to contain a semicolon-delimited list of all path prefixes (e.g., /etc/, /var/, /mnt/share/) the system should treat as absolute. The list must be case-sensitive.

appsettings.json



{
    "CMSUnixRootedPathPrefixes": "/etc/;/var/;/mnt/share/"
}


Only use the CMSUnixRootedPathPrefixes configuration key if your project contains non-standard file system mapping (e.g., for media library files), or if you encounter issues with the built-in path type detection mechanism. The default functionality covers all expected cases and filesystem configurations. 

Moreover, Xperience does not validate permissions on Linux filesystems.

Linux deployments – known issues

Images resized via the API not rendered on the live site

By default, Linux deployments of Xperience ASP.NET Core live site projects cannot display resized images (e.g., retrieved from media libraries or as page attachments).

The System.Drawing.Common package used for image processing is deprecated for Linux environments (see System.Drawing.Common only supported on Windows). To resolve the issue, developers need to apply hotfix 13.0.107 or newer and install the Kentico.Xperience.ImageProcessing.KX13 NuGet package into the live site project. The package uses the SkiaSharp library to process images.