Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DotnetCore content root path is changing when using systemD on Ubuntu16.04

I am currently trying to deploy a DotNetCore app on a Ubuntu16.04 vm on Azure by following this tutorial: https://docs.microsoft.com/en-us/aspnet/core/publishing/linuxproduction

After deploying the contents of the folder produced by dotnet publish to the vm .... if I manually go into the project folder and start Kestrel via dotnet app_name.dll, it works perfectly and I'm able to access the application from a browser.

The output I get from the terminal after running dotnet app_name.dll manually is

Hosting environment: Production Content root path: /home/myUser/publish Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.

Now, the tutorial wants me use SystemD to manage the Kestrel process.

It runs dotnet for us via ExecStart=/usr/bin/dotnet /var/aspnetcore/app_name.dll. in the service file

When I start the service, it looks like it's going to work. I get:

Hosting environment: Production Content root path: / Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.

... but kestrel never get's the request when I try to access the app. The only difference I'm seeing between the two is the Content root path.

Now, in the project the path is referenced in startup.cs:

public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath ....

I tried hardcoding the string value, but that didn't actually change anything...

So, is the culprit for my web app not working under systemD the Content root path?

If so, how can I fix this? If not, are there any other issues that I should be aware of?

like image 767
Sherman Szeto Avatar asked Dec 09 '16 04:12

Sherman Szeto


2 Answers

Are you calling .UseContentRoot(Directory.GetCurrentDirectory()) when new'ing up your WebHostBuilder?

If so, that's not going to work when it's called from systemd. You'll find that if you remove that line it will get the correct ContentRoot.

Edit:

To follow-up on Arthur's supplemental answer: Yes, you can specify WorkingDirectory in your systemd config as an alternate solution. What you will need to do is dependent on your specific requirements and environment.

Keep in mind:

If WorkingDirectory is not set, it "defaults to the root directory when systemd is running as a system instance and the respective user's home directory if run as user."

If WorkingDirectory is set but RootDirectory is not set "then WorkingDirectory= is relative to the root of the system running the service manager."

"Note that setting this parameter might result in additional dependencies to be added to the unit." (such as the directory existing)

like image 84
Rob Smith Avatar answered Oct 03 '22 00:10

Rob Smith


The problem is that Directory.CurrentDirectory() returns the directory from where the dotnet command was run. The easiest way to solve this problem is to modify the systemd configuration file by adding the following line:

 WorkingDirectory=/var/aspnetcore

This changes the directory from where the dotnet command is executed. This way you don't have to change your project's code and it will work the same way on your local machine as on your remote machine.

like image 38
Arthur Avatar answered Oct 03 '22 00:10

Arthur