Artwork by Ashley Willis on GitHub
I'm running on Xubuntu 22.04 day in day out working with .NET most of the time, so downtime is not an option.
.NET 6 SDK was installed using the dotnet6
package from Ubuntu.
Shortly after Microsoft released .NET 7, I wanted to upgrade, but it did not work because of this error:
Package 'dotnet-sdk-7.0' has no installation candidate
So, no .NET 7 for me so far.
Last weekend has been the time when I finally wanted to install .NET 7 SDK side-by-side with the existing .NET 7 SDK because I wanted to test out some stuff:
This 👇https://t.co/WdanSAlhvW
— Alexander Zeitler (@lxztlr) January 27, 2023
And side projects ofc https://t.co/xrrLC8tV35 pic.twitter.com/rzMkeyIHYR
As I knew there would be some trouble I pulled out the Microsoft installation Guide for .NET 7 on Ubuntu. I also had an eye on the troubleshooting guide for mixed installations like my scenario was.
So my first attempt has been this:
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
And it failed (obviously, because this would not be worth a blog post):
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package dotnet-sdk-7.0 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package 'dotnet-sdk-7.0' has no installation candidate
Back to the troubleshooting guide, I prioritized the Microsoft package feed for the dotnet-sdk-7.0
package as described in the guide by editing / adding /etc/apt/preferences
:
Package: dotnet-sdk-7.0
Pin: origin "packages.microsoft.com"
Pin-Priority: 999
Next sudo apt update && sudo apt install dotnet-sdk-7.0
: no errors.
Let's try dotnet --list-sdks
:
6.0.405 [/usr/share/dotnet/sdk]
7.0.102 [/usr/share/dotnet/sdk]
Restrained joy. Should that have been it?
Of course - not.
Back to my major project, I noticed that .NET 6 SDK (via dotnet run --framework net6.0
) stopped working:
dotnet run --framework net6.0
Building...
You must install or update .NET to run this application.
App: /home/alexzeitler/src/myproject/bin/Debug/net6.0/myproject
Architecture: x64
Framework: 'Microsoft.NETCore.App', version '6.0.0' (x64)
.NET location: /usr/share/dotnet
The following frameworks were found:
7.0.2 at [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Learn about framework resolution:
https://aka.ms/dotnet/app-launch-failed
To install missing framework, download:
https://aka.ms/dotnet-core-applaunch?framework=Microsoft.NETCore.App&framework_version=6.0.0&arch=x64&rid=ubuntu.22.04-x64
Maybe add a global.json
inside project folder?
{
"sdk": {
"version": "6.0.405",
"rollForward": "latestMinor",
"allowPrerelease": false
}
}
Nobody likes your global.json
, Alex.
"Maybe I should just move on and work with .NET 7 locally...".
Didn't want that, but I didn't want to invest more time and I also wanted to keep .NET 7 SDK installed.
So, I updated the csproj
file like this to target .NET 6 and .NET 7:
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
Now I could use build and run my project locally using .NET 7 and tests did also work.
That's all nice but how about some broken CI builds?
Of course this didn't work as expected because the project has multiple targets now, and you need to specify a framework version in your Docker build.
"Well, that's easy".
No, it's not.
dotnet restore
doesn't understand --framework
flag.
But: it does understand a MSBuild parameter called TargetFramework
.
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore -p:TargetFramework=net6.0
So, this should also work for dotnet publish
one might guess...
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore -p:TargetFramework=net6.0
# Build and publish a release
RUN dotnet publish --framework net6.0 -p:TargetFramework=net6.0 -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "MyApp.dll"]
Hard "no", again.
And it's not interested in your --framework
flag also, Alex.
For whatever reason, this command did work outside the Docker build.
Meanwhile, I got a suggestion to try the .NET Core plugin for the asdf
version manager and do a manual install (did I mention we really should have something like nvm
for Node?).
I was tempted to walk this path, but something dragged me to take a look at the issues for the plugin first.
And there it was: Rider can't detect dotnet sdk.
And this ongoing issue dug another rabbit hole.
Ok, time to chop some wood.
It's been late in the evening and I did not want to start the next day with a broken installation, so I decided to wipe .NET SDK completely and start with a fresh install.
sudo apt remove dotnet-sdk-6.0 dotnet-sdk-7.0
Now dotnet --version
shouldn't work, but...
6.0.13
Wait, what?
Turns out, there's still something left from the Ubuntu .NET 6 SDK install. So comment out the settings in /etc/apt/preferences
.
sudo apt remove dotnet6
Finally, gone.
Next: reinstall .NET 6 SDK.
Undo the comment out of the settings in /etc/apt/preferences
:
Package: dotnet-* aspnetcore-* netstandard-*
Pin: origin "packages.microsoft.com"
Pin-Priority: 999
sudo apt clean
sudo apt update
sudo apt install dotnet-sdk-6.0
No errors.
dotnet --version
A fatal error occurred. The folder [/usr/share/dotnet/host/fxr] does not exist
Great.
But apt install
did tell me, the dependencies for dotnet-sdk-6.0
have been installed...
Turns out, they have been installed from Ubuntu packages and dotnet-sdk-6.0
has been installed from Microsoft packages.
So, remove everything again, but also the dependencies:
sudo apt remove dotnet-sdk-6.0
sudo apt autoremove #this will remove the unused dependencies
Update the /etc/apt/preferences
again. This time include all dependencies:
Package: dotnet-* aspnetcore-* netstandard-*
Pin: origin "packages.microsoft.com"
Pin-Priority: 999
Next try:
sudo apt update
sudo apt install dotnet-sdk-6.0
dotnet --version
6.0.405
Good. Next: Run the app:
dotnet run
[08:32:51 INF] Now listening on: https://0.0.0.0:5001
[08:32:51 INF] Now listening on: http://0.0.0.0:5000
[08:32:51 DBG] Loaded hosting startup assembly MyProject
[08:32:51 DBG] Loaded hosting startup assembly Microsoft.AspNetCore.Watch.BrowserRefresh
[08:32:51 INF] Application started. Press Ctrl+C to shut down.
[08:32:51 INF] Hosting environment: Development
[08:32:51 DBG] Hosting started
Ok, let's try dotnet watch run
.
dotnet watch run
You must install .NET to run this application.
App: /home/alexzeitler/.dotnet/tools/dotnet-outdated
Architecture: x64
App host version: 6.0.13
.NET location: Not found
Learn about runtime installation:
https://aka.ms/dotnet/app-launch-failed
Download the .NET runtime:
https://aka.ms/dotnet-core-applaunch?missing_runtime=true&arch=x64&rid=ubuntu.22.04-x64&apphost_version=6.0.13
Still something broken - but what?
Looks like it's not just me having issues: .NET runtime not found on Ubuntu
Ok, let's follow the advice and set /etc/dotnet/install_location
to /usr/share/dotnet
.
Then fix the missing DOTNET_ROOT
environment variable and add (re-add?) that path to the PATH
environment variable in ~/.zshrc
:
export DOTNET_ROOT=/usr/share/dotnet
export PATH=$PATH:$DOTNET_ROOT
Source the updated .zshrc
:
. ~/.zshrc
Try a dotnet
tool:
dotnet-outdated
Discovering projects...The directory '/home/alex' does not contain any solutions or projects.
Fine. Try to dotnet watch run
the project again:
[08:32:51 INF] Now listening on: https://0.0.0.0:5001
[08:32:51 INF] Now listening on: http://0.0.0.0:5000
[08:32:51 DBG] Loaded hosting startup assembly MyProject
[08:32:51 DBG] Loaded hosting startup assembly Microsoft.AspNetCore.Watch.BrowserRefresh
[08:32:51 INF] Application started. Press Ctrl+C to shut down.
[08:32:51 INF] Hosting environment: Development
[08:32:51 DBG] Hosting started
Ok. I can get my work done tomorrow.
But what about .NET 7 SDK?
"It's just 1:30am so why not give it a try again?"
sudo apt update
sudo apt install dotnet-sdk-7.0
No errors.
dotnet --list-sdks
6.0.405 [/usr/share/dotnet/sdk]
7.0.102 [/usr/share/dotnet/sdk]
Open the .NET 6 Project in Rider with only .NET 6 targeted again:
<TargetFramework>net6.0</TargetFramework>
Loads.
Try to build.
Works.
Try to run the tests.
Works.
Open a .NET 7 project.
Try to build.
Works.
Try to run the tests.
Works.
YES!