☰
Ubuntu 24.04安装.NET 10开发环境:从apt源配置到排障实战全记录
2026/9/26 21:04:54 网站建设 项目流程

最近一次我在一台刚装好Ubuntu 24.04 LTS的工作机上部署.NET 10开发环境,前前后后折腾了小半天,踩了几个不折腾根本遇不到的坑。这篇就是我整个安装过程的实操日志,从环境准备、apt源替换、SDK安装、验证运行,到VS Code集成、NuGet源配置、排障记录,全部照实记录。如果你是刚把系统升级到24.04、或者正打算在这版系统上安装dotnet并开始写C#的项目,这篇内容可以直接照着操作,连我踩过的坑都帮你标好了。

先说结论:Ubuntu 24.04上装dotnet 10本身不复杂,麻烦的是安装之前的环境清理、安装之后的路径配置,以及几个看起来莫名其妙、实际上有明确原因的报错。这篇日志会把每一步命令、每一个坑、每一次排查的过程都写清楚,力求你照着走一遍就能顺利跑起来。

1. 为什么这次选择在24.04上装dotnet 10

1.1 系统版本确认与基础状态检查

动手之前先确认系统版本,这一步千万别省。我之前见过有人在22.04上照着24.04的教程操作,结果apt源、依赖包全部对不上,白折腾一个多小时。

lsb_release -a

输出里确认是Ubuntu 24.04.2 LTS(或者24.04.x),代号noble。内核版本可以用uname -a看一眼,一般5.15以上都没问题,dotnet不挑内核版本,但和部分显卡驱动、容器运行时有关联,顺手记录一下没坏处。

接着检查架构。x86_64就写amd64,ARM架构的机器(比如树莓派5、部分国产开发板)需要下载arm64版本,后续注册apt源和下载SDK时架构名不能搞错。

arch

然后快速看一下磁盘空间。dotnet SDK完整装下来大概占用2GB到3GB,加上NuGet缓存、全局工具、模板文件,建议预留10GB以上空间。我用df -h /查看根分区,确认还有60多GB空闲,才放心往下走。

1.2 dotnet 10值得升级的理由

说实话,如果你的生产环境还在用.NET 6或.NET 8,不一定要急着升.NET 10。但在新装系统上,直接上最新长期支持版本是合理选择。

.NET 10最大的变化集中在三个方面:

  • 性能进一步提升:JIT编译优化、垃圾回收调整,对高并发服务端程序友好。
  • AOT发布更成熟:不需要运行时环境也能跑原生二进制,部署体积和启动速度都非常可观。
  • C#语言新特性:集合表达式、partial属性、扩展成员预览等,写起来更简洁。

由于24.04是当前最活跃的LTS版本,很多开发工具链(比如GitLab 19、新版Docker镜像、VSCode 1.9x以上版本)都已经把默认支持基线提升到24.04。系统层面你绕不开它,那开发环境直接架上.NET 10是比较省事的组合。

1.3 安装方式选型:apt源、snap还是手动解压

在Ubuntu上装dotnet主要有三条路:官方apt源、snap包、手动解压二进制包。我直接说结论:推荐apt源方式,次级推荐手动解压,snap方式我有过不愉快的经历,下面解释原因。

安装方式优点缺点适合场景
apt源依赖管理自动、版本更新可感知需要注册Microsoft仓库大多数人的首选
snap包隔离干净、自动更新首次运行慢、路径特殊、与VS Code snap版易冲突临时体验、容器内测试
手动解压tar.gz完全可控、可在用户目录安装需要自己配PATH、更新全手动无root权限的服务器环境

snap版本会在/snap/dotnet/下创建沙箱环境,运行时通过挂载方式映射到/usr/lib/dotnet,看着方便,但如果你再用snap方式装VS Code,终端里执行dotnet命令时经常出现PATH识别不到的情况,因为两个snap互相看不到对方的挂载目录。这个坑我在第4节详细说。

所以我最后选了注册Microsoft官方apt源的方式,把dotnet包和系统包管理统一在一起,依赖问题自动解决。

2. 安装前的系统准备与apt源配置

2.1 先做系统更新,顺手替换apt源

