30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

Node.jsでの環境変数の使い方

同じソースコード、同じアプリケーションでも、デプロイによって設定が異なるものがある。
各種APIキーや、データベースの設定など。本番環境と開発環境では異なる設定を使うことが多い。
こういったものをハードコーディングするべきではない。

また、GitHubでコードを公開する場合、APIキーなどの機密情報を書くわけにはいかない。

そのような場合に使うのが、環境変数である。

環境変数の正確な定義は知らないが、コードの外から設定を行う変数、という感じだろうか。
これを利用することで、APIキー等をコードに書かずに済む。

process.env

Node.jsにおける環境変数は、process.envというオブジェクトに格納される。
このオブジェクトは最初から存在しており、予め、いくつかの環境変数が入っている。
コマンドラインで確認できる。

$ node
> process.env

いくつか表示されると思う。

アプリケーション毎にprocess.envの中身を追加して利用するのが、基本的な使い方である。

なお、自分で定義する環境変数は慣習として、NODE_***という形式で命名することが多い。

起動時に設定

ここから、具体的な使い方を見ていく。
まず、以下のようなコードを用意する。

// key.js
let key = process.env.NODE_KEY;
console.log(key);

環境変数NODE_KEYを利用している。
これを$ node key.jsで実行すると、undefinedが表示される。NODE_KEYについて定義していないので、当然である。

環境変数の定義方法はいくつかあるが、最も簡単なのは、起動時に設定する方法である。
以下のように、key.jsを実行する。

$ NODE_KEY=2 node key.js

すると、2と表示される。

環境変数が複数ある場合は、全て書く。

// $ NODE_KEY=2 NODE_NAME=tom node key.js

let key = process.env.NODE_KEY;
let name = process.env.NODE_NAME;

console.log(key);   // 2
console.log(name);  // tom

foreverによるデーモン化でも、同じように使える。

$ 環境変数の設定 forever start ファイル名

envify

起動時に環境変数を設定する方法は、browserifyでバンドルしたファイルでは使えない。

// env.js
const outer = require('./outer.js');

console.log(process.env.NODE_KEY);
console.log(outer.num);
// outer.js
const num = process.env.NODE_NUM;
module.exports.num = num;

この2つをバンドルしてenv-b.jsというファイルを作り、それを実行しても、上手くいかない。

$ browserify env.js -o env-b.js
$ NODE_KEY=hoge NODE_NUM=9 node env-b.js
undefined
undefined

バンドルしたファイルでも環境変数を使うには、envifyというnpmモジュールを使えばよい。
これを使って、ファイルの起動時ではなくビルド時に、環境変数を設定する。

$ npm install envify

以下のように使う。

$ 環境変数の設定 browserify 元ファイル -t envify > 作成するファイル
$ NODE_KEY=hoge NODE_NUM=9 browserify env.js -t envify > env-b.js
$ node env-b.js
hoge
9

dotenv

2018/7/14 追記
dotenvより利用しやすいdirenvについて書いた。
direnv を使った環境変数の管理 - 30歳からのプログラミング
追記終わり

これまでに説明した方法では、いちいち起動時やビルド時に環境変数を入力しないといけない。
サンプルのように簡単なケースならいいかもしれないが、実際にはもっと複雑で冗長になってしまうだろう。

それを防ぐために、予め入力しておいた環境変数を自動的に読み込ませる方法がある。
dotenvというnpmモジュールを使うことで、可能になる。

$ npm install dotenv

事前に.envというファイルをルートディレクトリに用意しておくと、そこに記述しておいた内容を環境変数として読み込むことが出来る。
コードにrequire('dotenv').config();と書くことで、読み込める。

// .env
NODE_KEY = hoge
NODE_NUM = 9
// env.js
require('dotenv').config();

const key = process.env.NODE_KEY;
const num = process.env.NODE_NUM;

console.log(key);
console.log(num);
$ node env.js
hoge
9

起動オプションを指定した場合は、そちらが優先される。

$ NODE_KEY=option node env.js
option
9

dotenvの注意点

dotenvを使用する方法には、問題点というか、注意点がある。
それは、.envファイルを.gitignoreするのを忘れてしまうと、GitHubにプッシュした際にリポジトリに登録されてしまい、環境変数の中身がネット上に公開されてしまうことである。

個人的に、これが一番悩ましい。

そんなミスをしなければいい、ということなのかもしれないが、人間の注意力に頼るのはエンジニアらしくないし、スマートではないと感じてしまう。

ただ、ざっと調べた限りでは、dotenvを利用したこの方法がよく使われているらしい。
細かい使い方には、いろいろと工夫の余地があるのだろうけど。

参考資料