DotNET: Difference between revisions

Lostmsu (talk | contribs)
create systemd service from an ASP.NET-based package
m Use the correct command name.
 
(9 intermediate revisions by 6 users not shown)
Line 4: Line 4:
Example build file:
Example build file:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix" line="1" start="1">
{ fetchFromGitHub
{
, dotnetCorePackages
  buildDotnetModule,
, buildDotnetModule
  dotnetCorePackages,
}:
}:


buildDotnetModule rec {
buildDotnetModule {
   pname = "some_program";
   pname = "hello";
   version = "some_version";
   version = "0.1";


   src = fetchFromGitHub {
   src = ./.;
    owner = "some_owner";
    repo = pname;
    rev = "v${version}";
    hash = ""; # use e.g. `nix-prefetch-git`
  };


   projectFile = "SomeProject/SomeProject.csproj";
   projectFile = "Hello/Hello.csproj";
   dotnet-sdk = dotnetCorePackages.sdk_8_0;
   dotnet-sdk = dotnetCorePackages.sdk_8_0;
   dotnet-runtime = dotnetCorePackages.runtime_8_0;
   dotnet-runtime = dotnetCorePackages.runtime_8_0;
   nugetDeps = ./deps.nix; # to generate, set to `""`, then `nix-build -A fetch-deps && ./result`
   nugetDeps = ./deps.json;
 
  meta = with lib; {
    homepage = "some_homepage";
    description = "some_description";
    license = licenses.mit;
  };
}
}


</syntaxhighlight>
</syntaxhighlight>


If the <code>fetch-deps</code> script isn't working for whatever reason, you can manually run <code>nuget-to-nix</code>:
If the <code>fetch-deps</code> script isn't working for whatever reason, you can manually run <code>nuget-to-json</code>:
<syntaxhighlight lang="sh">
<syntaxhighlight lang="shell-session">
dotnet restore --packages=packageDir ./SomeProject.csproj
$ dotnet restore --packages=packageDir ./SomeProject.csproj
nuget-to-nix packageDir >deps.nix
$ nuget-to-json packageDir > deps.json
rm -r packageDir
$ rm -r packageDir
</syntaxhighlight>
</syntaxhighlight>


Line 54: Line 43:
== Packaging ASP.NET projects ==
== 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 `wwwroot`, so all the static assets won't load with 404.
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.


> Request finished HTTP/2 GET https://my.app/css/site.css - 404 0
<blockquote>
Request finished HTTP/2 GET https://my.app/css/site.css - 404 0
</blockquote>


The situation can be fixed by setting `WEBROOT` environment variable to the package path.
The situation can be fixed by setting <code>WEBROOT</code> environment variable to the package path.


An example of systemd + ASP.NET 8 service:
An example of systemd + ASP.NET 8 service:


```nix
<syntaxhighlight lang="nix">
# myapp package needs to be imported; and added to `environment.systemPackages`
# myapp package needs to be imported; and added to `environment.systemPackages`
# it is used below
# the variable myapp is used below


systemd.services.my-app = {
systemd.services.my-app = {
Line 73: Line 64:
   wants = [ "network-online.target" ];
   wants = [ "network-online.target" ];
   serviceConfig = {
   serviceConfig = {
     AmbientCapabilities = "CAP_NET_BIND_SERVICE"; # allow binding to privileged ports - when you want to expose Kestrel directly without reverse proxy
     # 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"; };
     User = "myapp"; # must be created using users.users.myapp = { isSystemUser = true; group = "myapp"; };
     Group = "myapp"; # must be created using users.groups.myapp = {};
     Group = "myapp"; # must be created using users.groups.myapp = {};
Line 110: Line 102:
};
};


```
</syntaxhighlight>
[ACME](https://wiki.nixos.org/wiki/ACME)
 
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>
<syntaxhighlight lang="nix">
environment.sessionVariables = {
environment.sessionVariables = {
   DOTNET_ROOT = "${pkgs.dotnet-sdk}";
   DOTNET_ROOT = "${pkgs.dotnet-sdk}/share/dotnet/";
};
};
</syntaxHighlight>
</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 133: 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 187: 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">
 
<syntaxHighlight lang=nix>
pkgs.jetbrains.rider
pkgs.jetbrains.rider
</syntaxHighlight>
</syntaxhighlight>rider-fhs.nix<syntaxhighlight lang="nix">
 
{ pkgs ? import <nixpkgs> {} }:
dotnet.nix


<syntaxHighlight lang=nix>
(pkgs.buildFHSEnv {
with import <nixpkgs> {};
   name = "rider-env";
 
   targetPkgs = pkgs: (with pkgs; [
mkShell {
    dotnetCorePackages.dotnet_8.sdk
   name = "dotnet-env";
     dotnetCorePackages.dotnet_8.aspnetcore
   packages = [
    (with dotnetCorePackages; combinePackages [
      sdk_6_0
      sdk_7_0
      sdk_8_0
     ])
     powershell
     powershell
   ];
   ]);
}
  multiPkgs = pkgs: (with pkgs; [
</syntaxHighlight>
  ]);
 
  runScript = "nohup rider &";
To execute Rider
}).env
 
</syntaxhighlight><syntaxhighlight lang="nix">
<syntaxHighlight lang=bash>
nix-shell ./rider-fhs.nix
nix-shell ./dotnet.nix --run 'nohup rider &'
</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>
</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. e.g. `~/nix/dotnet.nix`


== Example: multi-SDK installation with local workload installation enabled ==
== Example: multi-SDK installation with local workload installation enabled ==
Line 238: Line 244:
* https://learn.microsoft.com/en-us/dotnet/core/introduction
* https://learn.microsoft.com/en-us/dotnet/core/introduction


[[Category: Development]]
 
[[Category:Languages]]