我的习惯是先不急着加dotnet源,先把系统自身更新到最新状态。这一步除了常规的apt update和apt upgrade,还要处理一个国内用户经常遇到的老大难:默认官方源速度慢。

如果你在海外服务器或网络无障碍环境下,官方源没问题。但我在国内的机器上实测过,直接从archive.ubuntu.com拉取更新包经常只有几十KB/s,换镜像源后能跑到几MB/s。

替换源的方法不复杂,先备份:

sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak

24.04的apt源格式和旧版不一样,现在是DEB822格式,路径在/etc/apt/sources.list.d/ubuntu.sources,不再是sources.list单文件。用sed直接替换镜像域名:

sudo sed -i 's|http://archive.ubuntu.com|http://mirrors.aliyun.com|g' /etc/apt/sources.list.d/ubuntu.sources sudo sed -i 's|http://security.ubuntu.com|http://mirrors.aliyun.com|g' /etc/apt/sources.list.d/ubuntu.sources

我用的是阿里云镜像源,实测速度和稳定性都不错。如果你在南方省份,腾讯云和华为云的镜像源也可以,选一个距离近的就行。替换完执行:

sudo apt update sudo apt upgrade -y

等它跑完重启一遍,让新内核和库文件生效。这里提醒一下,升级完系统后内核可能变化,重启能避免后续装dotnet依赖时遇到内核模块不匹配的问题。

2.2 安装基础依赖包

虽然dotnet SDK自带大部分依赖,但有几个包在24.04的最小化安装里默认没有,直接装SDK时会补装,不过我习惯提前装好,避免中途出现奇怪的问题。

sudo apt install -y wget curl ca-certificates apt-transport-https gnupg

这几个包的作用分别是:wget和curl用来下载注册脚本和测试网络,ca-certificates是HTTPS证书信任链的必备组件,apt-transport-https确保apt能通过HTTPS访问源,gnupg用来导入微软的GPG签名密钥。

没有装apt-transport-https的话,后续添加Microsoft源会报错 "Unable to locate package",因为apt不认识https协议头。这是很常见的一个坑,提前装上就能避开。

2.3 检查网络连通性

这一步看似多余,但实际安装时网络问题是最容易让人误判的。我用来检查的几条命令:

curl -I https://packages.microsoft.com curl -I https://dotnet.microsoft.com

curl -I只请求头信息,不下载实际内容,速度快。看到HTTP/2 200就是通的,如果超时或返回403,先查DNS解析和防火墙规则,再排查其他问题。

另外,NuGet官网https://api.nuget.org/v3/index.json也建议测一下,SDK安装完之后创建项目需要从NuGet拉包,这一条不通的话后面照样卡住。

3. dotnet 10 SDK安装完整过程

3.1 注册Microsoft软件源

到了核心环节。dotnet官方推荐的方式是通过Microsoft的Linux软件仓库分发,这样能保证和apt包管理深度集成。执行如下命令:

wget https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb

下载的deb包主要做两件事:把Microsoft的GPG公钥写入系统信任链,同时生成/etc/apt/sources.list.d/microsoft-prod.list源文件。装完之后执行apt update刷新源列表,此时应该能看到microsoft-prod源里的dotnet相关包。

如果执行apt update时报GPG错误,原因是钥匙过期或未导入成功,重新导入即可:

curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg

然后检查/etc/apt/sources.list.d/microsoft-prod.list里的源指向是否正确,我见过部分情况下源文件路径指向了旧的noble代号,手动改成正确的即可。

3.2 安装dotnet SDK 10

源注册好之后,安装命令一条就够:

sudo apt install -y dotnet-sdk-10.0

如果只需要运行时(比如只跑别人编译好的程序),可以只装dotnet-runtime-10.0,但大多数开发场景建议直接上SDK,SDK里包含运行时,还能使用dotnet new、dotnet build等命令。

安装过程中apt会解析依赖,自动装上一些基础运行库,比如libicu、libssl、libgssapi等,这些是dotnet运行时在Linux上工作的必要组件,不用手动干预。

如果你还需要同时保留.NET 8(很多旧项目还在用),可以并行安装:

sudo apt install -y dotnet-sdk-8.0

