Linux System.d 单元服务看不到我的特定环境变量

我有一个基本的“服务单元”文件,如下所示。


[Unit]

Description=Certprovider service

After=network.target


[Service]

Type=simple

Restart=always

RestartSec=5s

ExecStart=/home/mert/certprovider/certprovider

WorkingDirectory=/home/mert

User=root

Group=root


[Install]

WantedBy=multi-user.target

我在项目的根目录中有.env文件。


CA_DIR_URL=https://acme-v02.api.letsencrypt.org/directory

EMAIL=mertsmsk0@gmail.com


HOST=127.0.0.1

PORT=8557

我用以下几行加载这个文件。


err := godotenv.Load()

if err != nil {

    log.Fatalln("Error loading .env file")

}

服务一直运行良好,但我无法访问PORT环境变量。因此我无法启动网络服务器,因为该端口无法侦听。我打印.env中不包括PORT的所有环境变量。我将其名称更改为APP_PORT但它是一样的。


神秘的部分是我可以访问.env文件中的其他变量。除此之外,当我在单元文件中添加以下行时,我可以访问该变量,但我不明白为什么我应该在单元文件中只添加PORT变量?


[Service]

Environment=PORT=8557

当我尝试将它作为二进制文件运行时,就会发生这种情况。因为我可以使用以下命令访问变量。


go run .


肥皂起泡泡
浏览 89回答 1
1回答

慕尼黑的夜晚无繁华

如果您在没有任何参数的情况下调用 Load ,它将默认在当前路径中加载 env。您的当前路径在此处配置:WorkingDirectory=/home/mert然而,你说(强调)我在项目的根目录中有 .env 文件。但这不是当前的工作目录。项目的根该概念对应用程序运行时没有意义。与 PHP 等解释性语言不同,Go 编译为静态二进制文件,该二进制文件在功能上与定义它的库和源集完全不同。在 PHP(或 python、ruby 等)中,这些库除了某个项目目录的根目录之外别无他处。在 go 中,这些东西只与开发和测试相关。您的可执行文件似乎位于“项目的根目录”中,这一事实完全是偶然的,完全没有意义。如果您真的想将运行时配置放在特定文件中,在该特定位置,只需将其设置为工作目录:ExecStart=/home/mert/certprovider/certprovider WorkingDirectory=/home/mert/certprovider/certprovider我会把这些东西放进去,/usr/local这样我就不会在摆弄我的主目录中的东西时意外破坏我的 let's encrypt —— 让我们加密更是如此,因为它可能需要长达 90 天才能意识到你的证书没有被刷新。出于同样的原因,我将配置放在我的主目录之外。实际上,对于这种情况,我可能会将所有配置放在单元文件中。为什么不把它放在那里?但当然,这是见仁见智的问题。如果您真的想使用自动.env发现,那么您应该指定一个目录来包含该隐藏文件。将特定于一个应用程序的配置放入~/.env.无论您放在哪里.env,请确保这是您的工作目录,以便被发现。我打印了 .env 中不包括 PORT 的所有环境变量。我将其名称更改为 APP_PORT 但它是一样的。[...] 神秘的部分是我可以访问 .env 文件中的其他变量。恕我直言,这听起来像是您的假设。如果没有相反的证据,很容易断定您已经为这些值设置了默认值,或者它们来自其他来源或行为。这比让godotenv库从文件中读取一些(但不是全部)值更简洁。当我尝试将它作为二进制文件运行时,就会发生这种情况。因为我可以使用以下命令访问变量。[ go run .]Go总是作为二进制文件运行。 go run .只需在临时位置自动构建二进制文件,然后运行它。 为什么在生产环境中运行 Go 应用程序时建议使用 `go build` 而不是 `go run`?谈论为什么go run在 SO 上经常被禁忌。
打开App,查看更多内容
随时随地看视频慕课网APP