Modern .NET (formerly .NET Core) is cross-platform: ASP.NET Core web apps, APIs and background services run on Linux servers just as well as on Windows — usually with lower hosting costs. Installing it takes a couple of commands.
SDK or runtime?
- SDK — everything needed to build apps (
dotnet build,dotnet publish). Install it on build machines or CI. - ASP.NET Core Runtime — runs ASP.NET Core web apps and APIs (includes the .NET Runtime). Install this on production servers.
- .NET Runtime — runs console apps and services that don’t use ASP.NET Core.
Servers usually only need the runtime; you publish on your machine or in CI and copy the output.
LTS or STS?
.NET releases a new major version every November:
- LTS (even numbers: .NET 8, .NET 10) — three years of support. Choose these for production.
- STS (odd numbers: .NET 9) — shorter support.
Check the official .NET support policy for current end-of-support dates before choosing.
Ubuntu
Recent Ubuntu releases include .NET packages in their own repositories (built by Canonical):
sudo apt update
sudo apt install -y aspnetcore-runtime-8.0 # runtime for web apps
# or
sudo apt install -y dotnet-sdk-8.0 # SDK for building
dotnet --info
Replace 8.0 with the version you need (10.0 where available). If the version isn’t in your Ubuntu release, use Microsoft’s package repository (packages.microsoft.com) or a backports PPA — but don’t mix Microsoft’s and Ubuntu’s .NET packages on one system, which causes conflicting files.
Debian
Debian doesn’t package .NET; use Microsoft’s repository:
wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb && rm packages-microsoft-prod.deb
sudo apt update
sudo apt install -y aspnetcore-runtime-8.0
Adjust the Debian version in the URL.
AlmaLinux / Rocky / RHEL
.NET is in the AppStream repository:
sudo dnf install -y aspnetcore-runtime-8.0
# or
sudo dnf install -y dotnet-sdk-8.0
Install script (any distro, no root)
For CI or when packages aren’t available:
curl -sSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh
chmod +x dotnet-install.sh
./dotnet-install.sh --channel 8.0 --runtime aspnetcore --install-dir ~/.dotnet
export PATH=$PATH:~/.dotnet
Script installs don’t receive automatic updates — you must rerun them for security patches. Prefer packages on servers.
Side-by-side versions
Multiple runtimes and SDKs can coexist; each app uses the version it was built for:
dotnet --list-runtimes
dotnet --list-sdks
A global.json in a project pins the SDK version used for builds.
Verify with a test app
On a machine with the SDK:
dotnet new webapi -o hello
cd hello
dotnet run --urls http://127.0.0.1:5000
curl http://127.0.0.1:5000/weatherforecast
Self-contained deployments
If you’d rather not install .NET on the server at all, publish self-contained — the runtime is bundled with your app:
dotnet publish -c Release -r linux-x64 --self-contained true -o out
Larger output, but no runtime dependency (you’re then responsible for republishing to get runtime security fixes).
Dependencies
.NET needs a few native libraries (ICU for globalization, OpenSSL, zlib) that packages pull in automatically. In minimal containers, set DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 if you don’t need culture-specific formatting and ICU isn’t installed.
Next step
Run your app as a service behind Nginx: deploy ASP.NET Core on Linux. Prefer Windows Server and IIS? See hosting ASP.NET on IIS.