Runtime Modes

This section describes how to use the runtime mode setting to optimize Umbraco for the best development experience or optimal production environment.

Configuring the runtime mode

You can configure the runtime mode to optimize Umbraco for different development experiences and environments by setting Umbraco:CMS:Runtime:Mode to one of the available modes:

  • BackofficeDevelopment (default)

  • Development

  • Production

This can be done via the appsettings.json file, environment variables, or any other .NET configuration provider (like Azure Key Vault/App Configuration). Although this setting affects how Umbraco behaves at runtime, some modes have prerequisites on how the project is built/published. Make sure to read the descriptions of each mode before changing this setting from the default BackofficeDevelopment mode, as incorrect configuration can result in your application not starting (by throwing a BootFailedException).

BackofficeDevelopment mode

The BackofficeDevelopment mode is the default behavior for Umbraco: it does not optimize Umbraco for any specific environment and does not have any prerequisites. This mode allows for rapid development (without having to recompile/rebuild your project), including all development from within the backoffice.

Development mode

The Development mode can be used when you're developing from an IDE (like Visual Studio, VS Code, or Rider) or the dotnet CLI (e.g. using dotnet watch). It is a recommended prerequisite if you want to use the Production mode in your production environment.

This mode disables in-memory ModelsBuilder generation and validates the following setting:

  • Umbraco:CMS:ModelsBuilder:ModelsMode is not set to InMemoryAuto.

If you want to use the generated models, use SourceCodeAuto or SourceCodeManual. These require manually recompiling the project after the models have changed (for example after updating Document Types, Media Types, Member Types, or Data Types). Razor views (cshtml files) will still be automatically compiled at runtime. They allow you to quickly iterate on the rendered output from templates, partial views, and view components.

The recommended approach to enable Development mode is to update the appsettings.json file with the following settings:

{
    "Umbraco": {
        "CMS": {
            "Runtime": {
                "Mode" : "Development"
            },
            "ModelsBuilder":{
                "ModelsMode": "SourceCodeAuto"
            }
        }
    }
}

Ensure your models are generated by running Umbraco and navigating to Settings > Models Builder > Generate models. You can remove the following properties from your csproj project file to enable the compilation of Razor views (which also ensures your views do not contain compilation errors and is a prerequisite for enabling Production mode):

<RazorCompileOnBuild>false</RazorCompileOnBuild>
<RazorCompileOnPublish>false</RazorCompileOnPublish>

Fix any compilation errors you might get after this, e.g. if you accidentally referenced deleted models or properties. Running the application will still show the rendered content and you're now ready to optionally enable Production mode on your production environment.

Ensure you have the <CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory> property set in your csproj project file, so Razor views are always copied to the publish directory. This is required by the CMS to display the contents in the backoffice, for Forms to lookup custom theme views and for Deploy to be able to compare schemas (otherwise you'll get schema mismatches).

Production mode

Use Production mode to ensure your production environment is running optimally by disabling development features and validating whether specific settings are configured to their recommended production values.

This mode disables both in-memory ModelsBuilder generation (see Development mode) and Razor (cshtml) runtime compilation. Production mode requires you to compile your views at build/publish time and enforces the following settings for optimal performance/security:

  • The application is built/published in Release mode (with JIT optimization enabled), e.g. using dotnet publish --configuration Release;

  • Umbraco:CMS:WebRouting:UmbracoApplicationUrl is set to a valid URL;

  • Umbraco:CMS:Global:UseHttps is enabled;

  • Umbraco:CMS:ModelsBuilder:ModelsMode is set to Nothing.

To compile your views at build/publish time, remove the <RazorCompileOnBuild> and <RazorCompileOnPublish> properties from your project file (see the Development mode section). If you don't, Umbraco can't find the templates and will return 404 (Page Not Found) errors.

The recommended approach to enable Production mode is to update the appsettings.Production.json file (or create one) with the following settings:

{
  "Umbraco": {
    "CMS": {
      "Runtime": {
        "Mode": "Production"
      },
      "Hosting": {
        "Debug": false
      },
      "Global": {
        "UseHttps": true
      },
      "ModelsBuilder": {
        "ModelsMode": "Nothing"
      },
      "WebRouting": {
        "UmbracoApplicationUrl": "https://<REPLACE_WITH_YOUR_PRIMARY_DOMAIN>/"
      },
      "RuntimeMinification": {
        "UseInMemoryCache": true,
        "CacheBuster": "AppDomain"
      }
    }
  }
}

Although you can still edit document types and views (if not running from the published output), changes won't be picked up until you've rebuilt your project or republished the application.

Models won't be generated by ModelsBuilder (because the mode is set to Nothing), requiring you to do all your changes while in Development mode. As Models Builder is set to Nothing, the Models Builder dashboard is disabled in the backoffice of live environment.

Also, templates cannot be edited on live environment as runtime compilation is not enabled and is set to Production.

Also ensure the UmbracoApplicationUrl is updated to the primary URL of your production environment, as this is used when sending emails (password reset, notifications, health check results, etc.) and the keep-alive task.

Customize/extend runtime mode validation

Validation of the above-mentioned settings is done when determining the runtime level during startup using the new IRuntimeModeValidationService and when it fails, causes a BootFailedException to be thrown. The default implementation gets all registered IRuntimeModeValidators to do the validation, making it possible to remove default checks and/or add your own (inherit from RuntimeModeProductionValidatorBase, if you only want to validate against the production runtime mode). The following validators are added by default:

  • JITOptimizerValidator - Ensure the application is built/published in Release mode (with JIT optimization enabled) when in production runtime mode, e.g. using dotnet publish --configuration Release;

  • UmbracoApplicationUrlValidator - ensure Umbraco:CMS:WebRouting:UmbracoApplicationUrl is configured when in production runtime mode;

  • UseHttpsValidator - ensure Umbraco:CMS:Global:UseHttps is enabled when in production runtime mode;

  • ModelsBuilderModeValidator - ensure Umbraco:CMS:ModelsBuilder:ModelsMode is not set to InMemoryAuto when in development runtime mode and set to Nothing when in production runtime mode.

The following example removes the default UmbracoApplicationUrlValidator and adds a new custom DisableElectionForSingleServerValidator:

using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Infrastructure.Runtime;
using Umbraco.Cms.Infrastructure.Runtime.RuntimeModeValidators;

public class RuntimeModeValidatorComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
        => builder.RuntimeModeValidators()
            .Remove<UmbracoApplicationUrlValidator>()
            .Add<DisableElectionForSingleServerValidator>();
}

public class DisableElectionForSingleServerValidator : IRuntimeModeValidator
{
    private readonly IOptionsMonitor<GlobalSettings> _globalSettings;

    public DisableElectionForSingleServerValidator(IOptionsMonitor<GlobalSettings> globalSettings) => _globalSettings = globalSettings;

    public bool Validate(RuntimeMode runtimeMode, [NotNullWhen(false)] out string? validationErrorMessage)
    {
        if (runtimeMode == RuntimeMode.Production && _globalSettings.CurrentValue.DisableElectionForSingleServer == false)
        {
            validationErrorMessage = "Disable primary server election (and support for load balancing) to improve startup performance.";
            return false;
        }

        validationErrorMessage = null;
        return true;
    }
}

Last updated