diff --git a/docs/core/deploying/index.md b/docs/core/deploying/index.md index 076198a311ece..60074d15a3cf3 100644 --- a/docs/core/deploying/index.md +++ b/docs/core/deploying/index.md @@ -1,35 +1,44 @@ --- title: Application publishing description: Learn about the ways to publish a .NET application. .NET can publish platform-specific or cross-platform apps. You can publish an app as self-contained or as framework-dependent. Each mode affects how a user runs your app. -ms.date: 03/18/2024 +ms.date: 07/01/2025 --- # .NET application publishing overview -Applications you create with .NET can be published in two different modes, and the mode affects how a user runs your app. +This article explains the different ways to publish a .NET application. It covers publishing modes, how to produce executables and cross-platform binaries, and the impact of each approach on deployment and runtime environments. -Publishing your app as *self-contained* produces an application that includes the .NET runtime and libraries, and your application and its dependencies. Users of the application can run it on a machine that doesn't have the .NET runtime installed. +## What is publishing -Publishing your app as *framework-dependent* produces an application that includes only your application itself and its dependencies. Users of the application have to separately install the .NET runtime. +Publishing a .NET app means compiling source code to create an executable or binary, along with its dependencies and related files, for distribution. After publishing, deploy the app to a server, distribution platform, container, or cloud environment. The publishing process prepares an app for deployment and use outside of a development environment. -Both publishing modes produce a platform-specific executable by default. Framework-dependent applications can be created without an executable, and these applications are cross-platform. +## Publishing modes -When an executable is produced, you can specify the target platform with a runtime identifier (RID). For more information about RIDs, see [.NET RID Catalog](../rid-catalog.md). +There are two primary ways to publish an app, and depending on how the app is deployed, one or the other is chosen. The choice largely depends on whether the deployment environment has the appropriate .NET Runtime installed. The two publishing modes are: + +- Publish *self-contained*\ +This mode produces a publishing folder that includes a platform-specific executable used to start the app, a compiled binary containing app code, any app dependencies, and the .NET runtime required to run the app. The environment that runs the app doesn't need to have the .NET runtime preinstalled. + +- Publish *framework-dependent*\ +This mode produces a publishing folder that includes a platform-specific executable used to start the app, a compiled binary containing app code, and any app dependencies. The environment that runs the app must have a version of the .NET runtime installed that the app can use. An optional platform-specific executable can be produced. + +> [!IMPORTANT] +> You specify the target platform with a runtime identifier (RID). For more information about RIDs, see [.NET RID Catalog](../rid-catalog.md). The following table outlines the commands used to publish an app as framework-dependent or self-contained: -| Type | Command | -|--|--| -| [framework-dependent executable](#publish-framework-dependent) for the current platform. | [`dotnet publish`](../tools/dotnet-publish.md) | -| [framework-dependent executable](#publish-framework-dependent) for a specific platform. | [`dotnet publish -r `](../tools/dotnet-publish.md) | -| [framework-dependent binary](#publish-framework-dependent). | [`dotnet publish`](../tools/dotnet-publish.md) | -| [self-contained executable](#publish-self-contained). | [`dotnet publish -r --self-contained`](../tools/dotnet-publish.md) | +| Type | Command | +|------------------------------------------------------------------------------------------|--------------------------------------------------------------------------| +| [framework-dependent executable](#publish-framework-dependent) for the current platform. | [`dotnet publish`](../tools/dotnet-publish.md) | +| [framework-dependent executable](#publish-framework-dependent) for a specific platform. | [`dotnet publish -r `](../tools/dotnet-publish.md) | +| [framework-dependent binary](#publish-framework-dependent). | [`dotnet publish`](../tools/dotnet-publish.md) | +| [self-contained executable](#publish-self-contained). | [`dotnet publish -r --self-contained`](../tools/dotnet-publish.md) | For more information, see [.NET dotnet publish command](../tools/dotnet-publish.md). ## Produce an executable -Executables aren't cross-platform, they're specific to an operating system and CPU architecture. When publishing your app and creating an executable, you can publish the app as [self-contained](#publish-self-contained) or [framework-dependent](#publish-framework-dependent). Publishing an app as self-contained includes the .NET runtime with the app, and users of the app don't have to worry about installing .NET before running the app. Publishing an app as framework-dependent doesn't include the .NET runtime; only the app and third-party dependencies are included. +Executables aren't cross-platform; they're specific to an operating system and CPU architecture. Executables are produced as either [self-contained](#publish-self-contained) or [framework-dependent](#publish-framework-dependent). Publishing as self-contained includes the .NET runtime with the app, so users don't have to install .NET before running it. Publishing as framework-dependent doesn't include the .NET runtime; only the app and third-party dependencies are included. The following commands produce an executable: @@ -41,14 +50,14 @@ The following commands produce an executable: ## Produce a cross-platform binary -Cross-platform binaries are created when you publish your app as [framework-dependent](#publish-framework-dependent), in the form of a *dll* file. The *dll* file is named after your project. For example, if you have an app named **word_reader**, a file named *word_reader.dll* is created. Apps published in this way are run with the `dotnet ` command and can be run on any platform. +Cross-platform binaries are created when the app is published as [framework-dependent](#publish-framework-dependent), in the form of a *dll* file. The *dll* file is named after the project. For example, if you have an app named **word_reader**, a file named *word_reader.dll* is created. Apps published in this way are run with the `dotnet ` command. -Cross-platform binaries can be run on any operating system as long as the targeted .NET runtime is already installed. If the targeted .NET runtime isn't installed, the app may run using a newer runtime if the app is configured to roll-forward. For more information, see [framework-dependent apps roll forward](../versions/selection.md#framework-dependent-apps-roll-forward). +Cross-platform binaries can run on any operating system as long as the targeted .NET runtime is already installed. If the targeted .NET runtime isn't installed, the app might run using a newer runtime if configured to roll-forward. For more information, see [framework-dependent apps roll forward](../versions/selection.md#framework-dependent-apps-roll-forward). -You can choose to run the app as a platform-specific executable or as a cross-platform binary via `dotnet` command. There should be no app behavior difference when launching the platform-specific executable versus the `dotnet` command for ordinary server apps Launching via a platform-specific executable gives you better integration with the underlying OS. For example: +You can choose to run the app as a platform-specific executable or as a cross-platform binary via the `dotnet` command. There should be no app behavior difference when launching the platform-specific executable versus the `dotnet` command. Launching via a platform-specific executable gives you better integration with the underlying OS. For example: -- You see the application executable name in your process list and not `dotnet`, which could be confusing if there's more than one. -- You can customize the platform-specific executable with OS specific features. For example, see [this discussion about configuring default stack size on Windows](https://github.com/dotnet/runtime/issues/96347#issuecomment-1981470713). +- The app executable name appears in the process list instead of `dotnet`, which could be confusing if there's more than one. +- The platform-specific executable can be customized with OS-specific features. For example, see [this discussion about configuring default stack size on Windows](https://github.com/dotnet/runtime/issues/96347#issuecomment-1981470713). The following command produces a cross-platform binary: @@ -58,42 +67,42 @@ The following command produces a cross-platform binary: ## Publish framework-dependent -Apps published as framework-dependent are cross-platform and don't include the .NET runtime. The user of your app is required to install the .NET runtime. +Apps published as framework-dependent are cross-platform and don't include the .NET runtime. The environment where the app runs must have the .NET runtime installed. -Publishing an app as framework-dependent produces a [cross-platform binary](#produce-a-cross-platform-binary) as a *dll* file, and a [platform-specific executable](#produce-an-executable) that targets your current platform. The *dll* is cross-platform while the executable isn't. For example, if you publish an app named **word_reader** and target Windows, a *word_reader.exe* executable is created along with *word_reader.dll*. When targeting Linux or macOS, a *word_reader* executable is created along with *word_reader.dll*. If the app uses a NuGet package that has platform-specific implementations, dependencies for all platforms are copied to the *publish\\runtimes\\{platform}* folder. +Publishing as framework-dependent produces a [cross-platform binary](#produce-a-cross-platform-binary) as a *dll* file, and a [platform-specific executable](#produce-an-executable) that targets the current platform. The *dll* is cross-platform while the executable isn't. For example, if the app is named **word_reader** and targets Windows, a *word_reader.exe* executable is created along with *word_reader.dll*. When targeting Linux or macOS, a *word_reader* executable is created along with *word_reader.dll*. If the app uses a NuGet package that has platform-specific implementations, dependencies for all platforms are copied to the *publish\\runtimes\\{platform}* folder. -The cross-platform binary of your app can be run with the `dotnet ` command, and can be run on any platform. +The cross-platform binary can be run with the `dotnet ` command, and can run on any environment. ### Platform-specific and framework-dependent -You can publish a framework-dependent app that's platform-specific by passing the `-r ` parameters to the [`dotnet publish`](../tools/dotnet-publish.md) command. Publishing in this way is the same as [publish framework-dependent](#publish-framework-dependent), except that platform-specific dependencies are handled differently. If the app uses a NuGet package that has platform-specific implementations, only the targeted platform's dependencies are copied. These dependencies are copied directly to the *publish* folder. +Publish a framework-dependent app that's platform-specific by passing the `-r ` parameters to the [`dotnet publish`](../tools/dotnet-publish.md) command. Publishing in this way is the same as [publish framework-dependent](#publish-framework-dependent), except that platform-specific dependencies are handled differently. If the app uses a NuGet package that has platform-specific implementations, only the targeted platform's dependencies are copied. These dependencies are copied directly to the *publish* folder. -While technically the binary produced is cross-platform, by targeting a specific platform, your app isn't guaranteed to run cross-platform. You can run `dotnet `, but the app may crash when it tries to access platform-specific dependencies that are missing. +While technically the binary produced is cross-platform, by targeting a specific environment, the app isn't guaranteed to run cross-platform. The app can be run with `dotnet `, but it might crash when it tries to access platform-specific dependencies that are missing. For more information about RIDs, see [.NET RID Catalog](../rid-catalog.md). ### Advantages - **Small deployment**\ -Only your app and its dependencies are distributed. The .NET runtime and libraries are installed by the user and all apps share the runtime. +Only the app and its dependencies are distributed. The environment where the app is run must already have the .NET runtime installed. - **Cross-platform**\ -Your app and any .NET-based library runs on other operating systems. You don't need to define a target platform for your app. For information about the .NET file format, see [.NET Assembly File Format](../../standard/assembly/file-format.md). +The app and any .NET-based library runs on other operating systems. There's no need to define a target platform for the app. For information about the .NET file format, see [.NET Assembly File Format](../../standard/assembly/file-format.md). - **Uses the latest patched runtime**\ -The app uses the latest runtime (within the targeted major-minor family of .NET) installed on the target system. This means your app automatically uses the latest patched version of the .NET runtime. This default behavior can be overridden. For more information, see [framework-dependent apps roll forward](../versions/selection.md#framework-dependent-apps-roll-forward). +The app uses the latest runtime (within the targeted major-minor family of .NET) installed in the environment. This means the app automatically uses the latest patched version of the .NET runtime. This default behavior can be overridden. For more information, see [framework-dependent apps roll forward](../versions/selection.md#framework-dependent-apps-roll-forward). ### Disadvantages - **Requires pre-installing the runtime**\ -Your app can run only if the version of .NET your app targets is already installed on the host system. You can configure roll-forward behavior for the app to either require a specific version of .NET or allow a newer version of .NET. For more information, see [framework-dependent apps roll forward](../versions/selection.md#framework-dependent-apps-roll-forward). +The app can run only if the version of .NET it targets is already installed in the environment running the app. Configure roll-forward behavior for the app to either require a specific version of .NET or allow a newer version of .NET. For more information, see [framework-dependent apps roll forward](../versions/selection.md#framework-dependent-apps-roll-forward). - **.NET may change**\ -It's possible for the .NET runtime and libraries to be updated on the machine where the app is run. In rare cases, this may change the behavior of your app if you use the .NET libraries, which most apps do. You can configure how your app uses newer versions of .NET. For more information, see [framework-dependent apps roll forward](../versions/selection.md#framework-dependent-apps-roll-forward). +It's possible that the environment where the app is run is using a newer .NET runtime. In rare cases, this might change the behavior of the app if it uses the .NET libraries, which most apps do. Configure how an app uses newer versions of .NET, known as rolling forward. For more information, see [framework-dependent apps roll forward](../versions/selection.md#framework-dependent-apps-roll-forward). ### Examples -Publish an app as cross-platform and framework-dependent. An executable that targets your current platform is created along with the *dll* file. Any platform-specific dependencies are published with the app. +Publish an app as cross-platform and framework-dependent. An executable that targets the current platform is created along with the *dll* file. Any platform-specific dependencies are published with the app. ```dotnetcli dotnet publish @@ -107,33 +116,32 @@ dotnet publish -r linux-x64 ## Publish self-contained -Publishing your app as self-contained produces a platform-specific executable. The output publishing folder contains all components of the app, including the .NET libraries and target runtime. The app is isolated from other .NET apps and doesn't use a locally installed shared runtime. The user of your app isn't required to download and install .NET. +Publishing as self-contained produces a platform-specific executable. The output publishing folder contains all components of the app, including the .NET libraries and target runtime. The app is isolated from other .NET apps and doesn't use a locally installed shared runtime. The environment running the app isn't required to have a .NET runtime installed. -You can publish a self-contained app by passing the `--self-contained` parameter to the [`dotnet publish`](../tools/dotnet-publish.md) command. The executable binary is produced for the specified target platform. For example, if you have an app named **word_reader**, and you publish a self-contained executable for Windows, a *word_reader.exe* file is created. Publishing for Linux or macOS, a *word_reader* file is created. The target platform and architecture is specified with the `-r ` parameter for the [`dotnet publish`](../tools/dotnet-publish.md) command. For more information about RIDs, see [.NET RID Catalog](../rid-catalog.md). +Publish a self-contained app by passing the `--self-contained` parameter to the [`dotnet publish`](../tools/dotnet-publish.md) command. The executable binary is produced for the specified target environment. For example, if your app is named **word_reader**, and you publish a self-contained executable for Windows, a *word_reader.exe* file is created. If you publish for Linux or macOS, a *word_reader* file is created. Specify the target environment and architecture with the `-r ` parameter for the [`dotnet publish`](../tools/dotnet-publish.md) command. For more information about RIDs, see [.NET RID Catalog](../rid-catalog.md). If the app has platform-specific dependencies, such as a NuGet package containing platform-specific dependencies, these are copied to the publish folder along with the app. ### Advantages - **Control .NET version**\ -You control which version of .NET is deployed with your app. +Control which version of .NET is deployed with the app. - **Platform-specific targeting**\ -Because you have to publish your app for each platform, you know where your app runs. If .NET introduces a new platform, users can't run your app on that platform until you release a version targeting that platform. You can test your app for compatibility problems before your users run your app on the new platform. +Because the app must be published for each platform, it's clear where the app runs. If .NET introduces a new platform, users can't run the app on that platform until a version targeting that platform is released. Test the app for compatibility problems before users run it on the new platform. ### Disadvantages - **Larger deployments**\ -Because your app includes the .NET runtime and all of your app dependencies, the download size and hard drive space required is greater than a [framework-dependent](#publish-framework-dependent) version. - - > [!TIP] - > You can reduce the size of your deployment on Linux systems by approximately 28 MB by using .NET [*globalization invariant mode*](https://github.com/dotnet/runtime/blob/main/docs/design/features/globalization-invariant-mode.md). This forces your app to treat all cultures like the [invariant culture](xref:System.Globalization.CultureInfo.InvariantCulture?displayProperty=nameWithType). +Because the app includes the .NET runtime and all dependencies, the download size and hard drive space required is greater than a [framework-dependent](#publish-framework-dependent) version. > [!TIP] - > [IL trimming](trimming/trim-self-contained.md) can further reduce the size of your deployment. + > Reduce the size of the deployment on Linux environments by approximately 28 MB by using .NET [*globalization invariant mode*](https://github.com/dotnet/runtime/blob/main/docs/design/features/globalization-invariant-mode.md). This forces the app to treat all cultures like the [invariant culture](xref:System.Globalization.CultureInfo.InvariantCulture?displayProperty=nameWithType). + > + > [IL trimming](trimming/trim-self-contained.md) can further reduce the size of the deployment. - **Harder to update the .NET version**\ -.NET Runtime (distributed with your app) can only be upgraded by releasing a new version of your app. +The .NET Runtime (distributed with the app) can only be upgraded by releasing a new version of the app. ### Examples @@ -151,17 +159,17 @@ dotnet publish -r win-x64 --self-contained ## Publish with ReadyToRun images -Publishing with ReadyToRun images improves the startup time of your application at the cost of increasing the size of your application. For more information, see [ReadyToRun](ready-to-run.md). +Publishing with ReadyToRun images improves the startup time of the app at the cost of increasing the size of the app. For more information, see [ReadyToRun](ready-to-run.md). ### Advantages - **Improved startup time**\ -The application spends less time running the JIT. +The app spends less time running the JIT. ### Disadvantages - **Larger size**\ -The application is larger on disk. +The app is larger on disk. ### Examples