Handling Environment Variables in Go Applications
In Go, you can use environment variables to configure your application without hardcoding values. This allows configuration settings to be separated from the code and to be easily modified without changing the application itself. The standard library os
package provides a simple and effective way to handle environment variables.
Setting Environment Variables
Environment variables can be set in different ways depending on your operating system and context:
Linux/macOS:
export APP_ENV=production
export DB_HOST=localhost
Windows:
setx APP_ENV production
setx DB_HOST localhost
Within a Docker container:
You can also set environment variables in a Dockerfile or docker-compose.yml
file.
Reading Environment Variables
The os
package provides functions like os.Getenv
, os.Setenv
, and os.LookupEnv
to interact with environment variables.
-
os.Getenv: This function retrieves the value of the specified environment variable. If the variable is not set, it returns an empty string.
package main import ( "fmt" "os" ) func main() { appEnv := os.Getenv("APP_ENV") dbHost := os.Getenv("DB_HOST") fmt.Printf("APP_ENV: %s\n", appEnv) // Output: APP_ENV: production fmt.Printf("DB_HOST: %s\n", dbHost) // Output: DB_HOST: localhost }
-
os.Setenv: This function sets the value of an environment variable.
package main import ( "fmt" "os" ) func main() { // Set environment variable err := os.Setenv("API_KEY", "your_api_key_here") if err != nil { fmt.Println("Error setting environment variable:", err) } // Retrieve and print environment variable apiKey := os.Getenv("API_KEY") fmt.Printf("API_KEY: %s\n", apiKey) // Output: API_KEY: your_api_key_here }
-
os.LookupEnv: This function returns the value of the specified environment variable and a boolean indicating whether the variable is set.
package main import ( "fmt" "os" ) func main() { dbHost, ok := os.LookupEnv("DB_HOST") if ok { fmt.Printf("DB_HOST: %s\n", dbHost) // Output: DB_HOST: localhost } else { fmt.Println("DB_HOST is not set") } }
Handling Default Values
Since os.Getenv
returns an empty string if the environment variable is not set, you may want to handle default values:
package main
import (
"fmt"
"os"
)
func getEnv(key, defaultValue string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return defaultValue
}
func main() {
appEnv := getEnv("APP_ENV", "development")
dbHost := getEnv("DB_HOST", "127.0.0.1")
fmt.Printf("APP_ENV: %s\n", appEnv) // Output: APP_ENV: production (if set) or default: development
fmt.Printf("DB_HOST: %s\n", dbHost) // Output: DB_HOST: localhost (if set) or default: 127.0.0.1
}
Loading Environment Variables from a File
You can use third-party packages like godotenv
to load environment variables from a .env
file. This is particularly useful for development and testing.
-
Install Godotenv:
go get github.com/joho/godotenv
-
Create a
.env
File:APP_ENV=production DB_HOST=localhost
-
Load the
.env
File in Your Application:package main import ( "fmt" "log" "os" "github.com/joho/godotenv" ) func main() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } appEnv := os.Getenv("APP_ENV") dbHost := os.Getenv("DB_HOST") fmt.Printf("APP_ENV: %s\n", appEnv) // Output: APP_ENV: production fmt.Printf("DB_HOST: %s\n", dbHost) // Output: DB_HOST: localhost }
Practical Example
A more comprehensive example that includes setting and getting environment variables along with using a utility function for default values:
package main
import (
"fmt"
"log"
"os"
"github.com/joho/godotenv"
)
func getEnv(key, defaultValue string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return defaultValue
}
func main() {
// Load .env file
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
// Set an environment variable
os.Setenv("API_KEY", "your_api_key_here")
// Get environment variables
appEnv := getEnv("APP_ENV", "development")
dbHost := getEnv("DB_HOST", "127.0.0.1")
apiKey := os.Getenv("API_KEY")
// Output the results
fmt.Printf("APP_ENV: %s\n", appEnv)
fmt.Printf("DB_HOST: %s\n", dbHost)
fmt.Printf("API_KEY: %s\n", apiKey)
}
Conclusion
Using environment variables in Go is straightforward with the os
package. For development and testing, tools like godotenv
can simplify the process of loading environment variables from files. By handling default values and using utility functions, you can make your Go applications more flexible and configurable.