🔐

暗号化に対応した次世代dotenvツールdotenvxを使う

2024/07/01に公開3

広く使われている環境変数をファイルで管理するdotenvの次世代版 dotenvxのv1.0がリリース されました(2024/06/30時点での最新はv1.2)。作者はdotenvを作ったMotさん。つまり正式な次世代版ということです。dotenvxはdotenvの弱点を克服したものになっています。

dotenvとdotenvxの大きな違い

dotenv dotenvx
動作環境 各言語の専用ライブラリが必要 依存せずdotenvx単体でOK
複数の環境 サポートなし ファイル指定可能(併用も可能)
暗号化 サポートなし サポート

特に一番最後の暗号化サポートは非常に嬉しい進化です。dotenv単体で環境変数を運用すると、秘匿情報が含まれたdotenvファイル自体の管理に困ることや、デプロイする際にどうやって環境変数を提供するかが課題になることがありました。

現代ではクラウドプラットフォーム上にシークレットマネージャーのような仕組みが用意され、そこで中央管理するというのが一般的になっているかと思います。ただ、それだと変数のバージョン管理やレビューの仕組みを別途用意しないといけなかったりと完全ではありません(個人的主観です)。

dotenvファイル自体が暗号化され、Gitでバージョン管理でき、そのままデプロイして環境変数を適用できたら運用の手間が一気に減ります。

dotenvxを使う

インストール

インストール方法は好きな方法で行ってください。

# npm
npm install @dotenvx/dotenvx --save

# macOS
brew install dotenvx/brew/dotenvx

# curl
curl -sfS https://dotenvx.sh | sh

まず普通に使ってみる

.env ファイルにサンプルの環境変数を定義します。

echo "HELLO=World" > .env

そしてインストールした dotenvx コマンドをつかって環境変数を出力してみます。

dotenvx run --quiet -- sh -c 'echo Hello $HELLO'
#=> Hello World

このコマンドで使用しているハイフン2つ -- が重要なポイントです。これはコマンドのオプションと引数の区切り線みたいなものです。dotenvxコマンドのオプション run --quiest と、引数 sh -c 'echo Hello $HELLO' に分離しています。つまり、dotenvxでは、引数で指定されたコマンドを変わりに実行することで、どんなアプリケーションやCLIツールにも対応しているということになります。

  • dotenvx run -- <環境変数を適用したいコマンド>

従来のdotenvでは各言語ごとに用意されたライブラリをimportして環境変数を読み込んでいましたが、dotenvxではdotenvxコマンドで環境変数を適用して、代理でアプリケーションなどを実行するという仕組みです。

本番環境用のファイルを作る

続いて複数の環境に対応してみます。これは非常にシンプルでdotenvファイルを -f オプションで指定できるだけです。

echo "HELLO=Production World" > .env.production
dotenvx run -f .env.production --quiet -- sh -c 'echo Hello $HELLO'
#=> Hello ProductionWorld

まぁ、これは従来のdotenvでも似たようなことはできましたし、dotenv周辺ツールでもサポートされていたので、ただ単純に使いやすくなったという印象です。

複数dotenvファイルのマージ・上書き

-f オプションで複数のdotenvファイルを指定することができます。もし同じキーが衝突していた場合、デフォルトでは先に指定したdotenvファイルが優先されます。 --overload オプションを追加すると逆になり、あとに指定したdotenvファイルが優先されます。

# overload があるので .env.production の HELLO が出力される
dotenvx run \
  -f .env \
  -f .env.production \
  --overload \
  -- sh -c 'echo Hello $HELLO'

また、衝突しないキーの場合はそのままマージされます。これは意外と便利で、どの環境でも値が変わらないキーは、一つのdotenvファイルに定義しておくことで共通化することができます。

暗号化を試してみる

暗号化の方法は大きく2つあります。

  • dotenvファイル自体を暗号化する
  • 環境変通を追加するときに暗号化する

dotenvファイル自体を暗号化する

シンプルなのはdotenvファイル自体をまるごと暗号化する方法です。

dotenvx encrypt
dotenvx encrypt -f .env.production

この dotenvx encrypt を実行すると .env ファイル自体が以下のように暗号化されます。

#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
#/            public-key encryption for .env files          /
#/       [how it works](https://dotenvx.com/encryption)     /
#/----------------------------------------------------------/
DOTENV_PUBLIC_KEY="xxxxxx"

# .env
HELLO="encrypted:BMEJdT+usAu6xxxxxxxx="
FOO="encrypted:BJDNyxxxxxx=="

そして .env.keys という複合するために必要なマスターキーファイルも作成されます。

#/------------------!DOTENV_PRIVATE_KEYS!-------------------/
#/ private decryption keys. DO NOT commit to source control /
#/     [how it works](https://dotenvx.com/encryption)       /
#/----------------------------------------------------------/

# .env
DOTENV_PRIVATE_KEY="xxxxxx"

この .env.keys は絶対にGitで管理してはなりませんし、このファイルが流出してしまうと誰でも復号できてしまいます。取り扱いには注意してください。.gitignore に以下を追加しておくことをオススメします。

.env.keys

環境変通を追加するときに暗号化する

もう一つのやり方は環境変通を追加するときに暗号化する方法です。

dotenvx set HELLO World

これも上記と同様の結果になるのですが、違いは「特定の環境変数を平文のままにできる」ことです。同じdotenvファイルで管理するけど秘匿情報ではなく公開情報なので暗号化せずに管理したい…というようなニーズに答えられます。

APP_NAME="Super App"
SECRET_KEY="xxxxx"

APP_NAME は環境によって変わるので環境変数にするが、平文でも問題がない、むしろ平文のほうが確認がすぐできるのでそうしたい、というときに dotenvx set コマンドでの運用をすると良いでしょう。ただ、途中で dotenvx encrypt を実行すると全部暗号化されてしまうので、気をつけないといけませんね…。


という感じで、環境変数管理ツールのdotenvが大きく進化し、とても使いやすくなったのでぜひ皆さんでも試してみてください。ちなみに、復号化する dotenvx decrypt は現在はまだありませんが将来的にサポートされるようです。たぶん。

ムーザルちゃんねる

Discussion

ryoryoryoryo

従来のdotenvでは各言語ごとに用意されたライブラリをimportして環境変数を読み込んでいましたが、dotenvxではdotenvxコマンドで環境変数を適用して、代理でアプリケーションなどを実行するという仕組みです。

dotenvも "--"で区切って実行できますよね?

dotenv -e .env.local -- next dev
zaruzaru

確かにできました。確認不足でした、すいません。

ということは、dotenvxが言ってるRun Anywhereというのはどちらかというとimportして使う用途を捨てて -- で一貫した使用方法にした…ということなのかな。

ryoryoryoryo

dotenv以外の環境変数向けパッケージに対してのことで、dotenvと比較した利点というわけではないんでしょうかねー