DotNET: Difference between revisions
Tomodachi94 (talk | contribs) m ryantm link -> canonical Nixpkgs manual link |
Lord-Valen (talk | contribs) m Use the correct command name. |
||
(20 intermediate revisions by 6 users not shown) | |||
Line 4: | Line 4: | ||
Example build file: | Example build file: | ||
< | <syntaxhighlight lang="nix" line="1" start="1"> | ||
{ | { | ||
, | buildDotnetModule, | ||
dotnetCorePackages, | |||
}: | }: | ||
buildDotnetModule | buildDotnetModule { | ||
pname = " | pname = "hello"; | ||
version = " | version = "0.1"; | ||
src = ./.; | |||
projectFile = "Hello/Hello.csproj"; | |||
dotnet-sdk = dotnetCorePackages.sdk_8_0; | |||
dotnet-runtime = dotnetCorePackages.runtime_8_0; | |||
nugetDeps = ./deps.json; | |||
} | |||
</syntaxhighlight> | |||
If the <code>fetch-deps</code> script isn't working for whatever reason, you can manually run <code>nuget-to-json</code>: | |||
<syntaxhighlight lang="shell-session"> | |||
$ dotnet restore --packages=packageDir ./SomeProject.csproj | |||
$ nuget-to-json packageDir > deps.json | |||
$ rm -r packageDir | |||
</syntaxhighlight> | |||
Remember to build and run the <code>fetch-deps</code> script after NuGet packages are updated, or building the derivation will fail. | |||
== Building non-.NET Core packages == | |||
Keep in mind that building projects which don't use the .NET SDK (formerly the .NET Core SDK) and its <code>dotnet</code> CLI tool isn't supported. | |||
For those projects, you'll have to heavily customise the <code>buildDotnetModule</code> build steps, or write a custom derivation. | |||
Projects which target .NET Standard or .NET Framework (incl. Mono), but still use the new project structure and SDK, work as expected. | |||
Just remember to add `mono` to `buildInputs` and generate a wrapper script in `postInstall`. | |||
== Packaging ASP.NET projects == | |||
Currently building ASP.NET project as Nix package produces a website that does not work correctly out of the box because the executable can not find <code>wwwroot</code>, so all the static assets won't load with 404. | |||
<blockquote> | |||
Request finished HTTP/2 GET https://my.app/css/site.css - 404 0 | |||
</blockquote> | |||
The situation can be fixed by setting <code>WEBROOT</code> environment variable to the package path. | |||
An example of systemd + ASP.NET 8 service: | |||
<syntaxhighlight lang="nix"> | |||
# myapp package needs to be imported; and added to `environment.systemPackages` | |||
# the variable myapp is used below | |||
systemd.services.my-app = { | |||
enable = true; | |||
description = "Runs my.app"; | |||
wantedBy = [ "multi-user.target" ]; | |||
after = [ "network-online.target" ]; | |||
wants = [ "network-online.target" ]; | |||
serviceConfig = { | |||
# allow binding to privileged ports - when you want to expose Kestrel directly without reverse proxy | |||
AmbientCapabilities = "CAP_NET_BIND_SERVICE"; | |||
User = "myapp"; # must be created using users.users.myapp = { isSystemUser = true; group = "myapp"; }; | |||
Group = "myapp"; # must be created using users.groups.myapp = {}; | |||
Restart = "always"; | |||
ExecStart = "${myapp}/bin/myapp"; | |||
StateDirectory = "myapp"; | |||
StateDirectoryMode = "0750"; | |||
WorkingDirectory = "/var/lib/myapp"; | |||
# EnvironmentFile = "/var/lib/myapp/env"; | |||
}; | }; | ||
environment = { | |||
WEBROOT = "${myapp}/lib/myapp/wwwroot"; # IMPORTANT, required to pick up static assets | |||
DOTNET_ENVIRONMENT = "Production"; | |||
# the following are examples | |||
ConnectionStrings__DefaultConnection = "Host=/var/run/postgresql;Database=myapp"; | |||
# Kestrel + HTTPS; must setup https://wiki.nixos.org/wiki/ACME | |||
Kestrel__Endpoints__Https__Url = "https://my.app"; | |||
Kestrel__Endpoints__Https__Certificate__Path = "/var/lib/acme/my.app/cert.pem"; | |||
Kestrel__Endpoints__Https__Certificate__KeyPath = "/var/lib/acme/my.app/key.pem"; | |||
Logging__LogLevel__Default = "Information"; | |||
Logging__LogLevel__Microsoft__AspNetCore = "Warning"; # this does not actually work, not sure how to fix | |||
Authentication__Google__ClientId = "xxxyyyzzz.apps.googleusercontent.com"; | |||
Authentication__Microsoft__ClientId = "aaaaaa-0000-aaaa-0000-aaaaaaaaaa"; | |||
# secrets must be placed in /var/lib/myapp/appsettings.json | |||
# TODO email | |||
# TODO Stripe | |||
Stripe__Currency = "USD"; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
See also: setting up SSL certificates using [[ACME]] | |||
== .NET location: Not found == | == .NET location: Not found == | ||
If running a .NET-build executable you get the above error, make sure the DOTNET_ROOT environment variable is set: | If running a .NET-build executable you get the above error, make sure the DOTNET_ROOT environment variable is set: | ||
< | <syntaxhighlight lang="nix"> | ||
environment.sessionVariables = { | environment.sessionVariables = { | ||
DOTNET_ROOT = "${pkgs.dotnet-sdk}"; | DOTNET_ROOT = "${pkgs.dotnet-sdk}/share/dotnet/"; | ||
}; | }; | ||
</ | </syntaxhighlight> | ||
See : https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#net-sdk-and-cli-environment-variables | See : https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#net-sdk-and-cli-environment-variables | ||
Line 61: | Line 126: | ||
Wontfix: The project will build only on Windows. | Wontfix: The project will build only on Windows. | ||
== Unable to find package == | |||
<blockquote> | |||
error NU1101: Unable to find package runtime.any.System.Collections. No packages exist with this id in source(s): nugetSource | |||
</blockquote> | |||
Unsure what specific situations cause this, probably has something to do with .NET Standard libraries. | |||
The workaround is modifying the bits that generate nuget-deps.nix: | |||
<syntaxhighlight lang="sh"> | |||
dotnet restore --packages=packageDir --use-current-runtime ./SomeProject.csproj | |||
nuget-to-nix packageDir >deps.nix | |||
rm -r packageDir | |||
</syntaxhighlight> | |||
The new parameter <code>--use-current-runtime</code> requires .NET SDK 8+. I believe what it does is explicitly adding packages missing in this runtime vs .NET Standard to packageDir. | |||
If this still does not work, it might indicate a good time to update target frameworks and dependencies. | |||
== NativeAOT == | == NativeAOT == | ||
Line 115: | Line 202: | ||
== Example: Running Rider with dotnet & PowerShell == | == Example: Running Rider with dotnet & PowerShell == | ||
Rider has better compatibility when run in FHS mode | |||
Rider package | Rider package<syntaxhighlight lang="nix"> | ||
< | |||
pkgs.jetbrains.rider | pkgs.jetbrains.rider | ||
</ | </syntaxhighlight>rider-fhs.nix<syntaxhighlight lang="nix"> | ||
{ pkgs ? import <nixpkgs> {} }: | |||
(pkgs.buildFHSEnv { | |||
name = "rider-env"; | |||
targetPkgs = pkgs: (with pkgs; [ | |||
dotnetCorePackages.dotnet_8.sdk | |||
dotnetCorePackages.dotnet_8.aspnetcore | |||
name = " | |||
powershell | powershell | ||
]; | ]); | ||
} | multiPkgs = pkgs: (with pkgs; [ | ||
</ | ]); | ||
runScript = "nohup rider &"; | |||
}).env | |||
</syntaxhighlight><syntaxhighlight lang="nix"> | |||
< | nix-shell ./rider-fhs.nix | ||
nix-shell ./ | </syntaxhighlight>This can be added as an alias to your shell if you update the reference to an absolute address, such as location within your home directory. <syntaxhighlight> | ||
</ | run-rider = "nix-shell ~/nix/rider-fhs.nix"; | ||
</syntaxhighlight> | |||
This can be added as an alias to your shell if you update the reference to an absolute address, such as location within your home directory. | |||
== Example: multi-SDK installation with local workload installation enabled == | == Example: multi-SDK installation with local workload installation enabled == | ||
Line 159: | Line 237: | ||
* [https://nixos.org/manual/nixpkgs/unstable/#dotnet dotnet in the nixpkgs manual] | * [https://nixos.org/manual/nixpkgs/unstable/#dotnet dotnet in the nixpkgs manual] | ||
* [https://github.com/search?q=repo%3ANixOS%2Fnixpkgs%20buildDotnetModule&type=code buildDotnetModule references in nixpkgs] | * [https://github.com/search?q=repo%3ANixOS%2Fnixpkgs%20buildDotnetModule&type=code buildDotnetModule references in nixpkgs] | ||
* [https://www.reddit.com/r/NixOS_dotnet NixOS.NET community on Reddit] | |||
* [https://discord.gg/pTpq7Qfs NixOS.NET community on Discord] | |||
* [https://sgt.hootr.club/molten-matter/dotnet-on-nix/ The journey of packaging a .NET app on Nix] | * [https://sgt.hootr.club/molten-matter/dotnet-on-nix/ The journey of packaging a .NET app on Nix] | ||
* https://en.wikipedia.org/wiki/.NET_Framework - The old, windows-only version of .NET. Newer versions (ie. .NET Core) are multiplatform. | * https://en.wikipedia.org/wiki/.NET_Framework - The old, windows-only version of .NET. Newer versions (ie. .NET Core) are multiplatform. | ||
** https://en.wikipedia.org/wiki/Mono_(software) is the | ** https://en.wikipedia.org/wiki/Mono_(software) is the open source reimplementation of .NET Framework. Its runtime/JIT has been merged into .NET Core, and now it only receives bugfixes. | ||
* https://learn.microsoft.com/en-us/dotnet/core/introduction | * https://learn.microsoft.com/en-us/dotnet/core/introduction | ||
[[Category: | |||
[[Category:Languages]] |