はじめに
Go言語でサーバーアプリケーションを作成しています。
このアプリでは、暗号化に使うシークレットキーやら、データベースのユーザー、パスワードといった設定値を簡単に扱えるライブラリとして、viperを使っています。
viperを使ってconfig.yamlといった外部ファイルを読み込む方法については、下記の参考資料等々よく見ますが、config.yamlの他に.envファイルも扱いたいと思いました。
viperにおける、.envの扱いについては、調べてもあまり出てこなかったので備忘録としてまとめました。
前提
Versionについて
Goのバージョン、viperのバージョンは以下のとおりです。
- Go 1.17.6
- github.com/spf13/viper v1.10.1
フォルダ構成
今回説明するフォルダ構成は以下の通りです。
.
├── config
│ ├── config.yaml
│ └── config.go
├── .env
└── main.go
viperを用いて、config.yamlを読み取る方法については、
に詳しく記載されていますので参照していただければと思います。
環境変数の定義
.envファイルに環境変数を定義する。
例:
VERSION=1.0.0
DBUSER=postgres
DBPASSWORD=postgres
Goのviperの設定
デフォルトでは、viperでconfig.yamlを読み取っているが、
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath("config/")
//↑がconfig.yamlの設定
//↓が環境変数の設定 ※これを書いただけでは、.envは読み取られない
viper.AutomaticEnv() //環境変数の読み込み
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) //プリフィックスの設定
とすることで、環境変数で設定値を上書きできる。
環境変数はすべて大文字で問題ない。viperがよしなにやってくれる。
ただし、注意点として、go runやgo buildしたあとの実行ファイルを実行するときに、自動で.envファイルを読み取ってくれるわけではないので、後述するやり方で.envファイルの値をgoの中に反映させる。
(環境変数の反映)
go runをする際に、
VERSION=1.0.0 DBUSER=postgres DBPASSWORD=postres go run main.go
といった形にすれば環境変数が反映される。
.envファイルの環境変数の反映
go buildで実行ファイル(./bin/main)を作成したあと、
#!/bin/ash
export $(cat .env | grep -v ^# | xargs); ./bin/main
とすることで、.envのファイルを表示させて実行してくれる。
#!/bin/ash
はalpine用なので、適宜変えること。
を参考にさせていただきました。
補足
dockerを使っているのであれば、dockerfileの中で.envの設定をしてもいいとは思うが、開発環境がローカル(dockerを使わない)ので、.envはこの形で反映させるようにしている。
参考資料
おわりに
間違い、あるいはご意見等あればコメントいただければ幸いです。