diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index 133dd8d65645..374242ff1603 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -972,12 +972,12 @@ }, { "source_path": "aspnetcore/host-and-deploy/blazor/client-side.md", - "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly/", "redirect_document_id": false }, { "source_path": "aspnetcore/host-and-deploy/blazor/server-side.md", - "redirect_url": "/aspnet/core/blazor/host-and-deploy/server", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/server/", "redirect_document_id": false }, { @@ -1077,12 +1077,12 @@ }, { "source_path": "aspnetcore/host-and-deploy/blazor/server.md", - "redirect_url": "/aspnet/core/blazor/host-and-deploy/server", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/server/", "redirect_document_id": false }, { "source_path": "aspnetcore/host-and-deploy/blazor/webassembly.md", - "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly/", "redirect_document_id": false }, { @@ -1310,7 +1310,7 @@ }, { "source_path": "aspnetcore/blazor/http-caching-issues.md", - "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly-caching/http-caching-issues", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly/http-caching-issues", "redirect_document_id": false }, { @@ -1357,6 +1357,36 @@ "source_path": "aspnetcore/blazor/security/server/index.md", "redirect_url": "/aspnet/core/blazor/security/", "redirect_document_id": false + }, + { + "source_path": "aspnetcore/blazor/host-and-deploy/webassembly-caching/index.md", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly/runtime-and-app-bundle-caching", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/blazor/host-and-deploy/webassembly-caching/http-caching-issues.md", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly/http-caching-issues", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/blazor/host-and-deploy/webassembly.md", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly/", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/blazor/host-and-deploy/multiple-hosted-webassembly.md", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly/multiple-hosted-webassembly", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/blazor/host-and-deploy/webassembly-deployment-layout.md", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/webassembly/deployment-layout", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/blazor/host-and-deploy/server.md", + "redirect_url": "/aspnet/core/blazor/host-and-deploy/server/", + "redirect_document_id": false } ] } diff --git a/aspnetcore/blazor/components/class-libraries.md b/aspnetcore/blazor/components/class-libraries.md index 0ebcf58fde6c..670218a37d6d 100644 --- a/aspnetcore/blazor/components/class-libraries.md +++ b/aspnetcore/blazor/components/class-libraries.md @@ -340,7 +340,7 @@ For more information, see . +For more information, see . :::moniker-end diff --git a/aspnetcore/blazor/components/index.md b/aspnetcore/blazor/components/index.md index 260211714999..df61df4117fb 100644 --- a/aspnetcore/blazor/components/index.md +++ b/aspnetcore/blazor/components/index.md @@ -1684,7 +1684,7 @@ Use a base-relative path (`/`) to refer to the web root for a static asset. In t Components do **not** support tilde-slash notation (`~/`). -For information on setting an app's base path, see . +For information on setting an app's base path, see . ## Tag Helpers aren't supported in components diff --git a/aspnetcore/blazor/components/integration-hosted-webassembly.md b/aspnetcore/blazor/components/integration-hosted-webassembly.md index 4b4b099c3836..69b8f4b10b95 100644 --- a/aspnetcore/blazor/components/integration-hosted-webassembly.md +++ b/aspnetcore/blazor/components/integration-hosted-webassembly.md @@ -559,7 +559,7 @@ The persisted prerendered state is transferred to the client, where it's used to * Authentication and authorization subjects that pertain to prerendering * [General aspects](xref:blazor/security/index) * [Prerendering with authentication in hosted Blazor WebAssembly apps](xref:blazor/security/webassembly/additional-scenarios#prerendering-with-authentication) -* [Host and deploy: Blazor WebAssembly](xref:blazor/host-and-deploy/webassembly) +* * [Handle errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering) * is executed *twice* when prerendering: [Handle asynchronous navigation events with `OnNavigateAsync`](xref:blazor/fundamentals/routing#handle-asynchronous-navigation-events-with-onnavigateasync) @@ -1074,7 +1074,7 @@ The persisted prerendered state is transferred to the client, where it's used to * Authentication and authorization subjects that pertain to prerendering * [General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization) * [Prerendering with authentication](xref:blazor/security/webassembly/additional-scenarios#prerendering-with-authentication) -* [Host and deploy: Blazor WebAssembly](xref:blazor/host-and-deploy/webassembly) +* :::moniker-end @@ -1332,7 +1332,7 @@ Additional work might be required depending on the static resources that compone * Authentication and authorization subjects that pertain to prerendering * [General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization) * [Prerendering with authentication](xref:blazor/security/webassembly/additional-scenarios#prerendering-with-authentication) -* [Host and deploy: Blazor WebAssembly](xref:blazor/host-and-deploy/webassembly) +* :::moniker-end diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 93e4d0a1a001..62785ea8d7be 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -58,7 +58,7 @@ Use the following guidance to integrate Razor components into pages or views of render-mode="ServerPrerendered" /> ``` - The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article. + The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, see . The component is used to render head (``) content for page titles ( component) and other head elements ( component) set by Razor components. For more information, see . @@ -556,7 +556,7 @@ To resolve the problem, use ***either*** of the following approaches: * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop) * [Authentication and authorization: General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization) * [Handle Errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering) -* [Host and deploy: Blazor Server](xref:blazor/host-and-deploy/server) +* * [Threat mitigation: Cross-site scripting (XSS)](xref:blazor/security/interactive-server-side-rendering#cross-site-scripting-xss) * is executed *twice* when prerendering: [Handle asynchronous navigation events with `OnNavigateAsync`](xref:blazor/fundamentals/routing#handle-asynchronous-navigation-events-with-onnavigateasync) @@ -589,7 +589,7 @@ Use the following guidance to integrate Razor components into pages or views of ``` - The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article. + The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, see . The component is used to render head (``) content for page titles ( component) and other head elements ( component) set by Razor components. For more information, see . @@ -1075,7 +1075,7 @@ To resolve the problem, use ***either*** of the following approaches: * [Prerendering with JavaScript interop](xref:blazor/components/lifecycle#prerendering-with-javascript-interop) * [Authentication and authorization: General aspects](xref:blazor/security/index#aspnet-core-blazor-authentication-and-authorization) * [Handle Errors: Prerendering](xref:blazor/fundamentals/handle-errors#prerendering) -* [Host and deploy: Blazor Server](xref:blazor/host-and-deploy/server) +* * [Threat mitigation: Cross-site scripting (XSS)](xref:blazor/security/interactive-server-side-rendering#cross-site-scripting-xss) :::moniker-end @@ -1103,7 +1103,7 @@ An existing Razor Pages or MVC app can integrate Razor components into pages or ``` - The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article. + The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, see . * Add a ` -``` - -After Blazor's ` -``` - -Standalone Blazor WebAssembly: - -:::moniker-end - -```html - -``` - -For more information on loading boot resources, see . - -:::moniker range=">= aspnetcore-8.0" - -To disable compression, add the `CompressionEnabled` MSBuild property to the app's project file and set the value to `false`: - -```xml - - false - -``` - -The `CompressionEnabled` property can be passed to the [`dotnet publish`](/dotnet/core/tools/dotnet-publish) command with the following syntax in a command shell: - -```dotnetcli -dotnet publish -p:CompressionEnabled=false -``` - -:::moniker-end - -:::moniker range="< aspnetcore-8.0" - -To disable compression, add the `BlazorEnableCompression` MSBuild property to the app's project file and set the value to `false`: - -```xml - - false - -``` - -The `BlazorEnableCompression` property can be passed to the [`dotnet publish`](/dotnet/core/tools/dotnet-publish) command with the following syntax in a command shell: - -```dotnetcli -dotnet publish -p:BlazorEnableCompression=false -``` - -:::moniker-end - -## Rewrite URLs for correct routing - -Routing requests for page components in a Blazor WebAssembly app isn't as straightforward as routing requests in a Blazor Server app. Consider a Blazor WebAssembly app with two components: - -* `Main.razor`: Loads at the root of the app and contains a link to the `About` component (`href="About"`). -* `About.razor`: `About` component. - -When the app's default document is requested using the browser's address bar (for example, `https://www.contoso.com/`): - -1. The browser makes a request. -1. The default page is returned, which is usually `index.html`. -1. `index.html` bootstraps the app. -1. component loads, and the Razor `Main` component is rendered. - -In the Main page, selecting the link to the `About` component works on the client because the Blazor router stops the browser from making a request on the Internet to `www.contoso.com` for `About` and serves the rendered `About` component itself. All of the requests for internal endpoints *within the Blazor WebAssembly app* work the same way: Requests don't trigger browser-based requests to server-hosted resources on the Internet. The router handles the requests internally. - -If a request is made using the browser's address bar for `www.contoso.com/About`, the request fails. No such resource exists on the app's Internet host, so a *404 - Not Found* response is returned. - -Because browsers make requests to Internet-based hosts for client-side pages, web servers and hosting services must rewrite all requests for resources not physically on the server to the `index.html` page. When `index.html` is returned, the app's Blazor router takes over and responds with the correct resource. - -When deploying to an IIS server, you can use the URL Rewrite Module with the app's published `web.config` file. For more information, see the [IIS](#iis) section. - -:::moniker range="< aspnetcore-8.0" - -## Hosted deployment with ASP.NET Core - -A *hosted deployment* serves the Blazor WebAssembly app to browsers from an [ASP.NET Core app](xref:index) that runs on a web server. - -The client Blazor WebAssembly app is published into the `/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot` folder of the server app, along with any other static web assets of the server app. The two apps are deployed together. A web server that is capable of hosting an ASP.NET Core app is required. For a hosted deployment, Visual Studio includes the **Blazor WebAssembly App** project template (`blazorwasm` template when using the [`dotnet new`](/dotnet/core/tools/dotnet-new) command) with the **`Hosted`** option selected (`-ho|--hosted` when using the `dotnet new` command). - -For more information, see the following articles: - -* ASP.NET Core app hosting and deployment: -* Deployment to Azure App Service: -* Blazor project templates: - -## Hosted deployment of a framework-dependent executable for a specific platform - -To deploy a hosted Blazor WebAssembly app as a [framework-dependent executable for a specific platform](/dotnet/core/deploying/#publish-framework-dependent) (not self-contained) use the following guidance based on the tooling in use. - -### Visual Studio - -A [self-contained](/dotnet/core/deploying/#publish-self-contained) deployment is configured for a generated publish profile (`.pubxml`). Confirm that the **:::no-loc text="Server":::** project's publish profile contains the `` MSBuild property set to `false`. - -In the `.pubxml` publish profile file in the **:::no-loc text="Server":::** project's `Properties` folder: - -```xml -false -``` - -Set the [Runtime Identifier (RID)](/dotnet/core/rid-catalog) using the **Target Runtime** setting in the **Settings** area of the **Publish** UI, which generates the `` MSBuild property in the publish profile: - -```xml -{RID} -``` - -In the preceding configuration, the `{RID}` placeholder is the [Runtime Identifier (RID)](/dotnet/core/rid-catalog). - -Publish the **:::no-loc text="Server":::** project in the **Release** configuration. - -> [!NOTE] -> It's possible to publish an app with publish profile settings using the .NET CLI by passing `/p:PublishProfile={PROFILE}` to the [`dotnet publish` command](/dotnet/core/tools/dotnet-publish), where the `{PROFILE}` placeholder is the profile. For more information, see the *Publish profiles* and *Folder publish example* sections in the article. If you pass the RID in the [`dotnet publish` command](/dotnet/core/tools/dotnet-publish) and not in the publish profile, use the MSBuild property (`/p:RuntimeIdentifier`) with the command, not with the `-r|--runtime` option. - -### .NET CLI - -Configure a [self-contained](/dotnet/core/deploying/#publish-self-contained) deployment by placing the `` MSBuild property in a `` in the **:::no-loc text="Server":::** project's project file set to `false`: - -```xml -false -``` - -> [!IMPORTANT] -> The `SelfContained` property must be placed in the **:::no-loc text="Server":::** project's project file. The property can't be set correctly with the [`dotnet publish` command](/dotnet/core/tools/dotnet-publish) using the `--no-self-contained` option or the MSBuild property `/p:SelfContained=false`. - -Set the [Runtime Identifier (RID)](/dotnet/core/rid-catalog) using ***either*** of the following approaches: - -* Option 1: Set the RID in a `` in the **:::no-loc text="Server":::** project's project file: - - ```xml - {RID} - ``` - - In the preceding configuration, the `{RID}` placeholder is the [Runtime Identifier (RID)](/dotnet/core/rid-catalog). - - Publish the app in the Release configuration from the **:::no-loc text="Server":::** project: - - ```dotnetcli - dotnet publish -c Release - ``` - -* Option 2: Pass the RID in the [`dotnet publish` command](/dotnet/core/tools/dotnet-publish) as the MSBuild property (`/p:RuntimeIdentifier`), not with the `-r|--runtime` option: - - ```dotnetcli - dotnet publish -c Release /p:RuntimeIdentifier={RID} - ``` - - In the preceding command, the `{RID}` placeholder is the [Runtime Identifier (RID)](/dotnet/core/rid-catalog). - -For more information, see the following articles: - -* [.NET application publishing overview](/dotnet/core/deploying/) -* - -:::moniker-end - -:::moniker range="< aspnetcore-8.0" - -## Hosted deployment with multiple Blazor WebAssembly apps - -For more information, see . - -:::moniker-end - -## Standalone deployment - -A *standalone deployment* serves the Blazor WebAssembly app as a set of static files that are requested directly by clients. Any static file server is able to serve the Blazor app. - -Standalone deployment assets are published into either the `/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot` or `bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish\` folder (depending on the version of the .NET SDK in use), where the `{TARGET FRAMEWORK}` placeholder is the target framework. - -## Azure App Service - -Blazor WebAssembly apps can be deployed to Azure App Services on Windows, which hosts the app on [IIS](#iis). - -Deploying a standalone Blazor WebAssembly app to Azure App Service for Linux isn't currently supported. We recommend hosting a standalone Blazor WebAssembly app using [Azure Static Web Apps](#azure-static-web-apps), which supports this scenario. - -## Azure Static Web Apps - -Use one of the following approaches to deploy a Blazor WebAssembly app to Azure Static Web Apps: - -* [Deploy from Visual Studio](#deploy-from-visual-studio) -* [Deploy from Visual Studio Code](#deploy-from-visual-studio-code) -* [Deploy from GitHub](#deploy-from-github) - -### Deploy from Visual Studio - -To deploy from Visual Studio, create a publish profile for Azure Static Web Apps: - -1. Save any unsaved work in the project, as a Visual Studio restart might be required during the process. - -1. In Visual Studio's **Publish** UI, select **Target** > **Azure** > **Specific Target** > **Azure Static Web Apps** to create a [publish profile](xref:host-and-deploy/visual-studio-publish-profiles). - -1. If the **Azure WebJobs Tools** component for Visual Studio isn't installed, a prompt appears to install the **ASP.NET and web development** component. Follow the prompts to install the tools using the Visual Studio Installer. Visual Studio closes and reopens automatically while installing the tools. After the tools are installed, start over at the first step to create the publish profile. - -1. In the publish profile configuration, provide the **Subscription name**. Select an existing instance, or select **Create a new instance**. When creating a new instance in the Azure portal's **Create Static Web App** UI, set the **Deployment details** > **Source** to **Other**. Wait for the deployment to complete in the Azure portal before proceeding. - -1. In the publish profile configuration, select the Azure Static Web Apps instance from the instance's resource group. Select **Finish** to create the publish profile. If Visual Studio prompts to install the Static Web Apps (SWA) CLI, install the CLI by following the prompts. The SWA CLI requires [NPM/Node.js (Visual Studio documentation)](/visualstudio/javascript/npm-package-management). - -After the publish profile is created, deploy the app to the Azure Static Web Apps instance using the publish profile by selecting the **Publish** button. - -### Deploy from Visual Studio Code - -To deploy from Visual Studio Code, see [Quickstart: Build your first static site with Azure Static Web Apps](/azure/static-web-apps/getting-started?tabs=blazor). - -### Deploy from GitHub - -To deploy from a GitHub repository, see [Tutorial: Building a static web app with Blazor in Azure Static Web Apps](/azure/static-web-apps/deploy-blazor). - -## IIS - -IIS is a capable static file server for Blazor apps. To configure IIS to host Blazor, see [Build a Static Website on IIS](/iis/manage/creating-websites/scenario-build-a-static-website-on-iis). - -Published assets are created in the `/bin/Release/{TARGET FRAMEWORK}/publish` or `bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish` folder, depending on which version of the SDK is used and where the `{TARGET FRAMEWORK}` placeholder is the target framework. Host the contents of the `publish` folder on the web server or hosting service. - -### web.config - -When a Blazor project is published, a `web.config` file is created with the following IIS configuration: - -* MIME types -* HTTP compression is enabled for the following MIME types: - * `application/octet-stream` - * `application/wasm` -* URL Rewrite Module rules are established: - * Serve the sub-directory where the app's static assets reside (`wwwroot/{PATH REQUESTED}`). - * Create SPA fallback routing so that requests for non-file assets are redirected to the app's default document in its static assets folder (`wwwroot/index.html`). - -### Use a custom `web.config` - -To use a custom `web.config` file: - -:::moniker range=">= aspnetcore-8.0" - -1. Place the custom `web.config` file in the project's root folder. -1. Publish the project. For more information, see . - -:::moniker-end - -:::moniker range="< aspnetcore-8.0" - -1. Place the custom `web.config` file in the project's root folder. For a hosted Blazor WebAssembly [solution](xref:blazor/tooling#visual-studio-solution-file-sln), place the file in the **:::no-loc text="Server":::** project's folder. -1. Publish the project. For a hosted Blazor WebAssembly solution, publish the solution from the **:::no-loc text="Server":::** project. For more information, see . - -:::moniker-end - -If the SDK's `web.config` generation or transformation during publish either doesn't move the file to published assets in the `publish` folder or modifies the custom configuration in your custom `web.config` file, use any of the following approaches as needed to take full control of the process: - -* If the SDK doesn't generate the file, for example, in a standalone Blazor WebAssembly app at `/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot` or `bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish`, depending on which version of the SDK is used and where the `{TARGET FRAMEWORK}` placeholder is the target framework, set the `` property to `true` in the project file (`.csproj`). Usually for standalone WebAssembly apps, this is the only required setting to move a custom `web.config` file and prevent transformation of the file by the SDK. - - ```xml - - true - - ``` - -* Disable the SDK's `web.config` transformation in the project file (`.csproj`): - - ```xml - - true - - ``` - -* Add a custom target to the project file (`.csproj`) to move a custom `web.config` file. In the following example, the custom `web.config` file is placed by the developer at the root of the project. If the `web.config` file resides elsewhere, specify the path to the file in `SourceFiles`. The following example specifies the `publish` folder with `$(PublishDir)`, but provide a path to `DestinationFolder` for a custom output location. - - ```xml - - - - ``` - -### Install the URL Rewrite Module - -The [URL Rewrite Module](https://www.iis.net/downloads/microsoft/url-rewrite) is required to rewrite URLs. The module isn't installed by default, and it isn't available for install as a Web Server (IIS) role service feature. The module must be downloaded from the IIS website. Use the Web Platform Installer to install the module: - -1. Locally, navigate to the [URL Rewrite Module downloads page](https://www.iis.net/downloads/microsoft/url-rewrite#additionalDownloads). For the English version, select **WebPI** to download the WebPI installer. For other languages, select the appropriate architecture for the server (x86/x64) to download the installer. -1. Copy the installer to the server. Run the installer. Select the **Install** button and accept the license terms. A server restart isn't required after the install completes. - -### Configure the website - -Set the website's **Physical path** to the app's folder. The folder contains: - -* The `web.config` file that IIS uses to configure the website, including the required redirect rules and file content types. -* The app's static asset folder. - -### Host as an IIS sub-app - -If a standalone app is hosted as an IIS sub-app, perform either of the following: - -* Disable the inherited ASP.NET Core Module handler. - - Remove the handler in the Blazor app's published `web.config` file by adding a `` section to the `` section of the file: - - ```xml - - - - ``` - -* Disable inheritance of the root (parent) app's `` section using a `` element with `inheritInChildApplications` set to `false`: - - ```xml - - - - - - - - - - - - ``` - - > [!NOTE] - > Disabling inheritance of the root (parent) app's `` section is the default configuration for published apps using the .NET SDK. - -Removing the handler or disabling inheritance is performed in addition to [configuring the app's base path](xref:blazor/host-and-deploy/index#app-base-path). Set the app base path in the app's `index.html` file to the IIS alias used when configuring the sub-app in IIS. - -Configure the app's base path by following the guidance in the article. - -### Brotli and Gzip compression - -:::moniker range=">= aspnetcore-8.0" - -*This section only applies to standalone Blazor WebAssembly apps.* - -:::moniker-end - -:::moniker range="< aspnetcore-8.0" - -*This section only applies to standalone Blazor WebAssembly apps. Hosted Blazor apps use a default ASP.NET Core app `web.config` file, not the file linked in this section.* - -:::moniker-end - -IIS can be configured via `web.config` to serve Brotli or Gzip compressed Blazor assets for standalone Blazor WebAssembly apps. For an example configuration file, see [`web.config`](https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/blazor/host-and-deploy/webassembly/_samples/web.config?raw=true). - -Additional configuration of the example `web.config` file might be required in the following scenarios: - -* The app's specification calls for either of the following: - * Serving compressed files that aren't configured by the example `web.config` file. - * Serving compressed files configured by the example `web.config` file in an uncompressed format. -* The server's IIS configuration (for example, `applicationHost.config`) provides server-level IIS defaults. Depending on the server-level configuration, the app might require a different IIS configuration than what the example `web.config` file contains. - -For more information on custom `web.config` files, see the [Use a custom `web.config`](#use-a-custom-webconfig) section. - -### Troubleshooting - -If a *500 - Internal Server Error* is received and IIS Manager throws errors when attempting to access the website's configuration, confirm that the URL Rewrite Module is installed. When the module isn't installed, the `web.config` file can't be parsed by IIS. This prevents the IIS Manager from loading the website's configuration and the website from serving Blazor's static files. - -For more information on troubleshooting deployments to IIS, see . - -## Azure Storage - -[Azure Storage](/azure/storage/) static file hosting allows serverless Blazor app hosting. Custom domain names, the Azure Content Delivery Network (CDN), and HTTPS are supported. - -When the blob service is enabled for static website hosting on a storage account: - -* Set the **Index document name** to `index.html`. -* Set the **Error document path** to `index.html`. Razor components and other non-file endpoints don't reside at physical paths in the static content stored by the blob service. When a request for one of these resources is received that the Blazor router should handle, the *404 - Not Found* error generated by the blob service routes the request to the **Error document path**. The `index.html` blob is returned, and the Blazor router loads and processes the path. - -If files aren't loaded at runtime due to inappropriate MIME types in the files' `Content-Type` headers, take either of the following actions: - -* Configure your tooling to set the correct MIME types (`Content-Type` headers) when the files are deployed. -* Change the MIME types (`Content-Type` headers) for the files after the app is deployed. - - In Storage Explorer (Azure portal) for each file: - - 1. Right-click the file and select **Properties**. - 1. Set the **ContentType** and select the **Save** button. - -For more information, see [Static website hosting in Azure Storage](/azure/storage/blobs/storage-blob-static-website). - -## Nginx - -The following `nginx.conf` file is simplified to show how to configure Nginx to send the `index.html` file whenever it can't find a corresponding file on disk. - -``` -events { } -http { - server { - listen 80; - - location / { - root /usr/share/nginx/html; - try_files $uri $uri/ /index.html =404; - } - } -} -``` - -When setting the [NGINX burst rate limit](https://www.nginx.com/blog/rate-limiting-nginx/#bursts) with [`limit_req`](https://nginx.org/docs/http/ngx_http_limit_req_module.html#limit_req) and [`limit_req_zone`](https://nginx.org/docs/http/ngx_http_limit_req_module.html), Blazor WebAssembly apps may require a large `burst`/`rate` parameter values to accommodate the relatively large number of requests made by an app. Initially, set the value to at least 60: - -``` -http { - limit_req_zone $binary_remote_addr zone=one:10m rate=60r/s; - server { - ... - - location / { - ... - - limit_req zone=one burst=60 nodelay; - } - } -} -``` - -Increase the value if browser developer tools or a network traffic tool indicates that requests are receiving a *503 - Service Unavailable* status code. - -For more information on production Nginx web server configuration, see [Creating NGINX Plus and NGINX Configuration Files](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/). - - -## Apache - -To deploy a Blazor WebAssembly app to Apache: - -:::moniker range=">= aspnetcore-8.0" - -1. Create the Apache configuration file. The following example is a simplified configuration file (`blazorapp.config`): - - ``` - - ServerName www.example.com - ServerAlias *.example.com - - DocumentRoot "/var/www/blazorapp" - ErrorDocument 404 /index.html - - AddType application/wasm .wasm - - - Options -Indexes - AllowOverride None - - - - AddOutputFilterByType DEFLATE text/css - AddOutputFilterByType DEFLATE application/javascript - AddOutputFilterByType DEFLATE text/html - AddOutputFilterByType DEFLATE application/octet-stream - AddOutputFilterByType DEFLATE application/wasm - - BrowserMatch ^Mozilla/4 gzip-only-text/html - BrowserMatch ^Mozilla/4.0[678] no-gzip - BrowserMatch bMSIE !no-gzip !gzip-only-text/html - - - - ErrorLog /var/log/httpd/blazorapp-error.log - CustomLog /var/log/httpd/blazorapp-access.log common - - ``` - -:::moniker-end - -:::moniker range="< aspnetcore-8.0" - -1. Create the Apache configuration file. The following example is a simplified configuration file (`blazorapp.config`): - - ``` - - ServerName www.example.com - ServerAlias *.example.com - - DocumentRoot "/var/www/blazorapp" - ErrorDocument 404 /index.html - - AddType application/wasm .wasm - AddType application/octet-stream .dll - - - Options -Indexes - AllowOverride None - - - - AddOutputFilterByType DEFLATE text/css - AddOutputFilterByType DEFLATE application/javascript - AddOutputFilterByType DEFLATE text/html - AddOutputFilterByType DEFLATE application/octet-stream - AddOutputFilterByType DEFLATE application/wasm - - BrowserMatch ^Mozilla/4 gzip-only-text/html - BrowserMatch ^Mozilla/4.0[678] no-gzip - BrowserMatch bMSIE !no-gzip !gzip-only-text/html - - - - ErrorLog /var/log/httpd/blazorapp-error.log - CustomLog /var/log/httpd/blazorapp-access.log common - - ``` - -:::moniker-end - -1. Place the Apache configuration file into the `/etc/httpd/conf.d/` directory. - -1. Place the app's published assets (`/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot`, where the `{TARGET FRAMEWORK}` placeholder is the target framework) into the `/var/www/blazorapp` directory (the location specified to `DocumentRoot` in the configuration file). - -1. Restart the Apache service. - -For more information, see [`mod_mime`](https://httpd.apache.org/docs/2.4/mod/mod_mime.html) and [`mod_deflate`](https://httpd.apache.org/docs/current/mod/mod_deflate.html). - -## GitHub Pages - -The following guidance for GitHub Pages deployments of Blazor WebAssembly apps demonstrates concepts with a live tool deployed to GitHub Pages. The tool is used by the ASP.NET Core documentation authors to create cross-reference (XREF) links to API documentation for article markdown: - -* [`BlazorWebAssemblyXrefGenerator` sample app (`blazor-samples/BlazorWebAssemblyXrefGenerator`)](https://github.com/dotnet/blazor-samples/tree/main/BlazorWebAssemblyXrefGenerator) -* [Live Xref Generator website](https://dotnet.github.io/blazor-samples/) - -### GitHub Pages settings - -* **Actions** > **General** - * **Actions permissions** - * **Allow enterprise actions, and select non-enterprise, actions and reusable workflows** > Enabled (selected) - * **Allow actions created by GitHub** > Enabled (selected) - * **Allow actions and reusable workflows** > `stevesandersonms/ghaction-rewrite-base-href@{SHA HASH},`† - * **Workflow permissions** > **Read repository contents and packages permissions** -* **Pages** > **Build and deployment** - * **Source** > **GitHub Actions** - * Selected workflow: **Static HTML** and base your static deployment Action script on the [Xref Generator `static.yml` file](https://github.com/dotnet/blazor-samples/blob/main/.github/workflows/static.yml) for the Xref Generator tool. The configuration in the file is described in the next section. - * **Custom domain**: Set if you intend to use a custom domain, which isn't covered by this guidance. For more information, see [Configuring a custom domain for your GitHub Pages site](https://docs.github.com/pages/configuring-a-custom-domain-for-your-github-pages-site). - * **Enforce HTTPS** > Enabled (selected) - -†The SHA hash (`{SHA HASH}` placeholder) represents the SHA hash for the latest `stevesandersonms/ghaction-rewrite-base-href` GitHub Action release version. By pinning to a specific version, there's less risk that a compromised latest release using a version moniker, such as `v1`, can jeopardize the deployment. Periodically, update the SHA to the latest release for the latest features and bug fixes. - -To obtain the SHA hash: - -1. Navigate to the [`SteveSandersonMS/ghaction-rewrite-base-href` Action GitHub repository](https://github.com/SteveSandersonMS/ghaction-rewrite-base-href). -1. Select the release on the right-side of the page under **Releases**. -1. Locate and select the short SHA hash (for example, `5b54862`). -1. Either: - * Take the full SHA from the URL in the browser's address bar. - * Select the copy button on the right side of page ![Copy button](~/blazor/host-and-deploy/index/copy-button.svg) to put the SHA on your clipboard. - -For more information, see [Using pre-written building blocks in your workflow: Using SHAs (GitHub documentation)](https://docs.github.com/actions/writing-workflows/choosing-what-your-workflow-does/using-pre-written-building-blocks-in-your-workflow#using-shas). - -### Static deployment script configuration - -[Xref Generator `static.yml` file](https://github.com/dotnet/blazor-samples/blob/main/.github/workflows/static.yml) - -Configure the following entries in the script for your deployment: - -* Publish directory (`PUBLISH_DIR`): Use the path to the repository's folder where the Blazor WebAssembly app is published. The app is compiled for a specific .NET version, and the path segment for the version must match. Example: `BlazorWebAssemblyXrefGenerator/bin/Release/net9.0/publish/wwwroot` is the path for an app that adopts the `net9.0` [Target Framework Moniker (TFM)](/dotnet/standard/frameworks) for the .NET 9.0 SDK -* Push path (`on:push:paths`): Set the push path to match the app's repo folder with a `**` wildcard. Example: `BlazorWebAssemblyXrefGenerator/**` -* .NET SDK version (`dotnet-version` via the [`actions/setup-dotnet` Action](https://github.com/actions/setup-dotnet)): Currently, there's no way to set the version to "latest" (see [Allow specifying 'latest' as dotnet-version (`actions/setup-dotnet` #497)](https://github.com/actions/setup-dotnet/issues/497) to up-vote the feature request). Set the SDK version at least as high as the app's framework version. -* Publish path (`dotnet publish` command): Set the publish folder path to the app's repo folder. Example: `dotnet publish BlazorWebAssemblyXrefGenerator -c Release` -* Base HREF (`base_href` for the [`SteveSandersonMS/ghaction-rewrite-base-href` Action](https://github.com/SteveSandersonMS/ghaction-rewrite-base-href)): Set the SHA hash for the latest version of the Action (see the guidance in the [*GitHub Pages settings*](#github-pages-settings) section for instructions). Set the base href for the app to the repository's name. Example: The Blazor sample's repository owner is `dotnet`. The Blazor sample's repository's name is `blazor-samples`. When the Xref Generator tool is deployed to GitHub Pages, its web address is based on the repository's name (`https://dotnet.github.io/blazor-samples/`). The base href of the app is `/blazor-samples/`, which is set into `base_href` for the `ghaction-rewrite-base-href` Action to write into the app's `wwwroot/index.html` `` tag when the app is deployed. For more information, see . - -The GitHub-hosted Ubuntu (latest) server has a version of the .NET SDK pre-installed. You can remove the [`actions/setup-dotnet` Action](https://github.com/actions/setup-dotnet) step from the `static.yml` script if the pre-installed .NET SDK is sufficient to compile the app. To determine the .NET SDK installed for `ubuntu-latest`: - -1. Go to the [**Available Images** section of the `actions/runner-images` GitHub repository](https://github.com/actions/runner-images?tab=readme-ov-file#available-images). -1. Locate the `ubuntu-latest` image, which is the first table row. -1. Select the link in the `Included Software` column. -1. Scroll down to the *.NET Tools* section to see the .NET Core SDK installed with the image. - -### Deployment notes - -The default GitHub Action, which deploys pages, skips deployment of folders starting with underscore, the `_framework` folder for example. To deploy folders starting with underscore, add an empty `.nojekyll` file to the root of the app's repository. Example: [Xref Generator `.nojekyll` file](https://github.com/dotnet/blazor-samples/blob/main/BlazorWebAssemblyXrefGenerator/.nojekyll) - -***Perform this step before the first app deployment:*** Git treats JavaScript (JS) files, such as `blazor.webassembly.js`, as text and converts line endings from CRLF (carriage return-line feed) to LF (line feed) in the deployment pipeline. These changes to JS files produce different file hashes than Blazor sends to the client in the `blazor.boot.json` file. The mismatches result in integrity check failures on the client. One approach to solving this problem is to add a `.gitattributes` file with `*.js binary` line before adding the app's assets to the Git branch. The `*.js binary` line configures Git to treat JS files as binary files, which avoids processing the files in the deployment pipeline. The file hashes of the unprocessed files match the entries in the `blazor.boot.json` file, and client-side integrity checks pass. For more information, see . Example: [Xref Generator `.gitattributes` file](https://github.com/dotnet/blazor-samples/blob/main/BlazorWebAssemblyXrefGenerator/.gitattributes) - -To handle URL rewrites based on [Single Page Apps for GitHub Pages (`rafrex/spa-github-pages` GitHub repository)](https://github.com/rafrex/spa-github-pages): - -* Add a `wwwroot/404.html` file with a script that handles redirecting the request to the `index.html` page. Example: [Xref Generator `404.html` file](https://github.com/dotnet/blazor-samples/blob/main/BlazorWebAssemblyXrefGenerator/wwwroot/404.html) -* In `wwwroot/index.html`, add the script to `` content. Example: [Xref Generator `index.html` file](https://github.com/dotnet/blazor-samples/blob/main/BlazorWebAssemblyXrefGenerator/wwwroot/index.html) - -GitHub Pages doesn't natively support using Brotli-compressed resources. To use Brotli: - -* Add the `wwwroot/decode.js` script to the app's `wwwroot` folder. Example: [Xref Generator `decode.js` file](https://github.com/dotnet/blazor-samples/blob/main/BlazorWebAssemblyXrefGenerator/wwwroot/decode.js) -* Add the ` +``` + +After Blazor's ` +``` + +Standalone Blazor WebAssembly: + +:::moniker-end + +```html + +``` + +For more information on loading boot resources, see . + +:::moniker range=">= aspnetcore-8.0" + +To disable compression, add the `CompressionEnabled` MSBuild property to the app's project file and set the value to `false`: + +```xml + + false + +``` + +The `CompressionEnabled` property can be passed to the [`dotnet publish`](/dotnet/core/tools/dotnet-publish) command with the following syntax in a command shell: + +```dotnetcli +dotnet publish -p:CompressionEnabled=false +``` + +:::moniker-end + +:::moniker range="< aspnetcore-8.0" + +To disable compression, add the `BlazorEnableCompression` MSBuild property to the app's project file and set the value to `false`: + +```xml + + false + +``` + +The `BlazorEnableCompression` property can be passed to the [`dotnet publish`](/dotnet/core/tools/dotnet-publish) command with the following syntax in a command shell: + +```dotnetcli +dotnet publish -p:BlazorEnableCompression=false +``` + +:::moniker-end + +## Rewrite URLs for correct routing + +Routing requests for page components in a Blazor WebAssembly app isn't as straightforward as routing requests in a Blazor Server app. Consider a Blazor WebAssembly app with two components: + +* `Main.razor`: Loads at the root of the app and contains a link to the `About` component (`href="About"`). +* `About.razor`: `About` component. + +When the app's default document is requested using the browser's address bar (for example, `https://www.contoso.com/`): + +1. The browser makes a request. +1. The default page is returned, which is usually `index.html`. +1. `index.html` bootstraps the app. +1. component loads, and the Razor `Main` component is rendered. + +In the Main page, selecting the link to the `About` component works on the client because the Blazor router stops the browser from making a request on the Internet to `www.contoso.com` for `About` and serves the rendered `About` component itself. All of the requests for internal endpoints *within the Blazor WebAssembly app* work the same way: Requests don't trigger browser-based requests to server-hosted resources on the Internet. The router handles the requests internally. + +If a request is made using the browser's address bar for `www.contoso.com/About`, the request fails. No such resource exists on the app's Internet host, so a *404 - Not Found* response is returned. + +Because browsers make requests to Internet-based hosts for client-side pages, web servers and hosting services must rewrite all requests for resources not physically on the server to the `index.html` page. When `index.html` is returned, the app's Blazor router takes over and responds with the correct resource. + +When deploying to an IIS server, you can use the URL Rewrite Module with the app's published `web.config` file. For more information, see . + +:::moniker range="< aspnetcore-8.0" + +## Hosted deployment with ASP.NET Core + +A *hosted deployment* serves the Blazor WebAssembly app to browsers from an [ASP.NET Core app](xref:index) that runs on a web server. + +The client Blazor WebAssembly app is published into the `/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot` folder of the server app, along with any other static web assets of the server app. The two apps are deployed together. A web server that is capable of hosting an ASP.NET Core app is required. For a hosted deployment, Visual Studio includes the **Blazor WebAssembly App** project template (`blazorwasm` template when using the [`dotnet new`](/dotnet/core/tools/dotnet-new) command) with the **`Hosted`** option selected (`-ho|--hosted` when using the `dotnet new` command). + +For more information, see the following articles: + +* ASP.NET Core app hosting and deployment: +* Deployment to Azure App Service: +* Blazor project templates: + +## Hosted deployment of a framework-dependent executable for a specific platform + +To deploy a hosted Blazor WebAssembly app as a [framework-dependent executable for a specific platform](/dotnet/core/deploying/#publish-framework-dependent) (not self-contained) use the following guidance based on the tooling in use. + +### Visual Studio + +A [self-contained](/dotnet/core/deploying/#publish-self-contained) deployment is configured for a generated publish profile (`.pubxml`). Confirm that the **:::no-loc text="Server":::** project's publish profile contains the `` MSBuild property set to `false`. + +In the `.pubxml` publish profile file in the **:::no-loc text="Server":::** project's `Properties` folder: + +```xml +false +``` + +Set the [Runtime Identifier (RID)](/dotnet/core/rid-catalog) using the **Target Runtime** setting in the **Settings** area of the **Publish** UI, which generates the `` MSBuild property in the publish profile: + +```xml +{RID} +``` + +In the preceding configuration, the `{RID}` placeholder is the [Runtime Identifier (RID)](/dotnet/core/rid-catalog). + +Publish the **:::no-loc text="Server":::** project in the **Release** configuration. + +> [!NOTE] +> It's possible to publish an app with publish profile settings using the .NET CLI by passing `/p:PublishProfile={PROFILE}` to the [`dotnet publish` command](/dotnet/core/tools/dotnet-publish), where the `{PROFILE}` placeholder is the profile. For more information, see the *Publish profiles* and *Folder publish example* sections in the article. If you pass the RID in the [`dotnet publish` command](/dotnet/core/tools/dotnet-publish) and not in the publish profile, use the MSBuild property (`/p:RuntimeIdentifier`) with the command, not with the `-r|--runtime` option. + +### .NET CLI + +Configure a [self-contained](/dotnet/core/deploying/#publish-self-contained) deployment by placing the `` MSBuild property in a `` in the **:::no-loc text="Server":::** project's project file set to `false`: + +```xml +false +``` + +> [!IMPORTANT] +> The `SelfContained` property must be placed in the **:::no-loc text="Server":::** project's project file. The property can't be set correctly with the [`dotnet publish` command](/dotnet/core/tools/dotnet-publish) using the `--no-self-contained` option or the MSBuild property `/p:SelfContained=false`. + +Set the [Runtime Identifier (RID)](/dotnet/core/rid-catalog) using ***either*** of the following approaches: + +* Option 1: Set the RID in a `` in the **:::no-loc text="Server":::** project's project file: + + ```xml + {RID} + ``` + + In the preceding configuration, the `{RID}` placeholder is the [Runtime Identifier (RID)](/dotnet/core/rid-catalog). + + Publish the app in the Release configuration from the **:::no-loc text="Server":::** project: + + ```dotnetcli + dotnet publish -c Release + ``` + +* Option 2: Pass the RID in the [`dotnet publish` command](/dotnet/core/tools/dotnet-publish) as the MSBuild property (`/p:RuntimeIdentifier`), not with the `-r|--runtime` option: + + ```dotnetcli + dotnet publish -c Release /p:RuntimeIdentifier={RID} + ``` + + In the preceding command, the `{RID}` placeholder is the [Runtime Identifier (RID)](/dotnet/core/rid-catalog). + +For more information, see the following articles: + +* [.NET application publishing overview](/dotnet/core/deploying/) +* + +:::moniker-end + +## Standalone deployment + +A *standalone deployment* serves the Blazor WebAssembly app as a set of static files that are requested directly by clients. Any static file server is able to serve the Blazor app. + +Standalone deployment assets are published into either the `/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot` or `bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish\` folder (depending on the version of the .NET SDK in use), where the `{TARGET FRAMEWORK}` placeholder is the target framework. + +## Azure App Service + +Blazor WebAssembly apps can be deployed to Azure App Services on Windows, which hosts the app on IIS. + +Deploying a standalone Blazor WebAssembly app to Azure App Service for Linux isn't currently supported. We recommend hosting a standalone Blazor WebAssembly app using [Azure Static Web Apps](xref:blazor/host-and-deploy/webassembly/azure-static-web-apps), which supports this scenario. + +## Standalone with Docker + +A standalone Blazor WebAssembly app is published as a set of static files for hosting by a static file server. + +To host the app in Docker: + +* Choose a Docker container with web server support, such as Nginx or Apache. +* Copy the `publish` folder assets to a location folder defined in the web server for serving static files. +* Apply additional configuration as needed to serve the Blazor WebAssembly app. + +For configuration guidance, see the following resources: + +* [Nginx](xref:blazor/host-and-deploy/webassembly/nginx) or [Apache](xref:blazor/host-and-deploy/webassembly/apache) articles +* [Docker Documentation](https://docs.docker.com/) + +## Host configuration values + +[Blazor WebAssembly apps](xref:blazor/hosting-models#blazor-webassembly) can accept the following host configuration values as command-line arguments at runtime in the development environment. + +### Content root + +The `--contentroot` argument sets the absolute path to the directory that contains the app's content files ([content root](xref:fundamentals/index#content-root)). In the following examples, `/content-root-path` is the app's content root path. + +* Pass the argument when running the app locally at a command prompt. From the app's directory, execute: + + ```dotnetcli + dotnet watch --contentroot=/content-root-path + ``` + +* Add an entry to the app's `launchSettings.json` file in the **IIS Express** profile. This setting is used when the app is run with the Visual Studio Debugger and from a command prompt with `dotnet watch` (or `dotnet run`). + + ```json + "commandLineArgs": "--contentroot=/content-root-path" + ``` + +* In Visual Studio, specify the argument in **Properties** > **Debug** > **Application arguments**. Setting the argument in the Visual Studio property page adds the argument to the `launchSettings.json` file. + + ```console + --contentroot=/content-root-path + ``` + +### Path base + +The `--pathbase` argument sets the app base path for an app run locally with a non-root relative URL path (the `` tag `href` is set to a path other than `/` for staging and production). In the following examples, `/relative-URL-path` is the app's path base. For more information, see . + +> [!IMPORTANT] +> Unlike the path provided to `href` of the `` tag, don't include a trailing slash (`/`) when passing the `--pathbase` argument value. If the app base path is provided in the `` tag as `` (includes a trailing slash), pass the command-line argument value as `--pathbase=/CoolApp` (no trailing slash). + +* Pass the argument when running the app locally at a command prompt. From the app's directory, execute: + + ```dotnetcli + dotnet watch --pathbase=/relative-URL-path + ``` + +* Add an entry to the app's `launchSettings.json` file in the **IIS Express** profile. This setting is used when running the app with the Visual Studio Debugger and from a command prompt with `dotnet watch` (or `dotnet run`). + + ```json + "commandLineArgs": "--pathbase=/relative-URL-path" + ``` + +* In Visual Studio, specify the argument in **Properties** > **Debug** > **Application arguments**. Setting the argument in the Visual Studio property page adds the argument to the `launchSettings.json` file. + + ```console + --pathbase=/relative-URL-path + ``` + +For more information, see . + +### URLs + +The `--urls` argument sets the IP addresses or host addresses with ports and protocols to listen on for requests. + +* Pass the argument when running the app locally at a command prompt. From the app's directory, execute: + + ```dotnetcli + dotnet watch --urls=http://127.0.0.1:0 + ``` + +* Add an entry to the app's `launchSettings.json` file in the **IIS Express** profile. This setting is used when running the app with the Visual Studio Debugger and from a command prompt with `dotnet watch` (or `dotnet run`). + + ```json + "commandLineArgs": "--urls=http://127.0.0.1:0" + ``` + +* In Visual Studio, specify the argument in **Properties** > **Debug** > **Application arguments**. Setting the argument in the Visual Studio property page adds the argument to the `launchSettings.json` file. + + ```console + --urls=http://127.0.0.1:0 + ``` + +:::moniker range=">= aspnetcore-5.0" + +## Configure the Trimmer + +Blazor performs Intermediate Language (IL) trimming on each Release build to remove unnecessary IL from the output assemblies. For more information, see . + +:::moniker-end + +:::moniker range="< aspnetcore-5.0" + +## Configure the Linker + +Blazor performs Intermediate Language (IL) linking on each Release build to remove unnecessary IL from the output assemblies. For more information, see . + +:::moniker-end + +:::moniker range=">= aspnetcore-5.0" + +## Change the file name extension of DLL files + +*This section applies to ASP.NET Core 6.x and 7.x. In ASP.NET Core in .NET 8 or later, .NET assemblies are deployed as WebAssembly files (`.wasm`) using the Webcil file format. In ASP.NET Core in .NET 8 or later, this section only applies if the Webcil file format has been disabled in the app's project file.* + +If a firewall, anti-virus program, or network security appliance is blocking the transmission of the app's dynamic-link library (DLL) files (`.dll`), you can follow the guidance in this section to change the file name extensions of the app's published DLL files. + +:::moniker-end + +:::moniker range=">= aspnetcore-8.0" + +> [!NOTE] +> Changing the file name extensions of the app's DLL files might not resolve the problem because many security systems scan the content of the app's files, not merely check file extensions. +> +> For a more robust approach in environments that block the download and execution of DLL files, use ASP.NET Core in .NET 8 or later, which packages .NET assemblies as WebAssembly files (`.wasm`) using the [Webcil](https://github.com/dotnet/runtime/blob/main/docs/design/mono/webcil.md) file format. For more information, see the *Webcil packaging format for .NET assemblies* section in an 8.0 or later version of this article. +> +> Third-party approaches exist for dealing with this problem. For more information, see the resources at [Awesome Blazor](https://github.com/AdrienTorris/awesome-blazor). + +:::moniker-end + +:::moniker range=">= aspnetcore-5.0 < aspnetcore-8.0" + +> [!NOTE] +> Changing the file name extensions of the app's DLL files might not resolve the problem because many security systems scan the content of the app's files, not merely check file extensions. +> +> For a more robust approach in environments that block the download and execution of DLL files, take ***either*** of the following approaches: +> +> * Use ASP.NET Core in .NET 8 or later, which packages .NET assemblies as WebAssembly files (`.wasm`) using the [Webcil](https://github.com/dotnet/runtime/blob/main/docs/design/mono/webcil.md) file format. For more information, see the *Webcil packaging format for .NET assemblies* section in an 8.0 or later version of this article. +> * In ASP.NET Core in .NET 6 or later, use a [custom deployment layout](xref:blazor/host-and-deploy/webassembly/deployment-layout). +> +> Third-party approaches exist for dealing with this problem. For more information, see the resources at [Awesome Blazor](https://github.com/AdrienTorris/awesome-blazor). + +:::moniker-end + +:::moniker range=">= aspnetcore-5.0" + +After publishing the app, use a shell script or DevOps build pipeline to rename `.dll` files to use a different file extension in the directory of the app's published output. + +In the following examples: + +* PowerShell (PS) is used to update the file extensions. +* `.dll` files are renamed to use the `.bin` file extension from the command line. +* Files listed in the published `blazor.boot.json` file with a `.dll` file extension are updated to the `.bin` file extension. +* If service worker assets are also in use, a PowerShell command updates the `.dll` files listed in the `service-worker-assets.js` file to the `.bin` file extension. + +To use a different file extension than `.bin`, replace `.bin` in the following commands with the desired file extension. + +On Windows: + +```powershell +dir {PATH} | rename-item -NewName { $_.name -replace ".dll\b",".bin" } +((Get-Content {PATH}\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content {PATH}\blazor.boot.json +``` + +In the preceding command, the `{PATH}` placeholder is the path to the published `_framework` folder (for example, `.\bin\Release\net6.0\browser-wasm\publish\wwwroot\_framework` from the project's root folder). + +If service worker assets are also in use: + +```powershell +((Get-Content {PATH}\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content {PATH}\service-worker-assets.js +``` + +In the preceding command, the `{PATH}` placeholder is the path to the published `service-worker-assets.js` file. + +On Linux or macOS: + +```console +for f in {PATH}/*; do mv "$f" "`echo $f | sed -e 's/\.dll/.bin/g'`"; done +sed -i 's/\.dll"/.bin"/g' {PATH}/blazor.boot.json +``` + +In the preceding command, the `{PATH}` placeholder is the path to the published `_framework` folder (for example, `.\bin\Release\net6.0\browser-wasm\publish\wwwroot\_framework` from the project's root folder). + +If service worker assets are also in use: + +```console +sed -i 's/\.dll"/.bin"/g' {PATH}/service-worker-assets.js +``` + +In the preceding command, the `{PATH}` placeholder is the path to the published `service-worker-assets.js` file. + +To address the compressed `blazor.boot.json.gz` and `blazor.boot.json.br` files, adopt either of the following approaches: + +* Remove the compressed `blazor.boot.json.gz` and `blazor.boot.json.br` files. **Compression is disabled with this approach.** +* Recompress the updated `blazor.boot.json` file. + +The preceding guidance for the compressed `blazor.boot.json` file also applies when service worker assets are in use. Remove or recompress `service-worker-assets.js.br` and `service-worker-assets.js.gz`. Otherwise, file integrity checks fail in the browser. + +The following Windows example for .NET 6 uses a PowerShell script placed at the root of the project. The following script, which disables compression, is the basis for further modification if you wish to recompress the `blazor.boot.json` file. + +`ChangeDLLExtensions.ps1:`: + +```powershell +param([string]$filepath,[string]$tfm) +dir $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework | rename-item -NewName { $_.name -replace ".dll\b",".bin" } +((Get-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json +Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json.gz +Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json.br +``` + +If service worker assets are also in use, add the following commands: + +```powershell +((Get-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js +Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js.gz +Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js.br +``` + +In the project file, the script is executed after publishing the app for the `Release` configuration: + +```xml + + + +``` + +> [!NOTE] +> When renaming and lazy loading the same assemblies, see the guidance in . + +Usually, the app's server requires static asset configuration to serve the files with the updated extension. For an app hosted by IIS, add a MIME map entry (``) for the new file extension in the static content section (``) in a custom `web.config` file. The following example assumes that the file extension is changed from `.dll` to `.bin`: + +```xml + + ... + + ... + +``` + +Include an update for compressed files if [compression](#compression) is in use: + +``` + + +``` + +Remove the entry for the `.dll` file extension: + +```diff +- +``` + +Remove entries for compressed `.dll` files if [compression](#compression) is in use: + +```diff +- +- +``` + +For more information on custom `web.config` files, see the [Use of a custom `web.config`](xref:blazor/host-and-deploy/webassembly/iis#use-of-a-custom-webconfig) section. + +:::moniker-end + +## Prior deployment corruption + +Typically on deployment: + +* Only the files that have changed are replaced, which usually results in a faster deployment. +* Existing files that aren't part of the new deployment are left in place for use by the new deployment. + +In rare cases, lingering files from a prior deployment can corrupt a new deployment. Completely deleting the existing deployment (or locally-published app prior to deployment) may resolve the issue with a corrupted deployment. Often, deleting the existing deployment ***once*** is sufficient to resolve the problem, including for a DevOps build and deploy pipeline. + +If you determine that clearing a prior deployment is always required when a DevOps build and deploy pipeline is in use, you can temporarily add a step to the build pipeline to delete the prior deployment for each new deployment until you troubleshoot the exact cause of the corruption. diff --git a/aspnetcore/blazor/host-and-deploy/multiple-hosted-webassembly.md b/aspnetcore/blazor/host-and-deploy/webassembly/multiple-hosted-webassembly.md similarity index 99% rename from aspnetcore/blazor/host-and-deploy/multiple-hosted-webassembly.md rename to aspnetcore/blazor/host-and-deploy/webassembly/multiple-hosted-webassembly.md index da45725523ba..002972171e63 100644 --- a/aspnetcore/blazor/host-and-deploy/multiple-hosted-webassembly.md +++ b/aspnetcore/blazor/host-and-deploy/webassembly/multiple-hosted-webassembly.md @@ -6,7 +6,7 @@ monikerRange: '>= aspnetcore-3.1 < aspnetcore-8.0' ms.author: riande ms.custom: mvc ms.date: 11/12/2024 -uid: blazor/host-and-deploy/multiple-hosted-webassembly +uid: blazor/host-and-deploy/webassembly/multiple-hosted-webassembly zone_pivot_groups: blazor-multiple-hosted-wasm-apps --- # Multiple hosted ASP.NET Core Blazor WebAssembly apps @@ -64,7 +64,7 @@ The examples shown in this article require additional configuration for: The preceding configurations are beyond the scope of this article. For more information, see the following resources: -* [Host and deploy articles](xref:host-and-deploy/index) +* * * diff --git a/aspnetcore/blazor/host-and-deploy/webassembly/nginx.md b/aspnetcore/blazor/host-and-deploy/webassembly/nginx.md new file mode 100644 index 000000000000..e63725c6f7e6 --- /dev/null +++ b/aspnetcore/blazor/host-and-deploy/webassembly/nginx.md @@ -0,0 +1,104 @@ +--- +title: Host and deploy ASP.NET Core Blazor WebAssembly with Nginx +author: guardrex +description: Learn how to host and deploy Blazor WebAssembly using Nginx. +monikerRange: '>= aspnetcore-3.1' +ms.author: riande +ms.custom: mvc, linux-related-content +ms.date: 03/31/2025 +uid: blazor/host-and-deploy/webassembly/nginx +--- +# Host and deploy ASP.NET Core Blazor WebAssembly with Nginx + +[!INCLUDE[](~/includes/not-latest-version.md)] + +This article explains how to host and deploy Blazor WebAssembly using [Nginx](https://nginx.org/). + +The following `nginx.conf` file is simplified to show how to configure Nginx to send the `index.html` file whenever it can't find a corresponding file on disk. + +``` +events { } +http { + server { + listen 80; + + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html =404; + } + } +} +``` + +When setting the [NGINX burst rate limit](https://www.nginx.com/blog/rate-limiting-nginx/#bursts) with [`limit_req`](https://nginx.org/docs/http/ngx_http_limit_req_module.html#limit_req) and [`limit_req_zone`](https://nginx.org/docs/http/ngx_http_limit_req_module.html), Blazor WebAssembly apps may require a large `burst`/`rate` parameter values to accommodate the relatively large number of requests made by an app. Initially, set the value to at least 60: + +``` +http { + limit_req_zone $binary_remote_addr zone=one:10m rate=60r/s; + server { + ... + + location / { + ... + + limit_req zone=one burst=60 nodelay; + } + } +} +``` + +Increase the value if browser developer tools or a network traffic tool indicates that requests are receiving a *503 - Service Unavailable* status code. + +For more information on production Nginx web server configuration, see [Creating NGINX Plus and NGINX Configuration Files](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/). + +:::moniker range="< aspnetcore-8.0" + +## Hosted deployment on Linux (Nginx) + +Configure the app with to forward the `X-Forwarded-For` and `X-Forwarded-Proto` headers by following the guidance in . + +For more information on setting the app's base path, including sub-app path configuration, see . + +Follow the guidance for an [ASP.NET Core SignalR app](xref:signalr/scale#linux-with-nginx) with the following changes: + +* Remove the configuration for proxy buffering (`proxy_buffering off;`) because the setting only applies to [Server-Sent Events (SSE)](https://developer.mozilla.org/docs/Web/API/Server-sent_events), which aren't relevant to Blazor app client-server interactions. +* Change the `location` path from `/hubroute` (`location /hubroute { ... }`) to the sub-app path `/{PATH}` (`location /{PATH} { ... }`), where the `{PATH}` placeholder is the sub-app path. + + The following example configures the server for an app that responds to requests at the root path `/`: + + ``` + http { + server { + ... + location / { + ... + } + } + } + ``` + + The following example configures the sub-app path of `/blazor`: + + ``` + http { + server { + ... + location /blazor { + ... + } + } + } + ``` + +:::moniker-end + +## Additional resources + +* +* Nginx documentation: + * [NGINX as a WebSocket Proxy](https://www.nginx.com/blog/websocket-nginx/) + * [WebSocket proxying](http://nginx.org/docs/http/websocket.html) +* Developers on non-Microsoft support forums: + * [Stack Overflow (tag: `blazor`)](https://stackoverflow.com/questions/tagged/blazor) + * [ASP.NET Core Slack Team](https://join.slack.com/t/aspnetcore/shared_invite/zt-1mv5487zb-EOZxJ1iqb0A0ajowEbxByQ) + * [Blazor Gitter](https://gitter.im/aspnet/Blazor) diff --git a/aspnetcore/blazor/host-and-deploy/webassembly-caching/index.md b/aspnetcore/blazor/host-and-deploy/webassembly/runtime-and-app-bundle-caching.md similarity index 97% rename from aspnetcore/blazor/host-and-deploy/webassembly-caching/index.md rename to aspnetcore/blazor/host-and-deploy/webassembly/runtime-and-app-bundle-caching.md index 7238f0f758b9..279daea37acb 100644 --- a/aspnetcore/blazor/host-and-deploy/webassembly-caching/index.md +++ b/aspnetcore/blazor/host-and-deploy/webassembly/runtime-and-app-bundle-caching.md @@ -1,17 +1,19 @@ --- title: ASP.NET Core Blazor WebAssembly .NET runtime and app bundle caching author: guardrex -description: Learn how to Blazor WebAssembly caches the WebAssembly .NET runtime and app bundle, how to disable caching, and how to diagnose integrity failures. +description: Learn how Blazor WebAssembly caches the WebAssembly .NET runtime and app bundle, how to disable caching, and how to diagnose integrity failures. monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc ms.date: 11/12/2024 -uid: blazor/host-and-deploy/webassembly-caching/index +uid: blazor/host-and-deploy/webassembly/runtime-and-app-bundle-caching --- # ASP.NET Core Blazor WebAssembly .NET runtime and app bundle caching [!INCLUDE[](~/includes/not-latest-version.md)] +This article explains how Blazor WebAssembly caches the WebAssembly .NET runtime and app bundle, how to disable caching, and how to diagnose integrity failures. + When a Blazor WebAssembly app loads in the browser, the app downloads boot resources from the server: * JavaScript code to bootstrap the app diff --git a/aspnetcore/blazor/performance.md b/aspnetcore/blazor/performance.md index 953c8b57f8d5..908ee0f3b7df 100644 --- a/aspnetcore/blazor/performance.md +++ b/aspnetcore/blazor/performance.md @@ -109,7 +109,7 @@ In a test performed by the ASP.NET Core product unit engineers, a rendering over It's possible to make components more lightweight so that you can have more of them. However, a more powerful technique is often to avoid having so many components to render. The following sections describe two approaches that you can take. -For more information on memory management, see . +For more information on memory management, see . ##### Inline child components into their parents @@ -801,7 +801,7 @@ Load assemblies at runtime when the assemblies are required by a route. For more When a Blazor WebAssembly app is published, the output is statically compressed during publish to reduce the app's size and remove the overhead for runtime compression. Blazor relies on the server to perform content negotiation and serve statically-compressed files. -After an app is deployed, verify that the app serves compressed files. Inspect the **Network** tab in a browser's [developer tools](https://developer.mozilla.org/docs/Glossary/Developer_Tools) and verify that the files are served with `Content-Encoding: br` (Brotli compression) or `Content-Encoding: gz` (Gzip compression). If the host isn't serving compressed files, follow the instructions in . +After an app is deployed, verify that the app serves compressed files. Inspect the **Network** tab in a browser's [developer tools](https://developer.mozilla.org/docs/Glossary/Developer_Tools) and verify that the files are served with `Content-Encoding: br` (Brotli compression) or `Content-Encoding: gz` (Gzip compression). If the host isn't serving compressed files, follow the instructions in . ### Disable unused features diff --git a/aspnetcore/blazor/progressive-web-app.md b/aspnetcore/blazor/progressive-web-app.md index ba74005514df..adc93c025b43 100644 --- a/aspnetcore/blazor/progressive-web-app.md +++ b/aspnetcore/blazor/progressive-web-app.md @@ -405,5 +405,5 @@ The [`CarChecker`](https://github.com/SteveSandersonMS/CarChecker) sample app de ## Additional resources -* [Troubleshoot integrity PowerShell script](xref:blazor/host-and-deploy/webassembly-caching/index#troubleshoot-integrity-powershell-script) +* [Troubleshoot integrity PowerShell script](xref:blazor/host-and-deploy/webassembly/runtime-and-app-bundle-caching#troubleshoot-integrity-powershell-script) * [Client-side SignalR cross-origin negotiation for authentication](xref:blazor/fundamentals/signalr#client-side-signalr-cross-origin-negotiation-for-authentication) diff --git a/aspnetcore/blazor/security/interactive-server-side-rendering.md b/aspnetcore/blazor/security/interactive-server-side-rendering.md index 24ad1cb8a1d6..dbb742a46ef1 100644 --- a/aspnetcore/blazor/security/interactive-server-side-rendering.md +++ b/aspnetcore/blazor/security/interactive-server-side-rendering.md @@ -146,7 +146,7 @@ There's no limit on the number of connections per user for an app. If the app re * Proxy WebSocket connections to an app through the use of a proxy, such as the [Azure SignalR Service](/azure/azure-signalr/signalr-overview) that multiplexes connections from clients to an app. This provides an app with greater connection capacity than a single client can establish, preventing a client from exhausting the connections to the server. * Server level * Use a proxy/gateway in front of the app. - * Although Long Polling is supported for Blazor apps, [WebSockets is the recommended transport protocol](xref:blazor/host-and-deploy/server#azure-signalr-service). We recommend selecting a proxy/gateway that supports WebSockets. + * Although Long Polling is supported for Blazor apps, [WebSockets is the recommended transport protocol](xref:blazor/host-and-deploy/server/index#azure-signalr-service). We recommend selecting a proxy/gateway that supports WebSockets. :::moniker-end diff --git a/aspnetcore/blazor/security/webassembly/additional-scenarios.md b/aspnetcore/blazor/security/webassembly/additional-scenarios.md index 363867fea0d6..60357204f413 100644 --- a/aspnetcore/blazor/security/webassembly/additional-scenarios.md +++ b/aspnetcore/blazor/security/webassembly/additional-scenarios.md @@ -1536,7 +1536,7 @@ If an app requires a custom version of the [Microsoft Authentication Library for 1. Set up the `dotnet/aspnetcore` GitHub repository for development following the documentation at [Build ASP.NET Core from Source](https://github.com/dotnet/aspnetcore/blob/main/docs/BuildFromSource.md). Fork and clone or download a ZIP archive of the [`dotnet/aspnetcore` GitHub repository](https://github.com/dotnet/aspnetcore). 1. Open the `src/Components/WebAssembly/Authentication.Msal/src/Interop/package.json` file and set the desired version of `@azure/msal-browser`. For a list of released versions, visit the [`@azure/msal-browser` npm website](https://www.npmjs.com/package/@azure/msal-browser) and select the **Versions** tab. 1. Build the `Authentication.Msal` project in the `src/Components/WebAssembly/Authentication.Msal/src` folder with the `yarn build` command in a command shell. -1. If the app uses [compressed assets (Brotli/Gzip)](xref:blazor/host-and-deploy/webassembly#compression), compress the `Interop/dist/Release/AuthenticationService.js` file. +1. If the app uses [compressed assets (Brotli/Gzip)](xref:blazor/host-and-deploy/webassembly/index#compression), compress the `Interop/dist/Release/AuthenticationService.js` file. 1. Copy the `AuthenticationService.js` file and compressed versions (`.br`/`.gz`) of the file, if produced, from the `Interop/dist/Release` folder into the app's `publish/wwwroot/_content/Microsoft.Authentication.WebAssembly.Msal` folder in the app's published assets. ## Pass custom provider options diff --git a/aspnetcore/blazor/tutorials/signalr-blazor.md b/aspnetcore/blazor/tutorials/signalr-blazor.md index cde1ef913174..82c0d4b77024 100644 --- a/aspnetcore/blazor/tutorials/signalr-blazor.md +++ b/aspnetcore/blazor/tutorials/signalr-blazor.md @@ -613,6 +613,6 @@ For detailed guidance on the SignalR and Blazor frameworks, see the following re * [Bearer token authentication with Identity Server, WebSockets, and Server-Sent Events](xref:signalr/authn-and-authz#bearer-token-authentication) * [Secure a SignalR hub in Blazor WebAssembly apps](xref:blazor/security/webassembly/index#secure-a-signalr-hub) * [SignalR cross-origin negotiation for authentication](xref:blazor/fundamentals/signalr#client-side-signalr-cross-origin-negotiation-for-authentication) -* [SignalR configuration](xref:blazor/host-and-deploy/server#signalr-configuration) +* [SignalR configuration](xref:blazor/host-and-deploy/server/index#signalr-configuration) * * [Blazor samples GitHub repository (`dotnet/blazor-samples`)](https://github.com/dotnet/blazor-samples) ([how to download](xref:blazor/fundamentals/index#sample-apps)) diff --git a/aspnetcore/blazor/webassembly-build-tools-and-aot.md b/aspnetcore/blazor/webassembly-build-tools-and-aot.md index 0f36894d8757..44947912185b 100644 --- a/aspnetcore/blazor/webassembly-build-tools-and-aot.md +++ b/aspnetcore/blazor/webassembly-build-tools-and-aot.md @@ -109,7 +109,7 @@ Disable the trimming property if it prevents your app from running normally: ## Heap size for some mobile device browsers -When building a Blazor app that runs on the client and targets mobile device browsers, especially Safari on iOS, decreasing the maximum memory for the app with the MSBuild property `EmccMaximumHeapSize` may be required. For more information, see . +When building a Blazor app that runs on the client and targets mobile device browsers, especially Safari on iOS, decreasing the maximum memory for the app with the MSBuild property `EmccMaximumHeapSize` may be required. For more information, see . ## Runtime relinking @@ -190,4 +190,4 @@ For more information, see the following resources: ## Additional resources * -* [Webcil packaging format for .NET assemblies](xref:blazor/host-and-deploy/webassembly#webcil-packaging-format-for-net-assemblies) +* [Webcil packaging format for .NET assemblies](xref:blazor/host-and-deploy/webassembly/index#webcil-packaging-format-for-net-assemblies) diff --git a/aspnetcore/blazor/webassembly-lazy-load-assemblies.md b/aspnetcore/blazor/webassembly-lazy-load-assemblies.md index be4f76b6bef7..8d5c24bd9e35 100644 --- a/aspnetcore/blazor/webassembly-lazy-load-assemblies.md +++ b/aspnetcore/blazor/webassembly-lazy-load-assemblies.md @@ -24,7 +24,7 @@ Lazy loading shouldn't be used for core runtime assemblies, which might be trimm :::moniker range=">= aspnetcore-8.0" -Assembly files use the [Webcil packaging format for .NET assemblies](xref:blazor/host-and-deploy/webassembly#webcil-packaging-format-for-net-assemblies) with a `.wasm` file extension. +Assembly files use the [Webcil packaging format for .NET assemblies](xref:blazor/host-and-deploy/webassembly/index#webcil-packaging-format-for-net-assemblies) with a `.wasm` file extension. Throughout the article, the `{FILE EXTENSION}` placeholder represents "`wasm`". @@ -353,7 +353,7 @@ For more information, see callback and the assembly names in the `blazor.boot.json` file are out of sync. +The resource loader relies on the assembly names that are defined in the `blazor.boot.json` file. If [assemblies are renamed](xref:blazor/host-and-deploy/webassembly/index#change-the-file-name-extension-of-dll-files), the assembly names used in an callback and the assembly names in the `blazor.boot.json` file are out of sync. To rectify this: diff --git a/aspnetcore/fundamentals/dependency-injection.md b/aspnetcore/fundamentals/dependency-injection.md index 998ff0c061c4..81b327580b46 100644 --- a/aspnetcore/fundamentals/dependency-injection.md +++ b/aspnetcore/fundamentals/dependency-injection.md @@ -252,7 +252,7 @@ The debug console shows the following output after each refresh of the Index pag ```console Service1: IndexModel.OnGet Service2: IndexModel.OnGet -Service3: IndexModel.OnGet, MyKey = MyKey from appsettings.Developement.json +Service3: IndexModel.OnGet, MyKey = MyKey from appsettings.Development.json Service1.Dispose ``` diff --git a/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md b/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md index 2091a327fad3..352d6cf6c832 100644 --- a/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md +++ b/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md @@ -228,7 +228,7 @@ The debug console shows the following output after each refresh of the Index pag ```console Service1: IndexModel.OnGet Service2: IndexModel.OnGet -Service3: IndexModel.OnGet, MyKey = MyKey from appsettings.Developement.json +Service3: IndexModel.OnGet, MyKey = MyKey from appsettings.Development.json Service1.Dispose ``` diff --git a/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md b/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md index 5a5b0d2bc45d..bae19be3f660 100644 --- a/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md +++ b/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md @@ -234,7 +234,7 @@ The debug console shows the following output after each refresh of the Index pag ```console Service1: IndexModel.OnGet Service2: IndexModel.OnGet -Service3: IndexModel.OnGet, MyKey = MyKey from appsettings.Developement.json +Service3: IndexModel.OnGet, MyKey = MyKey from appsettings.Development.json Service1.Dispose ``` diff --git a/aspnetcore/fundamentals/dependency-injection/samples/3.x/DependencyInjectionSample/appsettings.Development.json b/aspnetcore/fundamentals/dependency-injection/samples/3.x/DependencyInjectionSample/appsettings.Development.json index aa8aa8654eaa..b7a0bcb1a810 100644 --- a/aspnetcore/fundamentals/dependency-injection/samples/3.x/DependencyInjectionSample/appsettings.Development.json +++ b/aspnetcore/fundamentals/dependency-injection/samples/3.x/DependencyInjectionSample/appsettings.Development.json @@ -1,5 +1,5 @@ { - "MyKey": "MyKey from appsettings.Developement.json", + "MyKey": "MyKey from appsettings.Development.json", "Logging": { "LogLevel": { "Default": "Information", diff --git a/aspnetcore/fundamentals/dependency-injection/samples/6.x/DIsample2/DIsample2/appsettings.Development.json b/aspnetcore/fundamentals/dependency-injection/samples/6.x/DIsample2/DIsample2/appsettings.Development.json index 89e0471a71f3..8227d7469ce1 100644 --- a/aspnetcore/fundamentals/dependency-injection/samples/6.x/DIsample2/DIsample2/appsettings.Development.json +++ b/aspnetcore/fundamentals/dependency-injection/samples/6.x/DIsample2/DIsample2/appsettings.Development.json @@ -1,6 +1,6 @@ { "DetailedErrors": true, - "MyKey": "MyKey from appsettings.Developement.json", + "MyKey": "MyKey from appsettings.Development.json", "Logging": { "LogLevel": { "Default": "Information", diff --git a/aspnetcore/host-and-deploy/docker/building-net-docker-images.md b/aspnetcore/host-and-deploy/docker/building-net-docker-images.md index 2145f5e9f8ee..dbbfeb54538c 100644 --- a/aspnetcore/host-and-deploy/docker/building-net-docker-images.md +++ b/aspnetcore/host-and-deploy/docker/building-net-docker-images.md @@ -18,177 +18,7 @@ Windows Home Edition doesn't support Hyper-V, and Hyper-V is needed for Docker. See [Containerize a .NET app with dotnet publish](/dotnet/core/docker/publish-as-container) for information on containerized a .NET app with `dotnet publish`. -:::moniker range=">= aspnetcore-8.0" - -## ASP.NET Core Docker images - -For this tutorial, you download an ASP.NET Core sample app and run it in Docker containers. The sample works with both Linux and Windows containers. - -The sample Dockerfile uses the [Docker multi-stage build feature](https://docs.docker.com/engine/userguide/eng-image/multistage-build/) to build and run in different containers. The build and run containers are created from images that are provided in Docker Hub by Microsoft: - -* `dotnet/sdk` - - The sample uses this image for building the app. The image contains the .NET SDK, which includes the Command Line Tools (CLI). The image is optimized for local development, debugging, and unit testing. The tools installed for development and compilation make the image relatively large. - -* `dotnet/aspnet` - - The sample uses this image for running the app. The image contains the ASP.NET Core runtime and libraries and is optimized for running apps in production. Designed for speed of deployment and app startup, the image is relatively small, so network performance from Docker Registry to Docker host is optimized. Only the binaries and content needed to run an app are copied to the container. The contents are ready to run, enabling the fastest time from `docker run` to app startup. Dynamic code compilation isn't needed in the Docker model. - -## Prerequisites - -* [.NET SDK 8.0](https://dotnet.microsoft.com/download) -* Docker client 18.03 or later - - * Linux distributions - * [Debian](https://docs.docker.com/install/linux/docker-ce/debian/) - * [Fedora](https://docs.docker.com/install/linux/docker-ce/fedora/) - * [Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/) - * [macOS](https://docs.docker.com/desktop/mac/install/) - * [Windows](https://docs.docker.com/desktop/windows/install/) - -* [Git](https://git-scm.com/download) - -## Download the sample app - -* Download the sample by cloning the [.NET Docker repository](https://github.com/dotnet/dotnet-docker): - - ```console - git clone https://github.com/dotnet/dotnet-docker - ``` - -## Run the app locally - -* Navigate to the project folder at *dotnet-docker/samples/aspnetapp/aspnetapp*. - -* Run the following command to build and run the app locally: - - ```dotnetcli - dotnet run - ``` - -* Go to `http://localhost:` in a browser to test the app. - -* Press Ctrl+C at the command prompt to stop the app. - -## Run in a Linux container or Windows container - -* To run in a Linux container, right-click the System Tray's Docker client icon and select [switch to Linux containers](https://docs.docker.com/desktop/windows/#switch-between-windows-and-linux-containers). -* To run in a Windows container, right-click the System Tray's Docker client icon and select [switch to Windows containers](https://docs.docker.com/desktop/windows/#switch-between-windows-and-linux-containers). - -* Navigate to the Dockerfile folder at *dotnet-docker/samples/aspnetapp*. - -* Run the following commands to build and run the sample in Docker: - - ```console - docker build -t aspnetapp . - docker run -it --rm -p :8080 --name aspnetcore_sample aspnetapp - ``` - - The `build` command arguments: - * Name the image aspnetapp. - * Look for the Dockerfile in the current folder (the period at the end). - - The run command arguments: - * Allocate a pseudo-TTY and keep it open even if not attached. (Same effect as `--interactive --tty`.) - * Automatically remove the container when it exits. - * Map `` on the local machine to port 8080 in the container. - * Name the container aspnetcore_sample. - * Specify the aspnetapp image. - -* Go to `http://localhost:` in a browser to test the app. - -## Build and deploy manually - -In some scenarios, you might want to deploy an app to a container by copying its assets that are needed at run time. This section shows how to deploy manually. - -* Navigate to the project folder at *dotnet-docker/samples/aspnetapp/aspnetapp*. - -* Run the [dotnet publish](/dotnet/core/tools/dotnet-publish) command: - - ```dotnetcli - dotnet publish -c Release -o published - ``` - - The command arguments: - * Build the app in release mode (the default is debug mode). - * Create the assets in the *published* folder. - -* Run the app. - - * Windows: - - ```dotnetcli - dotnet published\aspnetapp.dll - ``` - - * Linux: - - ```dotnetcli - dotnet published/aspnetapp.dll - ``` - -* Browse to `http://localhost:` to see the home page. - -To use the manually published app within a Docker container, create a new *Dockerfile* and use the `docker build .` command to build an image. - -```dockerfile -FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime -WORKDIR /app -COPY published/ ./ -ENTRYPOINT ["dotnet", "aspnetapp.dll"] -``` - -To see the new image use the `docker images` command. - -### The Dockerfile - -Here's the *Dockerfile* used by the `docker build` command you ran earlier. It uses `dotnet publish` the same way you did in this section to build and deploy. - -```dockerfile -# https://hub.docker.com/_/microsoft-dotnet -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build -WORKDIR /source - -# copy csproj and restore as distinct layers -COPY *.sln . -COPY aspnetapp/*.csproj ./aspnetapp/ -RUN dotnet restore - -# copy everything else and build app -COPY aspnetapp/. ./aspnetapp/ -WORKDIR /source/aspnetapp -RUN dotnet publish -c release -o /app --no-restore - -# final stage/image -FROM mcr.microsoft.com/dotnet/aspnet:8.0 -WORKDIR /app -COPY --from=build /app ./ -ENTRYPOINT ["dotnet", "aspnetapp.dll"] -``` - -In the preceding *Dockerfile*, the `*.csproj` files are copied and restored as distinct *layers*. When the `docker build` command builds an image, it uses a built-in cache. If the `*.csproj` files haven't changed since the `docker build` command last ran, the `dotnet restore` command doesn't need to run again. Instead, the built-in cache for the corresponding `dotnet restore` layer is reused. For more information, see [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache). - -## Additional resources - -* [Containerize a .NET app with dotnet publish](/dotnet/core/docker/publish-as-container) -* [Docker build command](https://docs.docker.com/engine/reference/commandline/build) -* [Docker run command](https://docs.docker.com/engine/reference/commandline/run) -* [ASP.NET Core Docker sample](https://github.com/dotnet/dotnet-docker) (The one used in this tutorial.) -* [Configure ASP.NET Core to work with proxy servers and load balancers](xref:host-and-deploy/proxy-load-balancer) -* [Working with Visual Studio Docker Tools](xref:host-and-deploy/docker/visual-studio-tools-for-docker) -* [Debugging with Visual Studio Code](https://code.visualstudio.com/docs/nodejs/debugging-recipes#_debug-nodejs-in-docker-containers) -* [GC using Docker and small containers](xref:performance/memory#sc) -* [System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached](xref:host-and-deploy/docker/index#d128) -* [Updates to Docker images](https://andrewlock.net/exploring-the-dotnet-8-preview-updates-to-docker-images-in-dotnet-8/) - -## Next steps - -The Git repository that contains the sample app also includes documentation. For an overview of the resources available in the repository, see [the README file](https://github.com/dotnet/dotnet-docker/blob/main/samples/aspnetapp/README.md). In particular, learn how to implement HTTPS: - -> [!div class="nextstepaction"] -> [Developing ASP.NET Core Applications with Docker over HTTPS](https://github.com/dotnet/dotnet-docker/blob/main/samples/run-aspnetcore-https-development.md) - -:::moniker-end - +[!INCLUDE[](~/host-and-deploy/docker/includes/building-net-docker-images9.md)] +[!INCLUDE[](~/host-and-deploy/docker/includes/building-net-docker-images8.md)] [!INCLUDE[](~/host-and-deploy/docker/includes/building-net-docker-images7.md)] [!INCLUDE[](~/host-and-deploy/docker/includes/building-net-docker-images5.md)] diff --git a/aspnetcore/host-and-deploy/docker/includes/building-net-docker-images8.md b/aspnetcore/host-and-deploy/docker/includes/building-net-docker-images8.md new file mode 100644 index 000000000000..ed5d47700b82 --- /dev/null +++ b/aspnetcore/host-and-deploy/docker/includes/building-net-docker-images8.md @@ -0,0 +1,171 @@ +:::moniker range="= aspnetcore-8.0" + +## ASP.NET Core Docker images + +For this tutorial, you download an ASP.NET Core sample app and run it in Docker containers. The sample works with both Linux and Windows containers. + +The sample Dockerfile uses the [Docker multi-stage build feature](https://docs.docker.com/engine/userguide/eng-image/multistage-build/) to build and run in different containers. The build and run containers are created from images that are provided in Docker Hub by Microsoft: + +* `dotnet/sdk` + + The sample uses this image for building the app. The image contains the .NET SDK, which includes the Command Line Tools (CLI). The image is optimized for local development, debugging, and unit testing. The tools installed for development and compilation make the image relatively large. + +* `dotnet/aspnet` + + The sample uses this image for running the app. The image contains the ASP.NET Core runtime and libraries and is optimized for running apps in production. Designed for speed of deployment and app startup, the image is relatively small, so network performance from Docker Registry to Docker host is optimized. Only the binaries and content needed to run an app are copied to the container. The contents are ready to run, enabling the fastest time from `docker run` to app startup. Dynamic code compilation isn't needed in the Docker model. + +## Prerequisites + +* [.NET SDK 8.0](https://dotnet.microsoft.com/download) +* Docker client 18.03 or later + + * Linux distributions + * [Debian](https://docs.docker.com/install/linux/docker-ce/debian/) + * [Fedora](https://docs.docker.com/install/linux/docker-ce/fedora/) + * [Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/) + * [macOS](https://docs.docker.com/desktop/mac/install/) + * [Windows](https://docs.docker.com/desktop/windows/install/) + +* [Git](https://git-scm.com/download) + +## Download the sample app + +* Download the sample by cloning the [.NET Docker repository](https://github.com/dotnet/dotnet-docker): + + ```console + git clone https://github.com/dotnet/dotnet-docker + ``` + +## Run the app locally + +* Navigate to the project folder at *dotnet-docker/samples/aspnetapp/aspnetapp*. + +* Run the following command to build and run the app locally: + + ```dotnetcli + dotnet run + ``` + +* Go to `http://localhost:` in a browser to test the app. + +* Press Ctrl+C at the command prompt to stop the app. + +## Run in a Linux container or Windows container + +* To run in a Linux container, right-click the System Tray's Docker client icon and select [switch to Linux containers](https://docs.docker.com/desktop/windows/#switch-between-windows-and-linux-containers). +* To run in a Windows container, right-click the System Tray's Docker client icon and select [switch to Windows containers](https://docs.docker.com/desktop/windows/#switch-between-windows-and-linux-containers). + +* Navigate to the Dockerfile folder at *dotnet-docker/samples/aspnetapp*. + +* Run the following commands to build and run the sample in Docker: + + ```console + docker build -t aspnetapp . + docker run -it --rm -p :8080 --name aspnetcore_sample aspnetapp + ``` + + The `build` command arguments: + * Name the image aspnetapp. + * Look for the Dockerfile in the current folder (the period at the end). + + The run command arguments: + * Allocate a pseudo-TTY and keep it open even if not attached. (Same effect as `--interactive --tty`.) + * Automatically remove the container when it exits. + * Map `` on the local machine to port 8080 in the container. + * Name the container aspnetcore_sample. + * Specify the aspnetapp image. + +* Go to `http://localhost:` in a browser to test the app. + +## Build and deploy manually + +In some scenarios, you might want to deploy an app to a container by copying its assets that are needed at run time. This section shows how to deploy manually. + +* Navigate to the project folder at *dotnet-docker/samples/aspnetapp/aspnetapp*. + +* Run the [dotnet publish](/dotnet/core/tools/dotnet-publish) command: + + ```dotnetcli + dotnet publish -c Release -o published + ``` + + The command arguments: + * Build the app in release mode (the default is debug mode). + * Create the assets in the *published* folder. + +* Run the app. + + * Windows: + + ```dotnetcli + dotnet published\aspnetapp.dll + ``` + + * Linux: + + ```dotnetcli + dotnet published/aspnetapp.dll + ``` + +* Browse to `http://localhost:` to see the home page. + +To use the manually published app within a Docker container, create a new *Dockerfile* and use the `docker build .` command to build an image. + +```dockerfile +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime +WORKDIR /app +COPY published/ ./ +ENTRYPOINT ["dotnet", "aspnetapp.dll"] +``` + +To see the new image use the `docker images` command. + +### The Dockerfile + +Here's the *Dockerfile* used by the `docker build` command you ran earlier. It uses `dotnet publish` the same way you did in this section to build and deploy. + +```dockerfile +# https://hub.docker.com/_/microsoft-dotnet +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /source + +# copy csproj and restore as distinct layers +COPY *.sln . +COPY aspnetapp/*.csproj ./aspnetapp/ +RUN dotnet restore + +# copy everything else and build app +COPY aspnetapp/. ./aspnetapp/ +WORKDIR /source/aspnetapp +RUN dotnet publish -c release -o /app --no-restore + +# final stage/image +FROM mcr.microsoft.com/dotnet/aspnet:8.0 +WORKDIR /app +COPY --from=build /app ./ +ENTRYPOINT ["dotnet", "aspnetapp.dll"] +``` + +In the preceding *Dockerfile*, the `*.csproj` files are copied and restored as distinct *layers*. When the `docker build` command builds an image, it uses a built-in cache. If the `*.csproj` files haven't changed since the `docker build` command last ran, the `dotnet restore` command doesn't need to run again. Instead, the built-in cache for the corresponding `dotnet restore` layer is reused. For more information, see [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache). + +## Additional resources + +* [Containerize a .NET app with dotnet publish](/dotnet/core/docker/publish-as-container) +* [Docker build command](https://docs.docker.com/engine/reference/commandline/build) +* [Docker run command](https://docs.docker.com/engine/reference/commandline/run) +* [ASP.NET Core Docker sample](https://github.com/dotnet/dotnet-docker) (The one used in this tutorial.) +* [Configure ASP.NET Core to work with proxy servers and load balancers](xref:host-and-deploy/proxy-load-balancer) +* [Working with Visual Studio Docker Tools](xref:host-and-deploy/docker/visual-studio-tools-for-docker) +* [Debugging with Visual Studio Code](https://code.visualstudio.com/docs/nodejs/debugging-recipes#_debug-nodejs-in-docker-containers) +* [GC using Docker and small containers](xref:performance/memory#sc) +* [System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached](xref:host-and-deploy/docker/index#d128) +* [Updates to Docker images](https://andrewlock.net/exploring-the-dotnet-8-preview-updates-to-docker-images-in-dotnet-8/) + +## Next steps + +The Git repository that contains the sample app also includes documentation. For an overview of the resources available in the repository, see [the README file](https://github.com/dotnet/dotnet-docker/blob/main/samples/aspnetapp/README.md). In particular, learn how to implement HTTPS: + +> [!div class="nextstepaction"] +> [Developing ASP.NET Core Applications with Docker over HTTPS](https://github.com/dotnet/dotnet-docker/blob/main/samples/run-aspnetcore-https-development.md) + +:::moniker-end diff --git a/aspnetcore/host-and-deploy/docker/includes/building-net-docker-images9.md b/aspnetcore/host-and-deploy/docker/includes/building-net-docker-images9.md new file mode 100644 index 000000000000..0ebd03245c62 --- /dev/null +++ b/aspnetcore/host-and-deploy/docker/includes/building-net-docker-images9.md @@ -0,0 +1,171 @@ +:::moniker range=">= aspnetcore-9.0" + +## ASP.NET Core Docker images + +For this tutorial, you download an ASP.NET Core sample app and run it in Docker containers. The sample works with both Linux and Windows containers. + +The sample Dockerfile uses the [Docker multi-stage build feature](https://docs.docker.com/engine/userguide/eng-image/multistage-build/) to build and run in different containers. The build and run containers are created from images that are provided in Docker Hub by Microsoft: + +* `dotnet/sdk` + + The sample uses this image for building the app. The image contains the .NET SDK, which includes the Command Line Tools (CLI). The image is optimized for local development, debugging, and unit testing. The tools installed for development and compilation make the image relatively large. + +* `dotnet/aspnet` + + The sample uses this image for running the app. The image contains the ASP.NET Core runtime and libraries and is optimized for running apps in production. Designed for speed of deployment and app startup, the image is relatively small, so network performance from Docker Registry to Docker host is optimized. Only the binaries and content needed to run an app are copied to the container. The contents are ready to run, enabling the fastest time from `docker run` to app startup. Dynamic code compilation isn't needed in the Docker model. + +## Prerequisites + +* [.NET SDK 9.0](https://dotnet.microsoft.com/download) +* Docker client 18.03 or later + + * Linux distributions + * [Debian](https://docs.docker.com/install/linux/docker-ce/debian/) + * [Fedora](https://docs.docker.com/install/linux/docker-ce/fedora/) + * [Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/) + * [macOS](https://docs.docker.com/desktop/mac/install/) + * [Windows](https://docs.docker.com/desktop/windows/install/) + +* [Git](https://git-scm.com/download) + +## Download the sample app + +* Download the sample by cloning the [.NET Docker repository](https://github.com/dotnet/dotnet-docker): + + ```console + git clone https://github.com/dotnet/dotnet-docker + ``` + +## Run the app locally + +* Navigate to the project folder at *dotnet-docker/samples/aspnetapp/aspnetapp*. + +* Run the following command to build and run the app locally: + + ```dotnetcli + dotnet run + ``` + +* Go to `http://localhost:` in a browser to test the app. + +* Press Ctrl+C at the command prompt to stop the app. + +## Run in a Linux container or Windows container + +* To run in a Linux container, right-click the System Tray's Docker client icon and select [switch to Linux containers](https://docs.docker.com/desktop/windows/#switch-between-windows-and-linux-containers). +* To run in a Windows container, right-click the System Tray's Docker client icon and select [switch to Windows containers](https://docs.docker.com/desktop/windows/#switch-between-windows-and-linux-containers). + +* Navigate to the Dockerfile folder at *dotnet-docker/samples/aspnetapp*. + +* Run the following commands to build and run the sample in Docker: + + ```console + docker build -t aspnetapp . + docker run -it --rm -p :8080 --name aspnetcore_sample aspnetapp + ``` + + The `build` command arguments: + * Name the image aspnetapp. + * Look for the Dockerfile in the current folder (the period at the end). + + The run command arguments: + * Allocate a pseudo-TTY and keep it open even if not attached. (Same effect as `--interactive --tty`.) + * Automatically remove the container when it exits. + * Map `` on the local machine to port 8080 in the container. + * Name the container aspnetcore_sample. + * Specify the aspnetapp image. + +* Go to `http://localhost:` in a browser to test the app. + +## Build and deploy manually + +In some scenarios, you might want to deploy an app to a container by copying its assets that are needed at run time. This section shows how to deploy manually. + +* Navigate to the project folder at *dotnet-docker/samples/aspnetapp/aspnetapp*. + +* Run the [dotnet publish](/dotnet/core/tools/dotnet-publish) command: + + ```dotnetcli + dotnet publish -c Release -o published + ``` + + The command arguments: + * Build the app in release mode (the default is debug mode). + * Create the assets in the *published* folder. + +* Run the app. + + * Windows: + + ```dotnetcli + dotnet published\aspnetapp.dll + ``` + + * Linux: + + ```dotnetcli + dotnet published/aspnetapp.dll + ``` + +* Browse to `http://localhost:` to see the home page. + +To use the manually published app within a Docker container, create a new *Dockerfile* and use the `docker build .` command to build an image. + +```dockerfile +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime +WORKDIR /app +COPY published/ ./ +ENTRYPOINT ["dotnet", "aspnetapp.dll"] +``` + +To see the new image use the `docker images` command. + +### The Dockerfile + +Here's the *Dockerfile* used by the `docker build` command you ran earlier. It uses `dotnet publish` the same way you did in this section to build and deploy. + +```dockerfile +# https://hub.docker.com/_/microsoft-dotnet +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +WORKDIR /source + +# copy csproj and restore as distinct layers +COPY *.sln . +COPY aspnetapp/*.csproj ./aspnetapp/ +RUN dotnet restore + +# copy everything else and build app +COPY aspnetapp/. ./aspnetapp/ +WORKDIR /source/aspnetapp +RUN dotnet publish -c release -o /app --no-restore + +# final stage/image +FROM mcr.microsoft.com/dotnet/aspnet:9.0 +WORKDIR /app +COPY --from=build /app ./ +ENTRYPOINT ["dotnet", "aspnetapp.dll"] +``` + +In the preceding *Dockerfile*, the `*.csproj` files are copied and restored as distinct *layers*. When the `docker build` command builds an image, it uses a built-in cache. If the `*.csproj` files haven't changed since the `docker build` command last ran, the `dotnet restore` command doesn't need to run again. Instead, the built-in cache for the corresponding `dotnet restore` layer is reused. For more information, see [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache). + +## Additional resources + +* [Containerize a .NET app with dotnet publish](/dotnet/core/docker/publish-as-container) +* [Docker build command](https://docs.docker.com/engine/reference/commandline/build) +* [Docker run command](https://docs.docker.com/engine/reference/commandline/run) +* [ASP.NET Core Docker sample](https://github.com/dotnet/dotnet-docker) (The one used in this tutorial.) +* [Configure ASP.NET Core to work with proxy servers and load balancers](xref:host-and-deploy/proxy-load-balancer) +* [Working with Visual Studio Docker Tools](xref:host-and-deploy/docker/visual-studio-tools-for-docker) +* [Debugging with Visual Studio Code](https://code.visualstudio.com/docs/nodejs/debugging-recipes#_debug-nodejs-in-docker-containers) +* [GC using Docker and small containers](xref:performance/memory#sc) +* [System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached](xref:host-and-deploy/docker/index#d128) +* [Updates to Docker images](https://andrewlock.net/exploring-the-dotnet-8-preview-updates-to-docker-images-in-dotnet-8/) + +## Next steps + +The Git repository that contains the sample app also includes documentation. For an overview of the resources available in the repository, see [the README file](https://github.com/dotnet/dotnet-docker/blob/main/samples/aspnetapp/README.md). In particular, learn how to implement HTTPS: + +> [!div class="nextstepaction"] +> [Developing ASP.NET Core Applications with Docker over HTTPS](https://github.com/dotnet/dotnet-docker/blob/main/samples/run-aspnetcore-https-development.md) + +:::moniker-end diff --git a/aspnetcore/host-and-deploy/iis/advanced.md b/aspnetcore/host-and-deploy/iis/advanced.md index 0f53dd3618df..cf95b253f6c9 100644 --- a/aspnetcore/host-and-deploy/iis/advanced.md +++ b/aspnetcore/host-and-deploy/iis/advanced.md @@ -220,7 +220,7 @@ An ASP.NET Core app can be hosted as an [IIS sub-application (sub-app)](/iis/get Static asset links within the sub-app should use tilde-slash (`~/`) notation in MVC and Razor Pages. Tilde-slash notation triggers a [Tag Helper](xref:mvc/views/tag-helpers/intro) to prepend the sub-app's pathbase to the rendered relative link. For a sub-app at `/subapp_path`, an image linked with `src="~/image.png"` is rendered as `src="/subapp_path/image.png"`. The root app's Static File Middleware doesn't process the static file request. The request is processed by the sub-app's Static File Middleware. > [!NOTE] -> Razor components (`.razor`) shouldn't use tilde-slash notation. For more information, see the [Blazor app base path documentation](xref:blazor/host-and-deploy/index#app-base-path). +> Razor components (`.razor`) shouldn't use tilde-slash notation. For more information, see . If a static asset's `src` attribute is set to an absolute path (for example, `src="/image.png"`), the link is rendered without the sub-app's pathbase. The root app's Static File Middleware attempts to serve the asset from the root app's [web root](xref:fundamentals/index#web-root), which results in a *404 - Not Found* response unless the static asset is available from the root app. diff --git a/aspnetcore/host-and-deploy/linux-nginx.md b/aspnetcore/host-and-deploy/linux-nginx.md index 4862b05f5e70..f97875738087 100644 --- a/aspnetcore/host-and-deploy/linux-nginx.md +++ b/aspnetcore/host-and-deploy/linux-nginx.md @@ -190,7 +190,7 @@ server { } ``` -If the app is a SignalR or Blazor Server app, see and respectively for more information. +If the app is a SignalR or Blazor Server app, see and respectively for more information. When no `server_name` matches, Nginx uses the default server. If no default server is defined, the first server in the configuration file is the default server. As a best practice, add a specific default server that returns a status code of 444 in your configuration file. A default server configuration example is: @@ -497,7 +497,7 @@ Modify `/etc/nginx/nginx.conf`. Open it in a text editor, and replace the `http{ [!code-nginx[](~/host-and-deploy/linux-nginx/nginx.conf)] > [!NOTE] -> Blazor WebAssembly apps require a larger `burst` parameter value to accommodate the larger number of requests made by an app. For more information, see . +> Blazor WebAssembly apps require a larger `burst` parameter value to accommodate the larger number of requests made by an app. For more information, see . > [!NOTE] > The preceding example disables Online Certificate Status Protocol (OCSP) Stapling. If enabled, confirm that the certificate supports the feature. For more information and guidance on enabling OCSP, see the following properties in the [Module ngx_http_ssl_module (Nginx documentation)](http://nginx.org/en/docs/http/ngx_http_ssl_module.html) article: diff --git a/aspnetcore/host-and-deploy/linux-nginx/includes/linux-nginx5.md b/aspnetcore/host-and-deploy/linux-nginx/includes/linux-nginx5.md index b4824eed0aa2..19b4c23e9fd5 100644 --- a/aspnetcore/host-and-deploy/linux-nginx/includes/linux-nginx5.md +++ b/aspnetcore/host-and-deploy/linux-nginx/includes/linux-nginx5.md @@ -146,7 +146,7 @@ server { } ``` -If the app is a SignalR or Blazor Server app, see and respectively for more information. +If the app is a SignalR or Blazor Server app, see and respectively for more information. When no `server_name` matches, Nginx uses the default server. If no default server is defined, the first server in the configuration file is the default server. As a best practice, add a specific default server that returns a status code of 444 in your configuration file. A default server configuration example is: @@ -387,7 +387,7 @@ Add the */etc/nginx/proxy.conf* configuration file: [!code-nginx[](~/host-and-deploy/linux-nginx/nginx.conf)] > [!NOTE] -> Blazor WebAssembly apps require a larger `burst` parameter value to accommodate the larger number of requests made by an app. For more information, see . +> Blazor WebAssembly apps require a larger `burst` parameter value to accommodate the larger number of requests made by an app. For more information, see . > [!NOTE] > The preceding example disables Online Certificate Status Protocol (OCSP) Stapling. If enabled, confirm that the certificate supports the feature. For more information and guidance on enabling OCSP, see the following properties in the [Module ngx_http_ssl_module (Nginx documentation)](http://nginx.org/en/docs/http/ngx_http_ssl_module.html) article: @@ -592,7 +592,7 @@ server { } ``` -If the app is a SignalR or Blazor Server app, see and respectively for more information. +If the app is a SignalR or Blazor Server app, see and respectively for more information. When no `server_name` matches, Nginx uses the default server. If no default server is defined, the first server in the configuration file is the default server. As a best practice, add a specific default server that returns a status code of 444 in your configuration file. A default server configuration example is: @@ -834,7 +834,7 @@ Add the */etc/nginx/proxy.conf* configuration file: [!code-nginx[](~/host-and-deploy/linux-nginx/nginx.conf)] > [!NOTE] -> Blazor WebAssembly apps require a larger `burst` parameter value to accommodate the larger number of requests made by an app. For more information, see . +> Blazor WebAssembly apps require a larger `burst` parameter value to accommodate the larger number of requests made by an app. For more information, see . > [!NOTE] > The preceding example disables Online Certificate Status Protocol (OCSP) Stapling. If enabled, confirm that the certificate supports the feature. For more information and guidance on enabling OCSP, see the following properties in the [Module ngx_http_ssl_module (Nginx documentation)](http://nginx.org/en/docs/http/ngx_http_ssl_module.html) article: diff --git a/aspnetcore/migration/70-80.md b/aspnetcore/migration/70-80.md index 15148e4587b1..6890aea29048 100644 --- a/aspnetcore/migration/70-80.md +++ b/aspnetcore/migration/70-80.md @@ -314,7 +314,7 @@ Follow the guidance in the first three sections of this article: For apps that adopt [lazy assembly loading](xref:blazor/webassembly-lazy-load-assemblies), change the file extension from `.dll` to `.wasm` in the app's implementation to reflect Blazor WebAssembly's adoption of [Webcil assembly packaging](xref:aspnetcore-8#web-friendly-webcil-packaging). -Prior to the release of .NET 8, guidance in addresses environments that block clients from downloading and executing DLLs with a multipart bundling approach. In .NET 8 or later, Blazor uses the Webcil file format to address this problem. Multipart bundling using the experimental NuGet package described by the *WebAssembly deployment layout* article isn't supported for Blazor apps in .NET 8 or later. If you desire to continue using the multipart bundle package in .NET 8 or later apps, you can use the guidance in the article to create your own multipart bundling NuGet package, but it won't be supported by Microsoft. +Prior to the release of .NET 8, guidance in addresses environments that block clients from downloading and executing DLLs with a multipart bundling approach. In .NET 8 or later, Blazor uses the Webcil file format to address this problem. Multipart bundling using the experimental NuGet package described by the *WebAssembly deployment layout* article isn't supported for Blazor apps in .NET 8 or later. If you desire to continue using the multipart bundle package in .NET 8 or later apps, you can use the guidance in the article to create your own multipart bundling NuGet package, but it won't be supported by Microsoft. ### Convert a hosted Blazor WebAssembly app into a Blazor Web App @@ -520,7 +520,7 @@ dotnet publish -p:CompressionEnabled=false For more information, see the following resources: * [Static Web Assets Compression Flag Breaking Change (dotnet/announcements #283)](https://github.com/dotnet/announcements/issues/283) -* +* ### Migrate the `` component to cascading authentication state services @@ -562,7 +562,7 @@ For more information, see the following resources: We've added a new article that discusses some of the common HTTP caching issues that can occur when upgrading Blazor apps across major versions and how to address HTTP caching issues. -For more information, see . +For more information, see . ### New article on class libraries with static server-side rendering (static SSR) diff --git a/aspnetcore/release-notes/aspnetcore-6.0.md b/aspnetcore/release-notes/aspnetcore-6.0.md index edd8d15b8380..0be1994daf9e 100644 --- a/aspnetcore/release-notes/aspnetcore-6.0.md +++ b/aspnetcore/release-notes/aspnetcore-6.0.md @@ -156,7 +156,7 @@ Blazor WebAssembly apps can use native dependencies built to run on WebAssembly. ### WebAssembly Ahead-of-time (AOT) compilation and runtime relinking -Blazor WebAssembly supports ahead-of-time (AOT) compilation, where you can compile your .NET code directly into WebAssembly. AOT compilation results in runtime performance improvements at the expense of a larger app size. Relinking the .NET WebAssembly runtime trims unused runtime code and thus improves download speed. For more information, see [Ahead-of-time (AOT) compilation](xref:blazor/host-and-deploy/webassembly?view=aspnetcore-6.0#ahead-of-time-aot-compilation) and [Runtime relinking](xref:blazor/tooling/webassembly?view=aspnetcore-6.0#runtime-relinking). +Blazor WebAssembly supports ahead-of-time (AOT) compilation, where you can compile your .NET code directly into WebAssembly. AOT compilation results in runtime performance improvements at the expense of a larger app size. Relinking the .NET WebAssembly runtime trims unused runtime code and thus improves download speed. For more information, see [Ahead-of-time (AOT) compilation](xref:blazor/host-and-deploy/webassembly/index?view=aspnetcore-6.0#ahead-of-time-aot-compilation) and [Runtime relinking](xref:blazor/tooling/webassembly?view=aspnetcore-6.0#runtime-relinking). ### Persist prerendered state @@ -245,7 +245,7 @@ Generic type parameters are now supported. For more information, see . +Use a deployment layout to enable Blazor WebAssembly app downloads in restricted security environments. For more information, see . ### New Blazor articles diff --git a/aspnetcore/release-notes/aspnetcore-8.0.md b/aspnetcore/release-notes/aspnetcore-8.0.md index 1abf3f07fb28..73234209c6e7 100644 --- a/aspnetcore/release-notes/aspnetcore-8.0.md +++ b/aspnetcore/release-notes/aspnetcore-8.0.md @@ -42,7 +42,7 @@ For more information, see . +For more information, see . ### New Blazor Web App template @@ -201,7 +201,7 @@ For more information, see . +For more information, see . ### Ahead-of-time (AOT) SIMD and exception handling @@ -216,10 +216,10 @@ For more information, see the following articles: Webcil is web-friendly packaging of .NET assemblies that removes content specific to native Windows execution to avoid issues when deploying to environments that block the download or use of `.dll` files. Webcil is enabled by default for Blazor WebAssembly apps. -For more information, see . +For more information, see . > [!NOTE] -> Prior to the release of .NET 8, guidance in addresses environments that block clients from downloading and executing DLLs with a multipart bundling approach. In .NET 8 or later, Blazor uses the Webcil file format to address this problem. Multipart bundling using the experimental NuGet package described by the *WebAssembly deployment layout* article isn't supported for Blazor apps in .NET 8 or later. For more information, see [Enhance `Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle` package to define a custom bundle format (dotnet/aspnetcore #36978)](https://github.com/dotnet/aspnetcore/issues/36978#issuecomment-1439283893). If you desire to continue using the multipart bundle package in .NET 8 or later apps, you can use the guidance in the article to create your own multipart bundling NuGet package, but it won't be supported by Microsoft. +> Prior to the release of .NET 8, guidance in addresses environments that block clients from downloading and executing DLLs with a multipart bundling approach. In .NET 8 or later, Blazor uses the Webcil file format to address this problem. Multipart bundling using the experimental NuGet package described by the *WebAssembly deployment layout* article isn't supported for Blazor apps in .NET 8 or later. For more information, see [Enhance `Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle` package to define a custom bundle format (dotnet/aspnetcore #36978)](https://github.com/dotnet/aspnetcore/issues/36978#issuecomment-1439283893). If you desire to continue using the multipart bundle package in .NET 8 or later apps, you can use the guidance in the article to create your own multipart bundling NuGet package, but it won't be supported by Microsoft. ### Blazor WebAssembly debugging improvements @@ -254,8 +254,8 @@ Prior workarounds for configuring hub connection timeouts can be replaced with f For more information, see the following: * -* -* +* +* ### Project templates shed Open Iconic diff --git a/aspnetcore/signalr/scale.md b/aspnetcore/signalr/scale.md index 3f616b74edd3..f1b9e290d178 100644 --- a/aspnetcore/signalr/scale.md +++ b/aspnetcore/signalr/scale.md @@ -24,7 +24,7 @@ SignalR requires that all HTTP requests for a specific connection be handled by In all other circumstances (including when the Redis backplane is used), the server environment must be configured for sticky sessions. -For guidance on configuring Azure App Service for SignalR, see . For guidance on configuring sticky sessions for Blazor apps that use the [Azure SignalR Service](#azure-signalr-service), see . +For guidance on configuring Azure App Service for SignalR, see . For guidance on configuring sticky sessions for Blazor apps that use the [Azure SignalR Service](#azure-signalr-service), see . ## TCP connection resources diff --git a/aspnetcore/toc.yml b/aspnetcore/toc.yml index 008314be81b7..b6cd57e2e6ba 100644 --- a/aspnetcore/toc.yml +++ b/aspnetcore/toc.yml @@ -660,24 +660,44 @@ items: items: - name: Overview uid: blazor/host-and-deploy/index + - name: App base path + uid: blazor/host-and-deploy/app-base-path - name: Server - uid: blazor/host-and-deploy/server + items: + - name: Overview + uid: blazor/host-and-deploy/server/index + - name: Memory management + uid: blazor/host-and-deploy/server/memory-management - name: Blazor WebAssembly - uid: blazor/host-and-deploy/webassembly - - name: WebAssembly caching items: - name: Overview - uid: blazor/host-and-deploy/webassembly-caching/index + uid: blazor/host-and-deploy/webassembly/index + - name: Deploy to IIS + uid: blazor/host-and-deploy/webassembly/iis + - name: Deploy to Azure Static Web Apps + uid: blazor/host-and-deploy/webassembly/azure-static-web-apps + - name: Deploy to Azure Storage + uid: blazor/host-and-deploy/webassembly/azure-storage + - name: Deploy to Nginx + uid: blazor/host-and-deploy/webassembly/nginx + - name: Deploy to Apache + uid: blazor/host-and-deploy/webassembly/apache + - name: Deploy to GitHub Pages + uid: blazor/host-and-deploy/webassembly/github-pages + - name: Integrity check failures + uid: blazor/host-and-deploy/webassembly/integrity-check-failures + - name: Runtime and app bundle caching + uid: blazor/host-and-deploy/webassembly/runtime-and-app-bundle-caching - name: HTTP caching issues - uid: blazor/host-and-deploy/webassembly-caching/http-caching-issues + uid: blazor/host-and-deploy/webassembly/http-caching-issues + - name: Multiple hosted WebAssembly apps + uid: blazor/host-and-deploy/webassembly/multiple-hosted-webassembly + - name: Deployment layout + uid: blazor/host-and-deploy/webassembly/deployment-layout - name: Configure the Linker uid: blazor/host-and-deploy/configure-linker - name: Configure the Trimmer uid: blazor/host-and-deploy/configure-trimmer - - name: WebAssembly deployment layout - uid: blazor/host-and-deploy/webassembly-deployment-layout - - name: Multiple hosted WebAssembly apps - uid: blazor/host-and-deploy/multiple-hosted-webassembly - name: Blazor with EF Core uid: blazor/blazor-ef-core - name: Advanced scenarios diff --git a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod0.md b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod0.md index fd4af396428a..3cc48d3b7ed0 100644 --- a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod0.md +++ b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod0.md @@ -43,7 +43,7 @@ Welcome to what's new in the ASP.NET Core docs for June 2024. This article lists - - Clarify Blazor trim mode - - Blazor CLI commands moving to `dotnet watch` - - Blazor CLI commands moving to `dotnet watch` -- +- - Blazor CLI commands moving to `dotnet watch` - Update Apache coverage (drop CentOS mentions) - Fix spacing in Apache configuration example diff --git a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod2.md b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod2.md index 20fd67d912d6..9ed524806f4d 100644 --- a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod2.md +++ b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod2.md @@ -62,7 +62,7 @@ Welcome to what's new in the ASP.NET Core docs for February 2024. This article l - - Add roles and test user guidance - - [Blazor] SignalR - remove "using System" reminder - - Update 'Blazor Server' references -- +- - Update "ASP.NET Core" references - Clarify "subset" of .NET API remark - - Clarify "subset" of .NET API remark diff --git a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod3.md b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod3.md index 281cf2e8f84e..ef2bd944d5ac 100644 --- a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod3.md +++ b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod3.md @@ -13,7 +13,7 @@ Welcome to what's new in the ASP.NET Core docs for March 2024. This article list ### Updated articles -- - Update Azure SignalR Service remarks +- - Update Azure SignalR Service remarks - - Improve authorization opening remarks - Add coverage on antiforgery services and middleware diff --git a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod4.md b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod4.md index 74ea7b61e254..437235ed2ba8 100644 --- a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod4.md +++ b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod4.md @@ -13,7 +13,7 @@ Welcome to what's new in the ASP.NET Core docs for April 2024. This article list ### New articles -- +- - - - @@ -48,10 +48,10 @@ Welcome to what's new in the ASP.NET Core docs for April 2024. This article list - - Dedicated article on JS location - - Add Debugger support section - - [Blazor] DynamicComponents - fixes samples vulnerability + related adjustments -- +- - Blazor WASM build tools + AOT article - WASM runtime max heap size -- +- - Improve IIS crosslinking and additional deployment updates - Blazor WASM build tools + AOT article - Memory management updates diff --git a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod5.md b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod5.md index aa3f2c60f046..374ecd61c20e 100644 --- a/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod5.md +++ b/aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod5.md @@ -34,7 +34,7 @@ Welcome to what's new in the ASP.NET Core docs for May 2024. This article lists - Inform readers on support status of stateful reconnect - - More hints on interactivity for doc components - - RCLs for Blazor apps that support pages+views -- +- - Azure Container Apps updates - Inform readers on support status of stateful reconnect -