问题:C# 应用程序在 docker 中失败,但在主机上没有“无法从命令行启动服务”

我们有一个内部开发的 C# .NET 应用程序,我们正试图将其放入 Windows 容器中。该应用程序最初设计为作为服务运行,但似乎容器最好作为进程运行。所以开发人员做了一些小改动,我们现在可以从命令行运行应用程序了。它在 Win 10、2012 R2、2016 和 2019 上成功运行。

但是,当尝试在 2016 或 2019 容器上运行完全相同的应用程序时,我们会收到错误消息:

无法从命令行或调试器启动服务。必须首先安装 Windows 服务(使用 installutil.exe),然后使用 ServerExplorer、Windows 服务管理工具或 NET START 命令启动。

为什么在容器中运行会改变应用程序的运行方式?应用程序没有不包含在应用程序中的依赖项(.NET 除外)。

我能够成功地将应用程序作为服务安装在容器中,并在没有错误的情况下启动该服务。但是,即使通过 docker run 中的-p 80:80选项暴露端口,尝试在容器中或容器外部 curlhttp://localhost也会失败。

我已经看到这个应用程序的早期版本作为一个进程在 docker 容器中成功运行,所以我认为它必须是 C# 的一些警告,但我不是开发人员,我得到一个标准的“它在主机上运行,它一定是码头工人的事情”来自我们开发人员的回答。

解答

事实证明,代码在Environment.UserInteractive上有一个 if 语句,告诉它是作为控制台还是服务。在 Windows Docker 容器中,Environment.UserInteractive总是因为某种原因触发为假,这迫使应用程序即使在作为控制台运行时也能提供服务。我们使用环境变量来覆盖 if。

值得注意的是,显然在 .NET Core 中,该变量始终触发为 true,考虑到通常触发 Linux 应用程序的方式,这可能会有所帮助。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