最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

systemd - Why does my ASP.NET Core Web API need access to the user's home directory? - Stack Overflow

programmeradmin3浏览0评论

We have an API that was originally written using the ASP.NET MVC framework and hosted on Windows Server. We have now ported it to an ASP.NET Core 8 Web API, and want to host on Linux (Oracle Linux 9). Pretty much got it working - I could run it manually - but when I try to run as a systemd service it fails because it can't access the user's home directory.

I have followed the same pattern for my other Linux services, namely

  • Create a user to run the service as. This is a system user so has no home directory and cannot be logged in as
  • Create a folder, owned by that user, containing the API
  • Create a run script, also owned by that user and in that directory, to start the service
  • Create a systemd service definition, using the run script as ExecStart

My Systemd service definition looks like this:

[Unit]
Description=My API

[Service]
Type=forking
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_NOLOGO=true
ExecStart="/opt/myapi/run.sh"
User=myapiuser
WorkingDirectory=/opt/myapi
Restart=always
RestartSec=3
TimeoutStopSec=30
KillSignal=SIGINT
SyslogIdentifier=myapi

[Install]
WantedBy=multi-user.target

The /opt/myapi/run.sh looks like this:

#!/bin/bash

dotnet MyApi--url=http://localhost:8080 >> /var/log/myapi/myapi.log 2>&1 &

Now systemctl status myapi reports it's running. But if I look at the log file it's clearly crashing and restarting all the time with

2025-02-18 23:03:05.330709268+02:00 Starting: dotnet MyApi --url=http://localhost:8080
System.UnauthorizedAccessException: Access to the path '/home/myapiuser' is denied.
 ---> System.IO.IOException: Permission denied
   --- End of inner exception stack trace ---
   at System.IO.FileSystem.CreateParentsAndDirectory(String fullPath, UnixFileMode unixCreateMode)
   at System.IO.FileSystem.CreateDirectory(String fullPath, UnixFileMode unixCreateMode)
   at System.IO.Directory.CreateDirectory(String path)
   at Microsoft.Extensions.EnvironmentAbstractions.DirectoryWrapper.CreateDirectory(String path)
   at Microsoft.DotNet.Configurer.FileSystemExtensions.<>c__DisplayClass0_0.<CreateIfNotExists>b__0()
   at Microsoft.DotNet.Cli.Utils.FileAccessRetrier.RetryOnIOException(Action action)
   at Microsoft.DotNet.Configurer.DotnetFirstTimeUseConfigurer.Configure()
   at Microsoft.DotNet.Cli.Program.ConfigureDotNetForFirstTimeUse(IFirstTimeUseNoticeSentinel firstTimeUseNoticeSentinel, IAspNetCertificateSentinel aspNetCertificateSentinel, IFileSentinel toolPathSentinel, Boolean isDotnetBeingInvokedFromNativeInstaller, DotnetFirstRunConfiguration dotnetFirstRunConfiguration, IEnvironmentProvider environmentProvider, Dictionary`2 performanceMeasurements)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)

Thing is, I had run it as sudo -u myapiuser dotnet MyApi.dll and it had run. Now I get that same error there.

Anyway, my question is the same: why does it need (or think it needs) access to the user's home directory? I want to run it as a service user, without a home directory.

We have an API that was originally written using the ASP.NET MVC framework and hosted on Windows Server. We have now ported it to an ASP.NET Core 8 Web API, and want to host on Linux (Oracle Linux 9). Pretty much got it working - I could run it manually - but when I try to run as a systemd service it fails because it can't access the user's home directory.

I have followed the same pattern for my other Linux services, namely

  • Create a user to run the service as. This is a system user so has no home directory and cannot be logged in as
  • Create a folder, owned by that user, containing the API
  • Create a run script, also owned by that user and in that directory, to start the service
  • Create a systemd service definition, using the run script as ExecStart

My Systemd service definition looks like this:

[Unit]
Description=My API

[Service]
Type=forking
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_NOLOGO=true
ExecStart="/opt/myapi/run.sh"
User=myapiuser
WorkingDirectory=/opt/myapi
Restart=always
RestartSec=3
TimeoutStopSec=30
KillSignal=SIGINT
SyslogIdentifier=myapi

[Install]
WantedBy=multi-user.target

The /opt/myapi/run.sh looks like this:

#!/bin/bash

dotnet MyApi--url=http://localhost:8080 >> /var/log/myapi/myapi.log 2>&1 &

Now systemctl status myapi reports it's running. But if I look at the log file it's clearly crashing and restarting all the time with

2025-02-18 23:03:05.330709268+02:00 Starting: dotnet MyApi --url=http://localhost:8080
System.UnauthorizedAccessException: Access to the path '/home/myapiuser' is denied.
 ---> System.IO.IOException: Permission denied
   --- End of inner exception stack trace ---
   at System.IO.FileSystem.CreateParentsAndDirectory(String fullPath, UnixFileMode unixCreateMode)
   at System.IO.FileSystem.CreateDirectory(String fullPath, UnixFileMode unixCreateMode)
   at System.IO.Directory.CreateDirectory(String path)
   at Microsoft.Extensions.EnvironmentAbstractions.DirectoryWrapper.CreateDirectory(String path)
   at Microsoft.DotNet.Configurer.FileSystemExtensions.<>c__DisplayClass0_0.<CreateIfNotExists>b__0()
   at Microsoft.DotNet.Cli.Utils.FileAccessRetrier.RetryOnIOException(Action action)
   at Microsoft.DotNet.Configurer.DotnetFirstTimeUseConfigurer.Configure()
   at Microsoft.DotNet.Cli.Program.ConfigureDotNetForFirstTimeUse(IFirstTimeUseNoticeSentinel firstTimeUseNoticeSentinel, IAspNetCertificateSentinel aspNetCertificateSentinel, IFileSentinel toolPathSentinel, Boolean isDotnetBeingInvokedFromNativeInstaller, DotnetFirstRunConfiguration dotnetFirstRunConfiguration, IEnvironmentProvider environmentProvider, Dictionary`2 performanceMeasurements)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)

Thing is, I had run it as sudo -u myapiuser dotnet MyApi.dll and it had run. Now I get that same error there.

Anyway, my question is the same: why does it need (or think it needs) access to the user's home directory? I want to run it as a service user, without a home directory.

Share Improve this question edited yesterday marc_s 755k184 gold badges1.4k silver badges1.5k bronze badges asked yesterday AdamAdam 6,7634 gold badges44 silver badges69 bronze badges 4
  • I agree with your idea, myapiuser no need access to the user's home directory. But for this issue, I suggestion you can give permission of /home/myapiuser to myapiuser first, then check if the application is running or not. – Jason Pan Commented yesterday
  • And please also confirm the path /home/myapiuser exist or not. It looks like environment variable issue, by the way, please share the docker file with us, many thanks~ – Jason Pan Commented yesterday
  • 1 The path does not exist. As I said, it's a system suer without a home directory. That's what I want – Adam Commented yesterday
  • Yes, that's why I asked you to check the path, please share the docker file and other relevant configuration information. – Jason Pan Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 0

I'm still not sure exactly why, but this has fixed itself. I'm pretty sure I was running the exact same command, with the exact same .dll when it didn't work as when it earlier did, but other changes seem to have resolved it.

发布评论

评论列表(0)

  1. 暂无评论