Migrate and optimize a .NET nopCommerce application on Microsoft Azure
Introduction
Set up an Arm-based environment
Create a nopCommerce endpoint benchmark baseline on Arm
Generate an SBOM and run .NET dependency discovery before migration
Choose a containerization path for the nopCommerce application
Tune the performance of the .NET application on Azure
Use the Arm MCP Server to optimize .NET performance
Next Steps
Migrate and optimize a .NET nopCommerce application on Microsoft Azure
Introduction
Set up an Arm-based environment
Create a nopCommerce endpoint benchmark baseline on Arm
Generate an SBOM and run .NET dependency discovery before migration
Choose a containerization path for the nopCommerce application
Tune the performance of the .NET application on Azure
Use the Arm MCP Server to optimize .NET performance
Next Steps
Audit application dependencies
Run dependency discovery before migration changes so you understand direct references, transitive risk, and hidden native payloads. By doing so, you’ll avoid late surprises when deploying to Arm.
Map direct references
Start from the nopCommerce repository root. Project-level references show what the app explicitly depends on before NuGet expands the graph.
Run the following command to search project files under src and print file names and line numbers, so you can jump directly to the owning project:
rg -n "<PackageReference|<ProjectReference" src
List transitive dependencies
Enumerate the full dependency graph for the web entry point:
dotnet list src/Presentation/Nop.Web/Nop.Web.csproj package --include-transitive
Transitive packages often carry architecture-sensitive constraints. Review the output for runtime-specific package names, native library packages, image processing libraries, database providers, and platform-specific assets.
Generate an SBOM
Generate an SBOM so you can track all components, versions, and exposure surface as a first-class migration artifact. While not strictly necessary for migration purposes, this is a best practice that’ll save time. You can also give this SBOM to an LLM to extract insights about your codebase.
The CycloneDX tool is installed as a .NET global tool. Add ~/.dotnet/tools to PATH in the current shell so the dotnet-CycloneDX command is available immediately after installation.
To generate an SBOM, run the following command:
dotnet tool install --global CycloneDX
export PATH="$PATH:$HOME/.dotnet/tools"
dotnet-CycloneDX src/Presentation/Nop.Web/Nop.Web.csproj -o sbom/ -rs -F Json
The -rs option includes project references, and -F Json writes JSON output that’s easier to diff in CI. If tool installation is blocked, treat dotnet list --include-transitive plus *.deps.json evidence as a temporary fallback, not the final state.
Inspect package internals for native payloads
Inspect package contents directly when a dependency looks architecture-sensitive. NuGet package folders are usually lower case on Linux, so set PACKAGE_ID to the folder name under ~/.nuget/packages and PACKAGE_VERSION to the version you want to inspect:
PACKAGE_ID="replace-with-package-id"
PACKAGE_VERSION="replace-with-version"
NUPKG="$HOME/.nuget/packages/$PACKAGE_ID/$PACKAGE_VERSION/$PACKAGE_ID.$PACKAGE_VERSION.nupkg"
mkdir -p /tmp/nupkg-audit
cp "$NUPKG" /tmp/nupkg-audit/
cd /tmp/nupkg-audit
unzip -l "$(basename "$NUPKG")" | rg "runtimes/|native/"
If the command prints runtimes/linux-arm64, the package already carries an Arm Linux asset. If it prints only linux-x64, win-x64, or another non-Arm runtime, trace whether that asset is used by nopCommerce before you treat the dependency as portable. If there’s no output, the package doesn’t advertise runtime or native payload directories in the .nupkg.
Dependency cascade rule
Treat dependencies as a chain, not isolated items.
Assume the app depends on library A, library A depends on library B, library B is architecture-sensitive. In this scenario, you must resolve B first, then validate A, then validate the app.
What you’ve accomplished and what’s next
You’ve now mapped direct and transitive dependencies, generated an SBOM, and checked packages for native payloads that could affect Arm deployment.
Next, you’ll explore options to containerize and migrate the application.