masalibの日記

システム開発、運用と猫の写真ブログです

golang の入門 godotenv(環境変数)

Golangのgodotenvとは

godotenvは、Go用のオープンソースライブラリで、.envファイルから環境変数をロードするものです。これは、RubyのdotenvプロジェクトのGo言語版です。

.envファイルは、機密情報(APIキー、パスワードなど)を含む環境変数を格納するために使用されます。これらの変数は、アプリケーションコードから直接アクセスできるため、ソースコードにハードコーディングすることは避けたいものです。godotenvを使用すると、.envファイルからこれらの変数を安全にロードし、アプリケーションで使用することができます。

godotenvの主な利点は次のとおりです。

  • 機密情報の保護: .envファイルは、通常、ソースコード管理システムから除外されるため、機密情報が公開されるリスクを軽減できます。
  • 環境設定の簡素化: さまざまな環境(開発、本番、テストなど)で異なる設定を使用する必要がある場合、godotenvを使用すると、それぞれの環境に.envファイルを作成するだけで済みます。
  • コードの可読性の向上: 環境変数をコードに直接ハードコーディングする代わりに、godotenvを使用すると、コードがより読みやすく、保守しやすくなります。

godotenvの基本的な使い方

インストール

  1. godotenvをプロジェクトに追加するには、以下のコマンドを実行します
go get github.com/joho/godotenv
  1. .envファイルの作成

.envファイルには、以下の形式で環境変数を定義します。

KEY=VALUE

プロジェクトのルートディレクトリに.envファイルを作成します。このファイルには、環境変数をキーと値のペアで記述します:

DB_HOST=localhost
DB_PORT=5432
DB_USER=root
DB_PASS=password
  1. Goコードでの使用
package main

import (
    "fmt"
    "log"
    "github.com/joho/godotenv"
    "os"
)

func main() {
    // .envファイルを読み込む
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

    // 環境変数を取得
    dbHost := os.Getenv("DB_HOST")
    dbPort := os.Getenv("DB_PORT")
    dbUser := os.Getenv("DB_USER")
    dbPass := os.Getenv("DB_PASS")

    fmt.Printf("DB_HOST: %s\n", dbHost)
    fmt.Printf("DB_PORT: %s\n", dbPort)
    fmt.Printf("DB_USER: %s\n", dbUser)
    fmt.Printf("DB_PASS: %s\n", dbPass)
}

その他の使い方について

パスを指定する方法

ロード関数: godotenv.Load() はデフォルトで現在のディレクトリにある.envファイルをロードします。特定のファイルを指定することも可能です

godotenv.Load("path/to/your/.env")

複数ファイルのロード

複数の.envファイルを順に読み込むこともできます

godotenv.Load(".env", ".env.local")

補足

godotenv.Load() 関数を使用して複数の .env ファイルを指定した場合、それらのファイルは順に読み込まれます。つまり、最初の .env ファイルを読み込んだ後に次のファイルを読み込むため、複数のファイルがすべて読み込まれます。各ファイルに同じ環境変数が定義されている場合、後に読み込まれたファイルの値で上書きされます。

具体的な例で説明します:

以下のように2つの .env ファイルがあるとします。

.env

DB_HOST=localhost
DB_PORT=5432
DB_USER=root
DB_PASS=password

.env.local

DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=admin

この場合、以下のようにコードで読み込むとします:

package main

import (
    "fmt"
    "log"
    "github.com/joho/godotenv"
    "os"
)

func main() {
    // 複数の.envファイルを読み込む
    err := godotenv.Load(".env", ".env.local")
    if err != nil {
        log.Fatal("Error loading .env files")
    }

    // 環境変数を取得
    dbHost := os.Getenv("DB_HOST")
    dbPort := os.Getenv("DB_PORT")
    dbUser := os.Getenv("DB_USER")
    dbPass := os.Getenv("DB_PASS")

    fmt.Printf("DB_HOST: %s\n", dbHost)
    fmt.Printf("DB_PORT: %s\n", dbPort)
    fmt.Printf("DB_USER: %s\n", dbUser)
    fmt.Printf("DB_PASS: %s\n", dbPass)
}

このコードを実行すると、次のような出力が得られます:

DB_HOST: 127.0.0.1
DB_PORT: 3306
DB_USER: admin
DB_PASS: password

このように、最初に .env ファイルを読み込んだ後に .env.local ファイルを読み込むため、.env.local ファイルに定義されている DB_HOST, DB_PORT, DB_USER の値で上書きされますが、.env.local に定義されていない DB_PASS の値は .env の値が使用されます。

複数の .env ファイルを順に読み込み、後に読み込まれたファイルの値で前の値が上書きされることになります。

マップにロード: 環境変数をマップとしてロード

godotenv.Read() 関数を使用して .env ファイルの内容をマップとして読み込んだ場合、そのマップを使用して環境変数の値にアクセスできます。

まず、プロジェクトのルートディレクトリに .env ファイルを作成します:

.env

DB_HOST=localhost
DB_PORT=5432
DB_USER=root
DB_PASS=password

次に、Goコードで godotenv.Read() を使用してこの .env ファイルをマップとして読み込みます:

package main

import (
    "fmt"
    "log"
    "github.com/joho/godotenv"
)

func main() {
    // .envファイルをマップとして読み込む
    envMap, err := godotenv.Read()

    if err != nil {
        log.Fatal("Error reading .env file")
    }

    // マップから環境変数を取得
    dbHost := envMap["DB_HOST"]
    dbPort := envMap["DB_PORT"]
    dbUser := envMap["DB_USER"]
    dbPass := envMap["DB_PASS"]

    fmt.Printf("DB_HOST: %s\n", dbHost)
    fmt.Printf("DB_PORT: %s\n", dbPort)
    fmt.Printf("DB_USER: %s\n", dbUser)
    fmt.Printf("DB_PASS: %s\n", dbPass)
}

このコードを実行すると、次のように出力されます:

DB_HOST: localhost
DB_PORT: 5432
DB_USER: root
DB_PASS: password

マップの使い方のポイント

  • godotenv.Read() 関数は .env ファイルを読み込み、その内容をキーと値のペアとして持つマップ(map[string]string)を返します。
  • このマップからは、通常のマップ操作と同じように値を取得できます。

例えば、マップに含まれるすべての環境変数を出力する場合、次のようにすることができます:

package main

import (
    "fmt"
    "log"
    "github.com/joho/godotenv"
)

func main() {
    // .envファイルをマップとして読み込む
    envMap, err := godotenv.Read()
    if err != nil {
        log.Fatal("Error reading .env file")
    }

    // マップの内容をすべて出力
    for key, value := range envMap {
        fmt.Printf("%s: %s\n", key, value)
    }
}

このコードを実行すると、.env ファイルに含まれるすべてのキーと値が出力されます。

エラーハンドリング

godotenv.Read() 関数はエラーを返す可能性があるため、必ずエラーチェックを行うようにしましょう。エラーが発生した場合は、適切なエラーメッセージをログに記録するか、必要に応じてアプリケーションを終了することが推奨されます。

参考URL

godotenv GitHubリポジトリ: https://github.com/joho/godotenv
godotenv GoDoc: https://github.com/joho/godotenv
godotenvの使い方をざっくりまとめる: https://zenn.dev/yukihaga/scraps/19b101e0faf857
12ファクターアプリ: https://12factor.net/
環境変数: https://en.wikipedia.org/wiki/Environment_variable