Decision. Two distros minimise setup work for this exact stack, for opposite reasons. Ubuntu 26.04 LTS — every vendor (Microsoft, Docker, JetBrains, HashiCorp, Kubernetes) tests against it first, and
.NET 10is in the built-in feed [2][38]. Fedora 44 —dnf install dotnet-sdk-10.0works out of the box, Docker Engine is officially supported, and everything is 6–18 months newer [3][18], at the cost of SELinux relabelling every bind mount [21]. Debian 13 is the only family where Microsoft still ships .NET itself [1] but its Node is too old to matter. Arch has the freshest packages of anyone [8][20] and the least vendor support. openSUSE and atomic/immutable variants both add friction that only pays off if you want what they’re selling.
The four decisions that actually matter
Coming from Windows + WSL2, most of your stack is distro-agnostic: bun, pnpm, mise, kubectl and Terraform all install from vendor scripts or vendor repos that don’t care what’s underneath. Four things genuinely differ per distro:
- Where the .NET SDK comes from — and whether you can get a feature band other than
.1xx. - Whether the default container runtime is Docker or Podman, and whether SELinux is between you and your bind mounts.
- Whether the vendors you depend on (Docker, JetBrains) list your distro as tested.
- How much of your setup is a hand-written
.repo/.listfile that you’ll have to fix at the next release upgrade.
Everything below is organised around those.
.NET 10 SDK: the packaging story is genuinely different per family
This is the part that surprises Windows developers. There is no single “Microsoft .NET repo for Linux” any more. Since .NET 9, Microsoft only publishes to packages.microsoft.com for distros that don’t package .NET themselves — Azure Linux, Debian, openSUSE Leap and SLES. Alpine, CentOS Stream, Fedora, RHEL and Ubuntu ship their own builds [1], governed by a published selection policy [37] ⭐ 22k. Arch is on the “publishes its own” list too [6].
| Distro family | Install command | Who builds it | .NET 10 today | ⚠ Friction |
|---|---|---|---|---|
| Ubuntu 26.04 LTS | apt install dotnet-sdk-10.0 |
Canonical, built-in feed | ✓ in built-in feed [2] | .NET 9/8 need ppa:dotnet/backports; SDK is always .1xx band [2] |
| Ubuntu 24.04 LTS | apt install dotnet-sdk-10.0 |
Canonical | ✓ built-in feed [2] | .NET 9 only via backports PPA; Microsoft feed doesn’t exist for 24.04+ [2] |
| Debian 13 | add packages-microsoft-prod.deb, then apt install dotnet-sdk-10.0 |
Microsoft [4] | ✓ all supported versions | One extra repo to register; the only family where you get non-.1xx feature bands from a package manager |
| Fedora 43/44 | dnf install dotnet-sdk-10.0 |
Fedora/Red Hat | ✓ 10.0.110 on both [7] |
Microsoft explicitly warns packages can lag a .NET release [3]; RPM users hit No match for argument: dotnet-sdk-10.0 for weeks after launch [9] ⭐ 3.2k |
| openSUSE Leap 16 | add MS zypper repo, zypper install dotnet-sdk-10.0 |
Microsoft [5] | ✓ | Leap 16 only — Tumbleweed is not a supported .NET target [5]; packages depend on OpenSSL 3.x |
| Arch | pacman -S dotnet-sdk |
Arch, source-built | ✓ 10.0.10.sdk110, plus SDK 8/9/10 side by side [8] |
Not a Microsoft-supported distro at all [1]; -bin AUR packages needed for other bands |
| Any distro | dotnet-install.sh / tarball |
Microsoft binaries | ✓ any version incl. previews | You install dependencies, export DOTNET_ROOT + PATH, and patch by hand; Microsoft says “for a developer or user, it’s better to use a package manager” [10] |
| Any distro | snap install dotnet-sdk |
Canonical [11] | ✓ | Snap confinement; fine for CLI, awkward alongside a distro install |
The feature-band trap
Distro-built SDKs are all in the .1xx feature band: Ubuntu by Canonical policy [2], Fedora at 10.0.110 [7], Arch at 10.0.10.sdk110 [8]. If a repo’s global.json pins 10.0.2xx or 10.0.3xx, only Debian’s Microsoft feed [4] or dotnet-install.sh [10] can satisfy it. Preview SDKs are never in any package repo [3].
The one .NET failure mode to know about
Register two .NET feeds and dotnet build starts throwing libhostfxr.so could not be found or FrameworkList.xml not found, with the tell-tale symptom of both /usr/lib64/dotnet and /usr/share/dotnet existing [6]. This bites specifically when you add packages.microsoft.com for PowerShell — which you probably will [35] — on a distro that already ships .NET. The fix is a pin: an apt Pin-Priority: -10 fragment, or excludepkgs=dotnet*,aspnet*,netstandard* in the dnf repo file [6]. Set it up on day one, not after the first mystery build failure.
Node, bun, pnpm: ignore the distro entirely
Distro Node is always behind and pinned for the release lifetime. Ubuntu 26.04 ships Node 22.22.1, 24.04 ships 18.19.1, 22.04 ships 12.22.9 [12]; Fedora 44 ships nodejs22 at 22.22.2 [13]. Neither gets you the current LTS line, and neither lets you switch per project.
This makes the JS side of your stack completely distro-neutral, which is good news:
| Tool | Install path that works everywhere | Notes |
|---|---|---|
| mise ⭐ 31k (Jul 2026) | curl https://mise.run \| sh → ~/.local/bin [15] |
One tool for node, bun, terraform, kubectl via pluggable backends [15]; also in apt/yum/brew/nix/snap |
| fnm ⭐ 26k (Jul 2026) | single Rust binary | Node only; fastest shell-hook of the three |
| nvm ⭐ 94k (Jul 2026) | shell script | Node only; measurable shell-startup cost |
| bun ⭐ 95k (Jul 2026) | curl -fsSL https://bun.com/install \| bash [16] |
Needs unzip and glibc ≥ 2.17; ⚠ default x64 build requires AVX2 — pre-Haswell CPUs silently get the slower baseline build [16] |
| pnpm ⭐ 36k (Jul 2026) | standalone script (no Node needed) or Corepack [17] | Corepack/npm paths require Node ≥ 22 [17] |
| NodeSource ⭐ 14k (Jul 2026) | third-party apt/dnf repo [14] | Only worth it if you want one system-wide Node managed by the package manager |
Recommendation for this stack: mise covers node + bun + pnpm shims + kubectl + terraform in one .tool-versions-style config, which collapses four of the “homelab tooling” rows below into nothing.
Containers: this is where distro choice actually costs you
| Ubuntu / Debian | Fedora | openSUSE Leap | Arch | Atomic (Silverblue/Bluefin) | |
|---|---|---|---|---|---|
| Docker Engine officially supported | ✓ [18] | ✓ [18] | ✗ not listed [18] | ✗ not listed [18] | ✗ (layer it yourself [22]) |
| Docker Desktop officially supported | ✓ Ubuntu, Debian [19] | ✓ [19] | ✗ | ⚠ experimental, untested package [19] | ✗ |
| Distro-packaged Docker | via Docker’s own apt repo | via Docker’s own dnf repo | zypper (community) |
pacman -S docker 29.6.2 + docker-compose 5.3.1 [20] |
Bluefin DX preinstalls docker-ce + compose + buildx [23] |
| Default runtime shipped | Docker (after you add the repo) | Podman preinstalled | Podman | neither | Podman preinstalled |
| ⚠ SELinux bind-mount friction | none (AppArmor) | ✓ real — :z/:Z or chcon -Rt container_file_t needed [21] |
✓ | none | ✓ |
The Fedora/RHEL SELinux tax is the single biggest practical difference for a Docker Compose user. Your existing docker-compose.yml files from the homelab will hit permission denied on bind mounts until every host-path volume gains a :z (shared) or :Z (private) suffix [21]. That’s an edit to files you share with a Coolify-managed server that doesn’t need them. Do not “fix” it by relabelling system directories — :Z on /etc, /usr or /var/lib breaks the host [21].
Docker Desktop on Linux is mostly not worth it for this profile: it runs a KVM VM, needs GNOME/KDE/MATE, and conflicts with Docker Engine over port mapping [19]. On Linux you want Docker Engine + docker compose [18] — the same CLI your Coolify hosts run.
Podman is the better security default and is preinstalled on Fedora and the atomic desktops, but Compose is still Docker’s home turf: you either use podman-compose (containers/podman-compose ⭐ 6.2k (Jul 2026)) or point the real docker compose (docker/compose ⭐ 38k (Jul 2026)) at the Podman socket. Given your homelab already standardises on Docker Compose, install Docker Engine and don’t fight the distro default — that’s cheap on Ubuntu/Debian/Fedora [18] and a manual .repo drop plus reboot on atomic [22].
IDEs: Rider and VS Code
| Rider | VS Code | |
|---|---|---|
| Recommended path | JetBrains Toolbox tarball, unpacked to a directory you choose [25] | Official deb or rpm repo [26] |
| Distros JetBrains/MS test | Ubuntu 24.04 & 26.04 LTS, Fedora 43/44, Debian 13, Amazon Linux 2023; glibc ≥ 2.28 [24] | Debian/Ubuntu (deb), RHEL/Fedora/CentOS + openSUSE/SLE (same rpm repo) [26] |
| Snap | available, ⚠ JetBrains flags “performance degradation” and points you back to Toolbox [24] | official snap, auto-updates [26] |
| Flatpak | exists, not the documented path [24] | ✗ not an official channel [26] |
| Arch / Nix | AUR + Toolbox tarball | community AUR and nixpkgs builds [26] |
Do not use the VS Code Flatpak. The sandbox can’t see host toolchains, offers no easy way to install one inside it, and has no access to /var/run/docker.sock by default [28] — which kills Dev Containers, the .NET language server and every dotnet/node invocation from the integrated terminal. Developer consensus on Lobsters is blunt: it “really shouldn’t be the version suggested to users” [27]. Use the deb/rpm on a conventional distro, or a Distrobox/Toolbx container on an atomic one.
Rider’s supported-distro list [24] is a useful tiebreaker on its own: Ubuntu LTS, Fedora, Debian 13. openSUSE and Arch aren’t on it (the tarball still runs; you’re just off-menu).
Packaging ecosystems: how fast, how fragile
| Ecosystem | Dev-tool freshness | Breakage risk | Best used for |
|---|---|---|---|
| apt (Ubuntu/Debian) | slow for language runtimes (Node 22 on 26.04 [12]), fast for .NET on Ubuntu [2] | low; ⚠ vendor .list files break on release upgrade [2] |
the OS + vendor repos everyone tests against |
| dnf (Fedora) | good — .NET 10 at 10.0.110 [7], 6-month cadence |
low-medium; ⚠ .NET packages can lag a release by weeks [9] ⭐ 3.2k | current toolchains without rolling-release churn |
| pacman + AUR | fastest of all — Docker 29.6.2 within days [20], Ghostty in [extra] [29] |
highest; AUR -bin packages are third-party rebuilds of vendor binaries |
people who want today’s version and will read changelogs |
| zypper (openSUSE) | Leap is conservative; Tumbleweed is rolling but unsupported by Microsoft [5] | low on Leap | not this stack — worst vendor coverage of the five |
| Snap | good; official channels for VS Code [26], .NET SDK [11], kubectl [30] | medium; ⚠ JetBrains reports performance problems [24] | GUI apps, not toolchains |
| Flatpak | good for GUI apps | ⚠ actively harmful for dev tools — sandbox hides host toolchains and the Docker socket [28] | Slack, Spotify, browsers. Not IDEs |
| Homebrew on Linux (Homebrew/brew ⭐ 49k (Jul 2026)) | very fresh for CLI tools | low; needs a system C compiler and recent glibc/gcc, single-user by design [36] | CLI tools missing or stale in the distro, no sudo needed after install [36] |
| Nix / nixpkgs (NixOS/nixpkgs ⭐ 26k (Jul 2026)) | very fresh, reproducible per-project shells [39] | low for tools, medium conceptual cost; listed by Microsoft as a third-party .NET source [1] | per-project pinned environments — a big learning investment while Linux itself is new to you |
Rule of thumb for this stack: distro package manager for the OS, vendor repos for .NET/Docker/PowerShell, mise for language runtimes, Homebrew only for the odd missing CLI. That layering is identical on Ubuntu and Fedora, which is why they tie.
Homelab and infra tooling
All of this is distro-neutral or vendor-repo-driven — it does not discriminate between Ubuntu, Debian and Fedora, and only mildly penalises Arch/openSUSE.
| Tool | Availability |
|---|---|
| Docker Compose | plugin from Docker’s own repo on Ubuntu/Debian/Fedora [18]; pacman -S docker-compose on Arch [20] |
| kubectl | pkgs.k8s.io apt/dnf/zypper repos, pinned per minor version — you edit the repo URL to upgrade [30]; also curl binary, snap, brew |
| Terraform | HashiCorp’s own apt and dnf repos [31], which cover Ubuntu, Debian, Fedora, RHEL/CentOS and Amazon Linux only [32] — ✗ no openSUSE, ✗ no Arch |
| OpenTofu (opentofu/opentofu ⭐ 30k (Jul 2026)) | drop-in alternative if you’d rather avoid HashiCorp’s licence terms |
| Coolify (coollabsio/coolify ⭐ 60k (Jul 2026)) | server-side only; installer supports Debian- and RHEL-based hosts [33]. Your workstation needs nothing but ssh + docker CLI. For IaC, a community Terraform provider covers apps, databases, servers and env vars (API disabled by default — enable it and mint a token) [34] |
| PowerShell 7 | Microsoft apt/dnf/zypper repos are the preferred path [35] — ⚠ this is the repo that triggers the .NET package mix-up [6] |
Atomic / immutable variants
The pitch: the OS is an image, your tooling lives in containers or $HOME, and a bad update is one reboot away from being undone. The cost for this stack is concrete.
rpm-ostreelayering works but is not apt. Adding Docker CE on Silverblue means manually placing the.repofile in/etc/yum.repos.d/thenrpm-ostree install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin— and a reboot [22]. Fedora community members’ first answer is “use the preinstalled Podman instead” [22].- Bluefin ⭐ 2.6k (Jul 2026) removes most of that. Its DX image preinstalls
docker-cewith the Compose and Buildx plugins, Podman tooling, and VS Code with Dev Containers already wired to Docker [23]. If you want atomic, this is the version to try — it is the only atomic option where this stack is close to zero-config. - Distrobox ⭐ 13k (Jul 2026) / Toolbx ⭐ 3.4k (Jul 2026) become mandatory, not optional: your .NET SDK, Node and CLI tools live inside a mutable container that the IDE reaches into. That’s a genuinely new mental model on top of Linux itself.
- ⚠ You inherit both the SELinux tax and the sandbox tax at once. Podman default + SELinux enforcing [21] + Flatpak-first app delivery [28] is three unfamiliar layers stacked while bash is still new to you.
Verdict: excellent destination, wrong starting point. Revisit in a year.
Terminal and shell
Least distro-dependent part of the whole exercise, and the one where your PowerShell background matters most.
- Default shell is bash everywhere; zsh and fish are one package install on every family.
- starship ⭐ 59k (Jul 2026) gives a consistent prompt across bash/zsh/fish and installs from a script or every distro repo.
- Ghostty ⭐ 59k (Jul 2026) is the notable distro-discriminating terminal: first-party packages for Arch
[extra], Alpine, Gentoo, Nix, Solus, Void and snap; Fedora needs a COPR and Ubuntu a community.deb; ⚠ openSUSE dropped it over Zig versioning [29]. - Install PowerShell 7 from Microsoft’s repo [35] — but pin
dotnet*away from that repo first [6].
Master friction table
Count of things you must configure by hand for .NET 10 + TS + Docker Compose + Rider/VS Code:
| Ubuntu 26.04 LTS | Debian 13 | Fedora 44 | Arch | openSUSE Leap 16 | Bluefin DX | |
|---|---|---|---|---|---|---|
| .NET 10 SDK | ✓ built-in feed [2] | +1 MS repo [4] | ✓ dnf [3] |
✓ pacman [8] |
+1 MS repo [5] | inside a container |
Non-.1xx SDK band possible |
✗ [2] | ✓ [4] | ✗ [7] | ✗ (AUR -bin) [8] |
✓ [5] | ✓ (script in container) |
| Docker Engine | +1 vendor repo, ✓ supported [18] | +1 vendor repo, ✓ supported [18] | +1 vendor repo, ✓ supported [18] | ✓ pacman, ✗ unsupported [20] |
✗ unsupported [18] | ✓ preinstalled [23] |
| Compose bind mounts work unmodified | ✓ | ✓ | ✗ needs :z/:Z [21] |
✓ | ✗ | ✗ |
| Rider tested by JetBrains | ✓ [24] | ✓ [24] | ✓ [24] | ✗ | ✗ | ✓ (Fedora base) |
| VS Code official repo | ✓ deb [26] | ✓ deb [26] | ✓ rpm [26] | ✗ AUR [26] | ✓ same rpm repo [26] | ✓ preinstalled [23] |
| Terraform vendor repo | ✓ [32] | ✓ [32] | ✓ [32] | ✗ AUR/mise | ✗ [32] | ✓ |
| Node/bun/pnpm | mise, identical everywhere [15] | — | — | — | — | — |
| ⚠ .NET mix-up risk when adding MS repo for PowerShell | high [6] | none (same feed) | high [6] | high [6] | none (same feed) | contained |
| Hand-configured repos needed | 3 (Docker, VS Code, HashiCorp) | 4 (+MS .NET) | 3 | 0 repos, 0 vendor support | 4, worst coverage | 0–1 |
How to read that
- Ubuntu 26.04 LTS — fewest surprises, most documentation written for it, .NET 10 with no repo at all. Pay for it with old Node in-repo (irrelevant, use mise) and a
.1xx-only SDK. - Fedora 44 — same repo count, newer everything,
dnf install dotnet-sdk-10.0on day one. Pay for it with SELinux volume flags on every Compose file and occasional .NET package lag [9] ⭐ 3.2k. - Debian 13 — pick it if a project pins a non-
.1xxSDK band, or if you want a Microsoft-supported .NET feed and PowerShell from the same repo with zero mix-up risk [4]. - Arch — freshest Docker and .NET of anyone, zero vendor support: not on Microsoft’s [1], Docker’s [18], JetBrains’ [24] or HashiCorp’s [32] lists. When something breaks, you are the support.
- openSUSE Leap 16 — Microsoft supports it [5] but Docker [18], JetBrains [24] and HashiCorp [32] don’t. Skip for this stack.
- Bluefin DX — the only atomic option that’s nearly turnkey here [23], but it asks you to learn Distrobox, Podman, SELinux and Flatpak simultaneously.