実務のプロダクションコードで、普段意識してなかった環境変数周りの処理を追ったときに前提知識が不足しすぎてて、とても苦労したのでまとめておく
osパッケージ利用
sample.go
package main
import (
"fmt"
"os"
)
func main() {
// 環境変数のセット
os.Setenv("APP_ENV", "prod")
// 環境変数の取得
appEnv := os.Getenv("APP_ENV")
fmt.Printf("appEnv: %v\n", appEnv)
}
envconfigパッケージ利用
「環境変数名を列挙した構造体を渡すことで、各フィールドに環境変数を一気に読み込む」
機能を提供してくれるパッケージ。2024/11/12時点で、Star5.1kと人気がある(ただし最終コミットは2年前になっている)。
READMEに記述されている内容や、実際の挙動を確認した結果から察するに、以下の縛りで利用することを想定している模様。
- 環境変数名: 大文字スネークケース
- 環境変数値を保存する構造体のフィールド名:
- パスカルケース(アッパーキャメルケース)
- 環境変数が複数単語からなる場合:
split_words:"true"
タグを付与 (タグを付与しない場合、例えばXXX_YYYという環境変数の場合、フィールド名をXxxYyyにしたとしても、環境変数XXXYYYを探すため読み取れない) - 環境変数に数値がまざる場合:
envconfig:"<環境変数名(小文字スネークケース)>"
タグを付与 (タグを付与しない場合、例えばXXX_YYY_1という環境変数の場合、フィールドを XxxYyysplit_words:"true
にしたとしても、環境変数XXX_YYY1を探すため読み取れない)
また、環境変数値を保存する構造体には、想定する環境変数自体が見つからなかった場合に、デフォルト値をセットするdefault
、エラーにするrequired
といったタグが指定できる。
sample.go
package main
import (
"fmt"
"log"
"os"
"github.com/kelseyhightower/envconfig"
)
func main() {
// 環境変数をセット
os.Setenv("APP_ENV", "prod")
os.Setenv("APP_SERVER_NAME_1", "prod_server_1")
// 環境変数値を保存する構造体
type environmentalVariable struct {
AppEnv string `split_words:"true" required:"true"` // 環境変数 APP_ENV に対応
AppServerName1 string `envconfig:"app_server_name_1" default:"test_server_1"` // 環境変数 APP_SERVER_NAME_1 に対応
}
var envVar environmentalVariable
// envconfigを使った環境変数の取得
if err := envconfig.Process("", &envVar); err != nil {
log.Fatalf("envconfig.Process() failed. (err:%v)", err)
}
fmt.Printf("envVar: %+v\n", envVar)
}
envパッケージ利用
こちらも envconfig とよく似たもので、「環境変数名を列挙した構造体を渡すことで、各フィールドに環境変数を一気に読み込む」機能を提供してくれるパッケージ。2024/11/12 時点で Star4.9kと人気がある。最終コミットも3週間前とメンテは続いている模様。