在 Ubuntu16.04 上使用 systemD 时 DotnetCore 内容根路径发生变化

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

我目前正尝试按照本教程在 Azure 上的 Ubuntu16.04 虚拟机上部署 DotNetCore 应用程序: https://docs.microsoft.com/en-us/aspnet/core/publishing/linuxproduction

dotnet publish 生成的文件夹的内容部署到 vm 后....如果我手动进入项目文件夹并通过 dotnet app_name.dll 启动 Kestrel,它会完美运行并且我'我能够从浏览器访问该应用程序。

手动 运行 dotnet app_name.dll 后我从终端得到的输出是

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

现在,教程要我使用 SystemD 来管理 Kestrel 进程。

它通过 dotnet 为我们运行 ExecStart=/usr/bin/dotnet /var/aspnetcore/app_name.dll。在服务文件中

当我启动该服务时,它看起来会正常工作。我得到:

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

...但是当我尝试访问该应用程序时,红隼从未收到请求。我在两者之间看到的唯一区别是 Content root path.

现在,在项目中引用路径 startup.cs:

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

我尝试对字符串值进行硬编码,但这实际上并没有改变任何东西...

那么,我的网络应用程序无法在 systemD Content root path 下运行的罪魁祸首是什么?

如果是这样,我该如何解决? 如果没有,还有其他我应该注意的问题吗?

您在新建 WebHostBuilder 时调用 .UseContentRoot(Directory.GetCurrentDirectory()) 吗?

如果是这样,那么从 systemd 调用它时将不起作用。您会发现,如果删除该行,它将获得正确的 ContentRoot。

编辑:

跟进 补充答案:是的,您可以在 systemd 配置中指定 WorkingDirectory 作为替代解决方案。您需要做什么取决于您的具体要求和环境。

切记:

如果未设置 WorkingDirectory,则 "defaults to the root directory when systemd is running as a system instance and the respective user's home directory if run as user."

如果设置了 WorkingDirectory 但未设置 RootDirectory "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."(如目录已有)

问题是 Directory.CurrentDirectory() returns dotnet 命令所在的目录 运行。解决这个问题最简单的方法是通过添加以下行来修改systemd配置文件:

 WorkingDirectory=/var/aspnetcore

这会更改执行 dotnet 命令的目录。这样您就不必更改项目的代码,它在本地计算机上的工作方式与在远程计算机上的工作方式相同。

您的应用程序的服务文件可能如下所示:

[Unit]
Description=Example .NET Web API App running on Ubuntu

[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=your-user-name
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

您必须在“User=”行中指定用户名,并且您应该对项目目录具有完全权限(如/var/www/example)。如果您不添加用户线或不更改,您的服务将不会被系统执行。

获取目录权限:

sudo chown -R <user>:<user-group> /var/www/<your-app>
sudo setfacl -R -d -m u:<user>:rwx,g:<user-group>:rwx,o::r /var/www/<your-app>

如果你注意我说的,你的服务会运行没问题。