SoFunction
Updated on 2025-03-03

Summary of three ways to obtain Golang environment variables

Environment variables are the best way to configure software parameters and can define the system level, such as development, testing, and generation stages. The configuration parameters mainly include database configuration, third-party url, etc. Therefore, environment variables are crucial for the development and deployment of applications.

Environment variables and configuration files

It is relatively easy to read variables from files in shell programming. You only need to source the configuration file that includes the environment variables to access all of these variables. golang must rely on some modules to read variables from files. The content of this article includes:

  • How to declare environment variables through files
  • How to read environment variables from a file
  • How to set the default value when the variable is undefined or empty
  • If you read environment variables from the system
  • How to check if environment variables are defined or not empty

When deploying applications (cloud, Kubernetes, or Docker) in containerized to test and production environments, the environment variable role is very important, and it can easily override the default configuration. There are three common methods for golang to access environment variables:

  • Viper Package
  • godotenv package
  • os package

We create a configuration file in the sample project to set the default values ​​for predetermined environment variables.

There are some rules to follow when creating an environment variable configuration file, otherwise golang may not recognize the variable value:

All variables must be declared in separate lines
Case-sensitive variable names should be named in capital, and words should be separated by underscores. Example: DB_HOST
The variable value is divided by an equal sign after the variable name. For example: DB_HOST=localhost
Variable values ​​do not use double quotes, for example: DB_HOST="localhost"
Comments should not be on the same line as variables, for example:

# depends with database ports mysql,mongodb,postgres etc
DB_PORT=5432

For example, file:

# sample 
# environment can be test,production,testing
APP_ENV=development
# username
DB_USER=postgres
# secure password
DB_PASS=pass
# app version not set
APP_VERSION=
#listening to any address
SERVER_ADDRESS=0.0.0.0:8080
# host value
DB_HOST=localhost
#depends with database mysql,mongodb,postgres etc
DB_PORT=5432

Read environment variables from configuration files using Viper package

This is an environment variable management toolkit that allows you to read variable values ​​from environment variables or configuration files. Install the package through the following command:

go get /spf13/viper

Example 1

First, define the structure to save environment variables in the configuration file globally.

type Config struct {
	AppEnv        string `mapstructure:"APP_ENV"`
	DBUser        string `mapstructure:"DB_USER"`
	DBPass        string `mapstructure:"DB_PASS"`
	DBHost        string `mapstructure:"DB_HOST"`
	DBPort        string `mapstructure:"DB_PORT"`
	DBDriver      string `mapstructure:"DB_DRIVER"`
	AppVersion    string `mapstructure:"APP_VERSION"`
	ServerAddress string `mapstructure:"SERVER_ADDRESS"`
}

The following defines the function loading configuration file:

func LoadConfig(path string) (config Config, err error) {
	// Read file path
	(path)

	// set config file and path
	("app")
	("env")

	// watching changes in 
	()

	// reading the config file
	err = ()
	if err != nil {
		return
	}

	err = (&config)
	return
}

The complete code is as follows:

package main

import (
	"fmt"
	"log"

	"/spf13/viper"
)

// Config stores all configuration of the application.
// The values are read by viper from a config file or environment variable.
type Config struct {
	AppEnv        string `mapstructure:"APP_ENV"`
	DBUser        string `mapstructure:"DB_USER"`
	DBPass        string `mapstructure:"DB_PASS"`
	DBHost        string `mapstructure:"DB_HOST"`
	DBPort        string `mapstructure:"DB_PORT"`
	DBDriver      string `mapstructure:"DB_DRIVER"`
	AppVersion    string `mapstructure:"APP_VERSION"`
	ServerAddress string `mapstructure:"SERVER_ADDRESS"`
}

// LoadConfig reads configuration from file or environment variables.
func LoadConfig(path string) (config Config, err error) {
	// Read file path
	(path)
	// set config file and path
	("app")
	("env")
	// watching changes in 
	()
	// reading the config file
	err = ()
	if err != nil {
		return
	}

	err = (&config)
	return
}

func main() {
	// load  file data to struct
	config, err := LoadConfig(".")

	// handle errors
	if err != nil {
		("can't load environment : %v", err)
	}

	(" -----%s----\n", "Reading Environment variables Using Viper package")
	(" %s = %v \n", "Application_Environment", )
	// not defined
	(" %s = %s \n", "DB_DRIVE", dbDrive)
	(" %s = %s \n", "Server_Listening_Address", )
	(" %s = %s \n", "Database_User_Name", )
	(" %s = %s \n", "Database_User_Password", )

}

Output result:

$ go run 
 ------Reading Environment variables Using Viper package----------
 Application_Environment = development 
 Server_Listening_Address = 0.0.0.0:8080 
 Database_User_Name = postgres 
 Database_User_Password = pass

Example 2

Sometimes the environment variable may not be set, so the code may error. We can use the following method to define the default value:

:

The following example code defines a function, which returns the default value if the variable is not empty or undefined:

package main

import (
	"fmt"

	"/spf13/viper"
)

