.net-8.0systemddotnet-linux

.NET8 app running as a systemd service getting stuck


I have a .NET8 app which I want to run as a systemd service in Ubuntu. I have created a dummy service and a unit file. When I run the service through systemctl, it is not sending the notification to systemd, so the startup gets stuck and fails after a minute with timeout.

Here is my .NET8 service code:

public static void Main(string[] args)
{
    ConfigureLogger();
    
    var logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    logger.Info($"Starting gRPC service. Time: [{DateTime.Now}]...");

    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.
    builder.Services.AddGrpc();
    builder.Host.UseSystemd();
    
    var app = builder.Build();

    // Configure the HTTP request pipeline.
    app.MapGrpcService<GreeterService>();
    app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

    logger.Info("Before Run..");
    app.Run();

    logger.Info("After Run()..");
}

Here is my unit file:

[Unit]
Description=gRPC test Service

[Service]
ExecStart=sudo /usr/bin/dotnet /opt/TrialCode/GrpcTestService/GrpcTestService.dll
WorkingDirectory=/opt/TrialCode/GrpcTestService
Type=notify

[Install]
WantedBy=multi-user.target

When I start the service using systemctl, I get below message:

root@GW6SLX3-PC:/etc/systemd/system# systemctl start GrpcTest.service
Job for GrpcTest.service failed because a timeout was exceeded.
See "systemctl status GrpcTest.service" and "journalctl -xeu GrpcTest.service" for details.

In the logs, I see below entries:

2025-03-18 12:53:00,377 (INFO) [1] ((null), (null)) - Starting gRPC service. Time: [03/18/2025 12:53:00]...
2025-03-18 12:53:00,536 (INFO) [1] ((null), (null)) - Before Run..
2025-03-18 12:54:30,402 (INFO) [1] ((null), (null)) - After Run()..

In all the documents that I have read, the key point was to call UseSystemd() and set "Type=notify". Why is this not working for me?


Solution

  • You are using sudo, which runs the program as a child process; meaning that systemd considers the sudo process – not the dotnet process – to be the "main service process" and only allows notification messages to come from sudo (which of course doesn't send any), not from the dotnet runtime.

    On top of that, sudo likely cleans away the environment variables set by systemd to indicate the notify socket address so that dotnet may not even know where to send the notification.

    In short, do not use sudo in systemd services. It is completely redundant here as .service units already run the process as 'root' by default anyway – not to mention being a bad idea to run a web app as root – and you have the built-in User= parameter for when you do decide to run the program as some other account.