Manage config in Golang to get variables from file and env variables

Felipe Dutra Tine e Silva
2 min readJan 5, 2017

--

If we want to implement the best practices for manage our conf files. So getting variables from a conf file, and from the environment as well. But many developers does not want to manage 2 repository of information. They are used to work with only one config file. So in order to help those who don’t want to manage 2 repositories …

We can scaffold a project like :

main.go
config
|- config.development.json
|- config.production.json

On our main.go (or in a config.go dedicated to manage all configuration)

We should have a struct representing our configuration

type Configuration struct {
Port int
Static_Variable string
Connection_String string
}

On our json file we have a json, describing our configurations key/value :

{
"Port": 8080
"Static_Variable": "static"
}

we will also have the connection_string, but this one will be on the environment variables.

  • So we have to get information from the json :
//filename is the path to the json config file
file, err := os.Open(filename) if err != nil { return err }
decoder := json.NewDecoder(file)
err = decoder.Decode(&configuration)
if err != nil { return err }
  • and from the environment variables
configuration.Connection_String = os.Getenv("Connection_String")

If you don’t want to manage it by yourself, you can use gonfig or viper.

using gonfig

Gonfig will be useful to:

  • have a static configuration context allowing you to have all the configuration everywhere in your app.
  • have a generic way to get all env variables define in your struct.

So in order to use gonfig :

$ go get github.com/tkanos/gonfig

then you just have to define your struct

type Configuration struct {
Port int
Static_Variable string
Connection_String string
}

and send the filename and the struct to gonfig :

configuration := Configuration{}
err := gonfig.GetConf("path/to/myjonfile.json", &configuration)

So now we are able to manage conf like if we had only one config source.

fmt.Println(configuration.Port);

using Viper

go get github.com/spf13/viper

On your code you will need to declare your variables

var ( 
Port string
)

Viper will be able to read in a toml file, or in the env variables, so if you want to have a config file for your Development environment, but use the env vars, for Production, you can write a code like :

if os.Getenv("ENVIRONMENT") == "DEV" {        
viper.SetConfigName("config")
viper.SetConfigType("toml")
viper.AddConfigPath(filepath.Dir(dirname))
viper.ReadInConfig()
} else { viper.AutomaticEnv() }

And then to init your variable :

// To add a default value :
viper.SetDefault("APP_PORT", "8080")
//To get from the toml file or env var
Port = viper.GetString("APP_PORT")

Links

--

--