多个版本SDK共存没有任何冲突,它们各自安装在自己的目录下,通过global.json或dotnet --list-sdks管理版本选择。

安装完成先跑一下版本验证:

dotnet --version dotnet --list-sdks

我这边输出的是10.0.x,同时能看到系统里所有已经安装的SDK版本。如果dotnet命令提示找不到,大概率是PATH问题,我下面单独说。

3.3 PATH配置与权限细节

apt方式安装的dotnet默认路径是/usr/lib/dotnet/,安装器会自动把/usr/bin/dotnet软链接指过去,正常情况下不需要手动配PATH。但如果你遇到command not found,检查这几处:

which dotnet ls -la /usr/bin/dotnet ls -la /usr/lib/dotnet/dotnet

如果软链接丢失,手动重建:

sudo ln -s /usr/lib/dotnet/dotnet /usr/bin/dotnet

另外,如果你用的是zsh,需要在~/.zshrc里确认PATH包含/usr/lib/dotnet。我在测试时发现有些环境变量在bash里正常,切到zsh后失效,原因是zsh启动时读取的是~/.zshrc而不是~/.bashrc。

还有一个权限细节:dotnet首次运行会创建~/.dotnet缓存目录,如果当前用户home目录的权限有问题,或者之前用sudo高速缓存过root用户文件,会导致普通用户执行dotnet时Permission denied。排查方法:

ls -la ~/.dotnet sudo chown -R $USER:$USER ~/.dotnet

3.4 创建第一个项目并运行

安装是否真的成功,跑一个最小项目看效果最实在。我习惯用web API模板做验证,因为ASP.NET Core涉及依赖注入、配置、Kestrel等核心组件,能跑起来说明环境基本没问题:

dotnet new webapi -n HelloDotnet cd HelloDotnet dotnet run

第一次执行dotnet run会触发NuGet还原,耗时取决于网络状况,我在替换过NuGet源之后大约用了40秒左右。看到输出里有Now listening on: http://localhost:5xxx就算成功了。

浏览器访问该地址,能看到返回的JSON响应。如果测试机器没有桌面环境,用curl http://localhost:5xxx验证也可以。

新项目跑通之后建议顺手做一次发布测试,确认完整的构建链路没有缺失:

dotnet publish -c Release

发布目录下会生成可执行文件和DLL,这一步通过说明SDK组件完整,可以放心进入日常开发。

4. 开发环境集成与日常使用细节

4.1 VS Code的snap版和dotnet命令的兼容问题

开发C#离不开编辑器,我在24.04上最常用的组合是VS Code + C# Dev Kit插件。但这里有个非常隐蔽的坑:

如果你通过snap安装VS Code:

sudo snap install code --classic

那么VS Code内置终端里执行dotnet命令会有概率报command not found。原因是snap应用运行在受限环境中,默认只暴露部分系统路径,/usr/lib/dotnet未必在snap的PATH映射里。

排查方法很简单,在VS Code的终端里执行:

echo $PATH

如果发现没有/usr/lib/dotnet,就是这个问题。解决方式有两种:

  1. 在VS Code的settings.json里给终端设置PATH:
"terminal.integrated.env.linux": { "PATH": "/usr/lib/dotnet:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }
  1. 直接在~/.bashrc末尾追加一行:
export PATH="$PATH:/usr/lib/dotnet"

我个人推荐第一种,因为只影响VS Code终端,不至于污染全局环境。这类坑调起来很恼人,因为命令行单独执行dotnet是正常的,一旦在编辑器里就不行,特别容易让人误判成插件问题。

4.2 NuGet包源配置,国内网络环境下必做

由于NuGet官方源api.nuget.org的服务器基本都在海外,国内直连的时候经常出现超时、还原失败的情况。解决办法是把NuGet源切换/增加为国内可信镜像。

NuGet的配置文件分用户级和项目级,用户级配置在~/.nuget/NuGet/NuGet.Config。我的做法是直接把镜像源加到用户级配置里,这样所有项目都能生效:

dotnet nuget add source https://mirrors.aliyun.com/nuget/v3/index.json -n AliyunMirror dotnet nuget add source https://mirrors.cloud.tencent.com/nuget/ -n TencentMirror

添加完之后可以通过dotnet nuget list source查看当前所有源。注意,多个源同时存在可以提升一些私有包的可用性,但也可能造成版本选择不一致,如果你对包来源有严格要求,可以把官方源暂时禁用在急用时单独开启:

dotnet nuget disable source nuget.org

配置完镜像源之后,之前遇到的还原超时问题基本消失。我在测试中执行dotnet restore的速度提升了至少5倍。

4.3 中文语言环境与文件编码的潜在干扰

这个话题我在日志里专门记了一笔,因为现象太迷惑。24.04有一个被广泛讨论的中文环境相关异常:部分中文语言包或中文输入法组件会导致终端输出乱码、文件路径里中文名显示异常,甚至在个别系统版本下dotnet build的输出文本编码判断错误。

我的系统是英文locale,只装了中文输入法,所以没遇到严重问题。但如果你的系统安装时选择了中文语言环境,建议先检查:

locale

确保LANG是zh_CN.UTF-8或en_US.UTF-8这样的合理值,如果显示C或POSIX,dotnet的日志输出、NuGet错误信息全都会变成乱码。

解决方式是手动生成locale:

sudo apt install -y locales sudo locale-gen en_US.UTF-8 zh_CN.UTF-8 sudo update-locale LANG=en_US.UTF-8

至于和代码本身相关的中文编码问题,在.csproj文件里设置<InvariantGlobalization>false</InvariantGlobalization>可以保证国际化的代码按预期运行,不过一般默认值就够用,不需要额外配置。

4.4 AOT发布与单文件部署尝试

dotnet 10的AOT发布比之前版本稳定很多,依赖项处理更漂亮,本来编译原生二进制时经常出现的剪裁警告也减少了。我实际测试了一个简单的控制台程序:

dotnet publish -c Release -r linux-x64 --self-contained -p:PublishAot=true

命令执行时间大约50秒,生成的原生二进制大小约12MB,直接扔到一个没有dotnet运行时和依赖库的干净容器里也能跑起来。

单文件发布(非AOT)也很方便:

dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true

这两种方式各有适用场景:AOT启动极快、内存占用低,适合云函数、边缘设备;单文件发布对第三方库兼容性更好,适合交付给用户直接运行。建议两个都试一遍,感受一下差异。

5. 实际排障记录:安装过程中遇到的三次报错

5.1 现象一:Unable to locate package dotnet-sdk-10.0

这个报错出现在我执行sudo apt install dotnet-sdk-10.0的时候,当时愣了一下,因为注册源的步骤明明执行成功了。

排查过程如下:

  1. 执行apt-cache search dotnet,发现输出里只有dotnet-sdk-8.0,没有10.
  2. 检查/etc/apt/sources.list.d/microsoft-prod.list,发现源文件里的Ubuntu版本代号是jammy(22.04),而不是noble.
  3. 回看注册deb包的命令,确认使用的配置包是config/ubuntu/24.04/packages-microsoft-prod.deb.

问题根源很简单:我在下载deb包时用了旧的URL缓存,虽然没有报错,但装进去的是22.04的源配置。删除错误源文件,重新用24.04的包注册,apt update之后就能搜到dotnet-sdk-10.0了。

提示:如果使用旧版系统迁移过来的源文件,务必检查源文件里的代号,jammy和noble的包版本差异很大,混用会带来依赖冲突。

5.2 现象二:No such file or directory 的DLL加载错误

第一次安装完成后执行dotnet --info,能打印版本信息,但创建完项目执行dotnet build时抛出一个特别奇怪的错误:

A fatal error occurred. The folder [/usr/share/dotnet/host/fxr/10.0.x] does not exist

报错路径是/usr/share/dotnet,但我安装的dotnet明明在/usr/lib/dotnet。排查了半天发现是shell别名或软链接指向混乱造成的。之前系统里装过其他版本的dotnet,残留了/usr/share/dotnet软链接。

删除旧的软链接,重建/usr/bin/dotnet指向:

sudo rm -rf /usr/share/dotnet /usr/bin/dotnet sudo ln -s /usr/lib/dotnet/dotnet /usr/bin/dotnet

这个问题在反复折腾过多版本SDK的机器上经常出现,新手可能遇不到,但如果你是从旧环境升级上来的,留意一下这个路径。

5.3 现象三:NuGet还原时连接超时

我在第4节提过NuGet源配置,那次超时问题是在刚装完SDK创建项目时遇到的。当时执行dotnet new webapi能正常创建模板,但dotnet restore一直卡在连接api.nuget.org。

确认问题后,我没有选择反复重试,而是直接增加国内镜像源:

dotnet nuget add source https://mirrors.aliyun.com/nuget/v3/index.json -n Aliyun dotnet nuget remove source nuget.org

然后又顺手清理了一次NuGet缓存:

dotnet nuget locals all --clear

重新restore,瞬间成功。这个操作看起来简单,但要提醒一点:清理缓存会把已经下载的包全部删除,下次还原要重新下载。如果不是缓存损坏,尽量不要每次都用all --clear。

5.4 额外记录:无法加载libhostfxr.so

这个坑是在一台内存很小的2GB机器上遇到的,表现是任何dotnet命令都报:

The library libhostfxr.so was not found

原因很直接:内存不足,安装过程中部分文件没有正确解压完成,或者文件系统写入异常。解决方法是确认/usr/lib/dotnet/host/fxr/目录下文件是否完整,如果缺失就直接重新安装SDK包:

sudo apt install --reinstall dotnet-sdk-10.0

另外,在低内存环境下可以考虑设置DOTNET_gcServer=0来减少垃圾回收器的内存占用,这个变量对2GB内存机器上的启动稳定性有帮助。

6. 写给同样在折腾的人的一些提醒

6.1 安装检查单,照着过一遍更稳妥

折腾完这一趟,我把整个流程整理成了检查单,下次在新机器上装dotnet就直接过这一遍:

  1. 确认系统版本为Ubuntu 24.04.x,架构为amd64或arm64。
  2. 替换apt源为本地镜像,执行apt update && apt upgrade -y。
  3. 安装基础依赖:wget、curl、ca-certificates、apt-transport-https、gnupg。
  4. 用24.04专用deb包注册Microsoft源,验证源文件里的代号是noble。
  5. apt install dotnet-sdk-10.0,同时确认需要的其他SDK版本。
  6. 执行dotnet --info和dotnet --list-sdks验证安装。
  7. 创建临时项目,跑通dotnet run和dotnet publish。
  8. 配置NuGet国内镜像源,必要时清理缓存。
  9. 在VS Code或JetBrains Rider里测试终端PATH集成。

每一步时间都不长,加起来5分钟能做完全部验证。千万别跳过第7步,我见过太多人装完SDK不测试就关终端,第二天写代码时才发现问题。

6.2 最后想强调的几件事

根据这次实际安装的经验,有几个观点想专门拿出来说:

第一,apt源方式优于手动解压和snap。不要以为手动解压自由度更高,等到系统库升级后dotnet跑不起来,你会发现包管理器的依赖处理能力才是最省心的。

第二,国内环境下系统源和NuGet源一定要提前配置。装SDK不换源最多慢一点,等创建项目时反复超时那才叫折磨。一次配好,后面所有项目都受益。

第三,多版本SDK共存完全没必要焦虑。dotnet的SDK选择机制做得很好,项目里的global.json或.csproj的目标框架能精确控制使用哪个版本,旧项目的兼容性不会因为系统里装了新版SDK而受影响。

第四,遇到奇怪的报错先看路径。我这次排障的三个问题,两个都出在路径上。/usr/lib/dotnet、/usr/share/dotnet、/usr/bin/dotnet这几个地方只要有一个指向错了,整个环境就像中了邪一样。养成用which dotnet和dotnet --info验证的习惯,能省掉大量排查时间。

第五,如果你和我一样长期需要在Linux下写C#,建议抽空把AOT发布、单文件发布、global tool安装这几个场景都试一遍。这些不是高频操作,但真到部署阶段时,每一个都能救命。

这篇日志写到这里,我的Ubuntu 24.04开发机已经在稳定运行dotnet 10环境了,希望你也能顺利装完,少走这些弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询