Here's my config.yaml
file
server:
port: 5000
here's my logic to unmarshal using viper
type Configurations struct {
Server ServerConfig
}
type ServerConfig struct {
Port int
}
// LoadConfig reads configuration from file or environment variables.
func LoadConfig(path string) (config Configurations, err error) {
viper.AddConfigPath(path)
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AutomaticEnv()
err = viper.ReadInConfig()
if err != nil {
return
}
err = viper.Unmarshal(&config)
return
}
I have set env variable export PORT=9000
, now my question is how can I map the environmental variable PORT
to Configurations.ServerConfig.Port
.
I would like to have config file with default values for dev and would like my app to read/override config from env variables on production, how can I achieve this using viper.
I see following options
SERVER_PORT
and then use replacer like below to unmarshal it to structreplacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
But I would like to map variable PORT
to the struct member, probably because my hosting service provider sets PORT
env variable, and I cannot use 2nd point because I would like to have yaml for default values.
You can use viper.BindEnv(string...) error
to bind specific environment variables to configuration.
From Working with Environment Variables:
BindEnv takes one or more parameters. The first parameter is the key name, the rest are the name of the environment variables to bind to this key. If more than one are provided, they will take precedence in the specified order.
Here the configuration key for the port is server.port
, and the environment variable PORT
should bind to it.
...
viper.AutomaticEnv()
err = viper.BindEnv("server.port", "PORT")
if err != nil {
return
}
err = viper.ReadInConfig()
...
With this change in place a call like PORT=9999 ./yourbinary
picks up PORT
and writes it into server.port
. From there, it will be unmarshalled into your struct.