如何修复从 Go 中的 system-d 服务运行时环境变量不起作用的问题

问题描述 投票:0回答:4

我使用

os.Getenv("APP_PATH")
从系统环境变量中读取,在正常运行应用程序的构建时它工作正常。但我需要将此 Go 程序作为服务运行,这是我使用 systemd 完成的,在这种情况下它无法读取环境变量。有什么办法可以解决这个问题吗

go
4个回答
9
投票

您可以按照此处的操作来使用环境变量。我在项目中实现环境变量的方式是 GODOTENV go 库。它非常容易实现并且独立于平台。

只需运行

err = godotenv.Load(filepath.Join(path_dir, ".env"))

你就完成了。现在您可以使用代码

os.Getenv("APP_PATH")
.env
文件中读取密钥,并且它与 systemd 服务完美配合。


8
投票

这取决于您运行 systemd 服务的方式。 Systemd 提供了一堆你应该使用的贬义词:

[Unit]
Description=My service
After=network.target

[Service]
Type=simple
User=user
Group=user
EnvironmentFile=/home/user/env_file
ExecStart=/bin/bash -c -l '/home/user/go_program'
# ... other directive goes here

[Install]
WantedBy=multi-user.target
  • EnvironmentFile
    - 带有 ENV 变量的文件,该文件将由 systemd 为您加载。

  • User
    Group
    - 程序应在哪个用户和组下运行。

  • ExecStart=/bin/bash -c -l '/home/user/go_program'
    -
    -l
    选项使 bash 的行为就好像它已被调用为登录 shell,因此将加载
    .bash_profile
    中的变量(请参阅
    User
    Group
    部分)。

6
投票

我们的环境变量位于 .env 文件中并使用 godotenv

    import {
       "github.com/joho/godotenv"
    }

    func main() {

        dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
        if err != nil {
            log.Fatal(err)
        }
        environmentPath := filepath.Join(dir, ".env")
        err = godotenv.Load(environmentPath)
        fatal(err)
    }

当我们以守护进程模式运行应用程序时,它就可以工作了


0
投票

如果您在使用

godotenv 包时遇到错误 Error loading .env file,这意味着您必须将 
.env
文件的完整路径传递给
Load
函数。

如果您的

main.go
文件位于
/cmd/main.go
.env
文件位于根文件夹
/.env
,请使用此示例

import (
    "fmt"
    "github.com/joho/godotenv"
    "log"
    "os"
    "path/filepath"
)

func main() {
    pwd, err := os.Getwd()
    if err != nil {
        panic(err)
    }
    
    //use ../.env because main.go inside /cmd
    err = godotenv.Load(filepath.Join(pwd, "../.env"))
    if err != nil {
        log.Fatal("Error loading .env file")
    }
    fmt.Println(fmt.Sprintf("MYVAR=%s", os.Getenv("MYVAR")))
}
© www.soinside.com 2019 - 2024. All rights reserved.