Context
As part of a CLI application, I have integrated viper to manage the different configuration streams to customize the behavior of the app (e.g, a config file, flags and environment variables).
The CLI loads by default the configuration from a yaml
file, and I wanted to offer the ability to override these settings with the equivalent environment variables. To accomplish this, I tried using the AutomaticEnv
function without result. It turns out that it only takes into account the environment variables when viper
is invoked with the Get
method, not when your using Unmarshal
to a config file.
Solution
There are several workarounds:
- Use
BindEnv
to manually link the desired environment variables before unmarshalling:
if err := viper.BindEnv("VARIABLE"); err != nil {
return err
}
viper.Unmarshal(conf) // Where conf is a struct to hold your configuration
- Use
SetDefault
to declare a default value for the key. That allows the unmarshalling operation to take into account the existing environment variable:
viper.SetDefault("VARIABLE", "default")
viper.Unmarshal(conf) // Where conf is a struct to hold your configuration
- There are some more advanced suggestions, including some that will automate this behavior for all environment variables without having to use
BindEnv
orSetDefault
. You can check those in the linked Github issue below