Open5
Goアプリの設定に.envファイルを使う提案
direnvのコマンドに「dotenv」というのがあります。
direnvのインストールは各自ググってもらうとして、
.envrc
dotenv local.env
dotenvの引数を省略すると「.env」ファイルを読み込みます。
local.env
PORT=/dev/ttyS0
LOG_DIR="/opt/log"
以上のファイルをプロジェクトフォルダに置いておき、
「direnv allow」することでexportedな環境変数がセットされます。
Goで環境変数をもとにしたConfigを構築する。
import "github.com/caarlos0/env/v6"
type Config struct {
Port string `env:"PORT, required"`
LogDir string `env:"LOG_DIR" envDefault:"/opt/log"`
}
func main() {
cfg := Config{}
if err := env.Parse(&cfg); err != nil {
log.Fatal(err)
}
// cfgを参照するコード
}
- 必須なフィールドには「,required」を付け足しておくとその環境変数がない場合はエラーになります。
- デフォルト値を指定するときはフィールドタグに「envDefault:"..."」を書きます。
実環境でどうするか?
一般シェル環境では以下のコマンドで環境変数をセットできる。
set -a; source production.env; set +a
docker runするときには以下のオプションで指定できます。
docker run --env-file=production.env ...
docker-composeでは以下のように指定できる。
docker-compose.yml
server:
env_file:
- production.env
systemd用のUnitファイルにも「EnvironmentFile=」で指定できます
server.service
[Unit]
Requires=network.service
[Service]
EnvironmentFile=/opt/server/production.env
...
もちろん、それぞれの方法は複数の「*.env」ファイルを読むこともできる。
この方法の特徴は
- docker、direnv、systemdで標準でサポートしているという点に加え、shellコマンドでも利用可能という汎用性
- サーバーアプリケーションのオプションの取り扱いが環境変数を見るだけというシンプルな実装で済む
- 一般のCLIほど引数の検証を行わないので変数名の記述には注意が必要です
以下のコードでenvファイルを環境変数に読み込める。
import "github.com/joho/godotenv"
func init() {
if err := godotenv.Load(".env"); err != nil {
log.Fatal(err)
}
}