3秒でわかる
OSやコンテナからプログラムへ値を渡す仕組み。接続先や秘密鍵をコードの外へ出し、開発と本番で同じコードのまま設定だけを切り替えられます。
もう少し詳しく
どういうものか
環境変数は、OS がプロセスへ受け渡す名前と値の組です。プログラムは起動時にこれを読み、接続先のURL、実行モード、APIキーなどを受け取ります。コードには変数名だけを書き、実際の値は動かす場所ごとに与えます。開発機と本番サーバーで同じコードのまま、接続先だけを切り替えられるのはこの仕組みのおかげです。
なぜ必要か
理由は 2 つあります。1 つは秘密の保護で、APIキーやデータベースのパスワードをソースへ直接書くと、リポジトリを見られる全員に知られ、git の履歴からは消すのも難しくなります。もう 1 つは環境ごとの差し替えで、本番とステージングで別のデータベースを見る必要があるとき、コードを分岐させると必ずどちらかで事故ります。値を外へ出しておけば、コードは 1 つで済みます。
具体例
# 端末で一時的に設定して実行する
export DATABASE_URL="mysql://user:pw@db.example.com/app"
node server.jsconst url = process.env.DATABASE_URL;
if (!url) {
console.error("DATABASE_URL が設定されていません");
process.exit(1);
}
const secret = process.env.JWT_SECRET ?? "dev-only-secret";起動直後に必須の変数を確認して止める書き方にしておくと、設定漏れが本番で発覚する事態を防げます。
つまずきやすいところ
.env ファイルを作ったところまでは正しく、それを git に載せてしまう事故が非常に多く起きます。.gitignore へ追加し、代わりに値を空にした .env.example を置きます。もうひとつは値の型で、環境変数は必ず文字列として渡ります。DEBUG=false を読んで条件に使うと、文字列の "false" は真と判定されるため、比較して真偽値に変換する処理が要ります。export を付けずに設定した変数は子プロセスへ引き継がれない点も、シェル経由で起動したときにつまずくところです。
似た用語との違い
| 手段 | 向いている用途 |
|---|---|
| 環境変数 | 環境ごとに変わる少数の設定と秘密情報 |
| 設定ファイル | 構造が複雑で、公開してよい設定 |
| シークレット管理サービス | 値の更新履歴と権限管理まで必要な秘密情報 |
覚え方
コードは公開してよい部分、環境変数は公開できない部分と環境ごとに変わる部分。この線引きで迷ったら、そのままリポジトリに載せられるかどうかを基準にします。