//Function to read an environment or return a default value
func getEnvValue(key string, defaultValue string) string {

	// Get file path
	("")
	//read configs and handle errors
	err := ()
	if err != nil {
		(err)
	}
	value := (key)
	if value != "" {
		return value
	}
	return defaultValue
}
func main() {
	// reading environments variable using the viper
	appEnv := getEnvValue("APP_ENV", "defaultEnvtesting")
	// not set in our 
	appVersion := getEnvValue("APP_VERSION", "1")
	dbPass := getEnvValue("DB_PASS", "1234")
	dbUser := getEnvValue("DB_USER", "goLinux_DB")
	serverAddress := getEnvValue("SERVER_ADDRESS", "127.0.0.1:8080")

	(" ------%s-----\n", "Reading Environment variables Using Viper package")
	(" %s = %s \n", "Application_Environment", appEnv)
	(" %s = %s \n", "Application_Version", appVersion)
	(" %s = %s \n", "Server_Listening_Address", serverAddress)
	(" %s = %s \n", "Database_User_Name", dbUser)
	(" %s = %s \n", "Database_User_Password", dbPass)
}

Output result:

$ go run 
 ---Reading Environment variables Using Viper package--------
 Application_Environment = development 
 Application_Version = 1 
 Server_Listening_Address = 0.0.0.0:8080 
 Database_User_Name = postgres 
 Database_User_Password = pass

Read environment variables from configuration files using GoDotEnv package

The GoDotEnv package function is similar to the viper package, but uses the() function to load the file, which receives the file name as input, returning the value in the application context. Implement the following command to install the package:

 go get /joho/godotenv

The Load method can pass in the file name, for example:("")
Sometimes the .env file is located in the project root directory, and it can be loaded directly without passing in parameters:(")godotenv also supports loading multiple configuration files at once:

_ = ("", "k8s_app.env")

It also supports YAML files as input:

// 
APP_ENV: Development
SERVER_ADDRESS: 0.0.0.0:8080

Here is a complete example:

// 
package main

import (
	"fmt"
	"log"
	"os"

	"/joho/godotenv"
)

// Function to read an environment or return a default value
func getEnvValue(key string, defaultValue string) string {
	if value, ok := (key); ok && value != "" {
		return value
	}
	return defaultValue
}

func main() {
	// load  file
	err := ("")
	//handle errors
	if err != nil {
		("can't load environment : %v", err)
	}

	// reading environments variable from the app context
	appEnv := getEnvValue("APP_ENV", "defaultEnvtesting")

	// not defined in our 
	appVersion := getEnvValue("APP_VERSION", "1")
	dbPass := getEnvValue("DB_PASS", "1234")

	// DB_NAME not defined in app env
	dbName := getEnvValue("DB_NAME", "goLinux_DB")
	dbUser := getEnvValue("DB_USER", "goLinux_DB")
	serverAddress := getEnvValue("SERVER_ADDRESS", "127.0.0.1:8080")

	(" ----%s---\n", "Reading Environment variables Using GoDotEnv package ")
	(" %s = %s \n", "Application_Environment", appEnv)
	(" %s = %s \n", "Application_Version", appVersion)
	(" %s = %s \n", "Server_Listening_Address", serverAddress)
	(" %s = %s \n", "Database_User_Name", dbUser)
	(" %s = %s \n", "Database_User_Password", dbPass)
	(" %s = %s \n", "Database_Name", dbName)

}

Output result:

$ go run    
              
 -----Reading Environment variables Using GoDotEnv package-----
 Application_Environment = development 
 Application_Version = 1 
 Server_Listening_Address = 0.0.0.0:8080 
 Database_User_Name = postgres 
 Database_User_Password = pass 
 Database_Name = goLinux_DB

Read environment variables from configuration files using os package

Set environment variables using ()

(key,value) Receives two input parameters, one is key and the other is the environment variable value.
The syntax is as follows:

err := (key, value)
if err != nil {
	("error will setting the environment value: %s", err)
}

For example, set COLOUR=BLUE:

err := (COLOUR, BLUE)
if err != nil {
	("error will setting the environment value: %s", err)
}

Read system environment variables using ()

Receive key, for example, the following code obtains the value of the environment variable PATH:

// 
package main

import (
	"fmt"
	"os"
)

func main() {
	("supported paths in my shell: ", ("PATH"))
}

Read system environment variables using ()

The disadvantage of () is that there is no error to return the key. For additional checks that need to be added, you need to use(), which includes a Boolean variable to indicate whether the key exists. For example:

// 
package main

import (
	"fmt"
	"log"
	"os"
)

func main() {

	path, ok := ("PATH123")
	if !ok {
		(path + " variable is not defined")
	}
	(path)
}

Use() to unset environment variables

() Delete or undefine any system environment variables. Note that this will only temporarily cancel the variable settings of the current terminal. For example:

// 
package main

import (
	"fmt"
	"os"
)

func main() {
	
	("MYUSER", "TestUser")
	// Before unsetting the variable
	out, _ := ("MYUSER")
	("BEFORE: " + out)

	// Unset the variable
	("MYUSER")

	// After unsetting the variable
	out, _ = ("MYUSER")
	("AFTER: " + out)
}

Summarize

This is the end of this article about the three ways to obtain Golang environment variables. For more relevant content on Golang to obtain environment variables, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!