Building ASP .NET Core app with nix - serving static files

I’ve been playing around building and running a simple .NET Blazor app with nix. It’s very similar to the default Blazor app created using a template.

Based on the information I found online I came up with the following default.nix

{ buildDotnetModule, dotnetCorePackages }:

buildDotnetModule rec {
  pname = "MyApp";
  version = "0.1";
  src = ../.;
  projectFile = "./MyApp.csproj";
  nugetDeps = ./deps.nix;
  buildType = "Release";

  dotnet-sdk = dotnetCorePackages.sdk_7_0;
  dotnet-runtime = dotnetCorePackages.aspnetcore_7_0;

deps.nix was created with nuget-to-nix and for now contains only empty array.

I successfully built the app, but when I run it, the static files fail to load and I see my site without any CSS nor JS.

When I run it from my terminal, I noticed that the Content root path is set to my current folder (notice the last line in the output copied below):

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/bratfizyk/Projects/myApp

However, my static files are stored under /home/bratfizyk/Projects/myApp/result/bin. When I try running it from that folder, I get the following error:

Unhandled exception. System.IO.InvalidDataException: Failed to load configuration from file '/nix/store/5x9a1z9pwn7yl17wjmfi62q0mrkvqdj2-MyApp-0.1/bin/appsettings.json'.
 ---> System.FormatException: Could not parse the JSON file.
 ---> System.Text.Json.JsonReaderException: '#' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
   at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
   at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)

Has anyone deployed a Blazor before, so that now can save me some tears? :slight_smile:

I noticed one more issue: before compilation my static assets are all stored in wwwroot split per category in subfolders (css, etc.). After compilation they all end up in result/bin directory next to the main executable, while I still import them in HTML using pre-build paths.

Is there a way to preserve the pre-build structure?

IIRC buildDotnetModule calls dotnet publish… the final directory structure you see might be caused by this?

Otherwise you could always add a postInstall to rearrange things as necessary.

If you need to dig into how buildDotnetModule works exactly see

1 Like

Hi @mausch
Thanks for the hints.
I worked it out.

I had to:
1.) Add executables = [ "MyApp" ]; to my nix file.
2.) Thanks to the parameter, the binary ended up in result/bin folder, while all the other required files were put in result/lib/MyApp. So in order to make everything work together I had to execute ../bin/MyApp using result/lib/MyApp as working directory.


I’ve read my post once again and found it a bit confusing.
So to clarify:

  • result/bin/MyApp is an executable
  • result/lib/MyApp is a folder containing resources required to launch the executable.
1 Like

fyi my standard pattern for core apps contains this line

makeWrapperArgs = [
  "--set DOTNET_CONTENTROOT ${placeholder "out"}/lib/${pname}"

Which sets up static file serving etc.

1 Like