Configuring Golang Applications Using Environment Variables

Marvin Blum
Emvi
Published in
2 min readNov 2, 2019

We found that using environment variables is one of the easiest and flexible methods for configuring Golang applications. They can be used everywhere in your application and configured on the terminal, in a shell script, using tools like Docker or Kubernetes and set or changed inside the application. Here is a simple example on how you could use them:

package mainimport (
"log"
"net/http"
"os"
)
func main() {
dir := os.Getenv("SERVER_DIR")
host := os.Getenv("SERVER_HOST")
// defaults
if dir == "" {
dir = "/www/"
}
if host == "" {
host = "localhost:8080"
}
http.Handle("/", http.FileServer(http.Dir(dir)))
log.Fatal(http.ListenAndServe(host, nil))
}

In this example we spin up a simple static HTTP file server. Two configuration variables are used, dir and host. Both are read from environment variables and set to some default value if not present. To configure and start the server we create a shell script (start.sh for example):

export SERVER_DIR=/www/mywebsite/
export SERVER_HOST=0.0.0.0:80
go run main.go

And spin it up by running ./start.sh .

Easy right? Well, as soon as we have a lot of these variables spread across our application, we probably lose track of what’s configured where and how. For that reason we use a name pattern or prefix and document all variables and possible values in the README at Emvi. That way it’s easy to find configuration variables inside our applications (by text search for example) and know the possible values.

If you use a configuration variable quite often you should “cache” its value in memory instead of reading it everytime you need it. Here is an example of what not to do:

for whatever := aLotOfObjects {
if whatever.Name == os.Getenv(“WHATEVER_NAME_SHOULD_NOT_BE”) {
whatever.Name = “You don’t need to know that”
}
}

In this example, we iterate over a slice and check a member of each struct against an environment variable and change its name based on the result. Reading an environment variable through os.Getenv is a very slow process. So instead of reading it from the environment everytime, you should store its value for later use. This can either be done by reading it into a variable ahead of the for loop or in the init.go file of the package using the configuration variable:

var (
whateverNameShouldBe = ""
)
func init() {
whateverNameShouldBe = os.Getenv("WHATEVER_NAME_SHOULD_BE")
}

And now we can just use whateverNameShouldBe inside the for loop. Setting it inside the init.go file means you will not be able to change the configuration on the fly. So if you need to actively change it while your application is running, go for the first method.

If you like this article please leave a 👏 and follow us for future articles.

--

--

Marvin Blum
Emvi
Editor for

Software Engineer, Open Source Enthusiast, Co-Founder of Pirsch and Emvi.