WSLで「direnv」を活用してプロジェクト単位で環境変数を管理しよう

2025年5月27日(火)
田中 智明
第13回の今回は「direnv」を活用して、WSL2上でプロジェクトごとに環境変数を柔軟かつ安全に管理する方法を解説します。

はじめに

近年、アプリケーションの実行環境として最も選択されているのはクラウドです。運用の簡素化やコスト効率など様々なメリットがありますが、クラウドを選択する理由の1つとして「スケーラビリティ」があります。スケーラビリティとは、環境やリソースを拡張できる能力を指します。柔軟に環境やリソースを追加できるのは、クラウド利用の最大のメリットと言えるでしょう。

クラウド利用を念頭に置いた設計思想を「クラウドネイティブ」と呼びます。クラウドネイティブなアプリケーションには、以下のような特徴があります:

  • Twelve-Factor App準拠
  • コンテナ化とオーケストレーション
  • マイクロサービスアーキテクチャ
  • クラウドの特徴を活かした設計

この中の1つ、Twelve-Factor Appには「設定を環境変数に格納する」と明示されています。

アプリケーションの設定は複数の環境(開発、ステージング、本番)で異なります。例えば、DBへの接続情報やホスト名など、これらの機密情報をアプリケーションと同じリポジトリで管理するわけにはいきません。つまり、環境ごとに設定ファイルを用意するより、環境変数から設定できる方がよりセキュアであると言えるでしょう。

このようなアプリケーションを開発するには、開発環境でも環境変数の管理が必要となります。特に、複数のプロジェクトを同時に扱う場合や複数の環境で作業する場合は、環境変数の切り替えが煩雑になりがちです。

このような課題を解決するツールとして「direnv」があります。

direnvとは

direnvは、ディレクトリごとに環境変数を自動的に設定・切り替えができるユーティリティです。これにより、プロジェクトや環境ごとの環境設定を簡単に管理できるようになります。

例えば、以下のようなシーンでdirenvは特に有用です:

  • 複数のKubernetesクラスターを管理する場合
  • 異なる環境の認証情報を扱う場合
  • プロジェクト固有の環境変数を設定する場合

この記事では、このdirenvを活用しながら、よりスムーズな開発体験を実現する方法を紹介します。

なぜdirenvが必要なのか

現代のアプリケーション開発では、環境変数を使用して設定を管理することが一般的です。しかし、以下のような課題があります:

  • プロジェクトごとに異なる環境変数が必要
  • 環境変数の設定を忘れてしまう
  • 環境変数の管理が煩雑
  • チームメンバー間での環境変数の共有が難しい

direnvはこれらの課題を解決し、より効率的な開発環境の構築を可能にします。

direnvの特徴

  1. 自動的な環境変数の設定
    • ディレクトリに入ったときに自動的に環境変数を設定
    • ディレクトリから出たときに自動的に環境変数を解除
  2. シンプルな設定ファイル
    • .envrcファイルで環境変数を管理
    • シンプルな構文で設定可能
  3. セキュリティ
    • 設定ファイルの変更を検知
    • 信頼できる設定ファイルのみを実行
  4. クロスプラットフォーム対応
    • Linux、macOS、Windowsで動作
    • 様々なシェルに対応

Windowsとの相性はイマイチ、WSLは◎

前述の「クロスプラットフォーム対応」の中でWindowsもその候補に挙げました。たしかにバイナリは配布されていますし、インストールも問題ありません。しかし、私のWindows 11環境では正しく動作しませんでした。動作確認を行うと、設定の不足や不明なエラーでかなりハマります。Windows関連のIssueも沢山上がっているようなので、まだ安定していないのかもしれません。

これはdirenvに限らず、Linux向けツールの多くは、Windowsでうまく動かない、または、動かすのに苦労することが少なくありません。そういう意味でも、Linux向けのツールをそのまま動かせるWSLの存在は、非常に大きいと言えるでしょう。

そのため、この記事ではWSL環境における使用に絞って解説していきます。

セットアップ

ここからは、WSL環境で作業します。

インストール

$ sudo apt install -U -y direnv

フックの設定

$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc

フックの設定が完了したらターミナルを再起動し、設定を読み込ませましょう。

基本的な使い方

今回は、仮に「project_a」と「project_b」ディレクトリで動作確認を行います。

mkdir ~/project_{a,b}

project_aディレクトリに.envrcファイルを作成

$ echo 'export PROJECT=A' > ~/project_a/.envrc

PROJECT環境変数にAという値を設定します。

設定ファイルを信頼

$ direnv allow ~/project_a

direnv allowに続き、信頼する設定ファイルが置かれているディレクトリを指定します。

動作確認

$ cd ~/project_a
direnv: loading ~/project_a/.envrc
direnv: export +PROJECT

$ echo $PROJECT
A

project_aディレクトリに入ると.envrcが読み込まれ、PROJECT環境変数にAがセットされます。

$ cd ..
direnv: unloading

$ echo $PROJECT

project_aディレクトリから出ると環境変数が解放されます。

project_bディレクトリに.envrcファイルを作成

$ echo 'export PROJECT=B' > ~/project_b/.envrc

PROJECT環境変数にBという値を設定します。

設定ファイルを信頼

$ direnv allow ~/project_b

動作確認

$ cd ~/project_b
direnv: loading ~/project_b/.envrc
direnv: export +PROJECT

$ echo $PROJECT
B

project_bディレクトリに入ると.envrcが読み込まれ、PROJECT環境変数にBがセットされます。

$ cd ..
direnv: unloading

$ echo $PROJECT

project_bディレクトリから出ると環境変数が解放されます。

よく見られる使用事例

「開発環境」と「本番環境」という複数の環境を対象に作業していることを想定してみましょう。以降の作業はproject_cディレクトリ以下で行うので、ディレクトリを作成し、移動しておいてください。

$ mkdir ~/project_c
$ cd ~/project_c

開発環境の設定

アプリ開発のため、下記の3つの環境変数が必要だとしましょう。

  • データベースの接続情報
  • デバッグモードの有無
  • APIエンドポイントの設定

project_cディレクトリ内に、以下の内容で.envrcを作成してください。

export DATABASE_URL="postgres://localhost:5432/dev_db"
export DEBUG=true
export API_ENDPOINT="http://localhost:3000"

.envrcを編集するとdirenvが変更を検知し、`Run `direnv allow` to approve its content`のようなメッセージが出力されます。このメッセージが出力されたらdirenv allow ~/project_cを実行しておいてください。

これで、開発環境における環境変数が自動的にセットされるようになりました。ここまでは、すでに解説した通りです。

環境ごとの設定を切り替え

前述の設定だけだと、開発環境向けの環境変数しか設定できていません。本番環境と簡単に切り替えられると便利です。

まず.envというファイルを以下の内容で作成してください。.envは「dotenv」というライブラリがデフォルトで読み込む設定ファイルです。ここに書かれた値が環境変数として利用されます。様々なランタイムで実装され、.envファイルをデフォルトで読み込むプログラムも増えてきています。ここでは開発環境(DEV)と本番環境(PROD)それぞれのAPIキーを環境変数にセットしています。また、ENV環境変数に「prod」を指定しています。

DEV_API_KEY=0123456789
PROD_API_KEY=9876543210
ENV=prod

.envはあくまで環境変数のセットを管理するだけなので、環境そのものは切り替えできません。そこで、direnvを挟むことで環境の切り替えを実現できます。先ほど作成した.envrcを、以下の内容で書き換えてください。

# .envrcと同じ階層に.envファイルがあれば読み込む
if [ -f "$PWD/.env" ]; then
  source "$PWD/.env"
fi

# ENVにprodが設定されていれば本番用の値を環境変数にセット
if [ "$ENV" = "prod" ]; then
  export DATABASE_URL="postgres://prod-db:5432/prod_db"
  export DEBUG=false
  export API_ENDPOINT="http://prod-api:3000"
  # .envから読み込んだ本番用のAPI_KEYをセット
  export API_KEY=$PROD_API_KEY

# ENVがprod以外の場合は開発用の値を環境変数にセット
else
  export DATABASE_URL="postgres://localhost:5432/dev_db"
  export DEBUG=true
  export API_ENDPOINT="http://localhost:3000"
  # .envから読み込んだ開発用のAPI_KEYをセット
  export API_KEY=$DEV_API_KEY
fi

ここまでの説明でお気づきの方もいるかもしれませんが、.envrcにはシェルスクリプトが記述されています。実際のところ.envrcはただのシェルスクリプトなのです。このディレクトリに入るとスクリプトが実行され、exportした環境変数がこのディレクトリ下で有効になります。言い換えると、direnvを使用すればディレクトリへの移動をトリガーとして、任意の処理を実行できるというわけです。

想定される運用

プロジェクト内で共通の環境変数を使用する場合は、.envrcをプロジェクトのリポジトリに含めると良いでしょう。ただし、リポジトリで管理するのであれば機密情報を書くべきではありません。その場合は前述の「環境ごとの設定を切り替え」の項でも行っている通り.envに機密情報を記述し、それを読み込むようにすれば良いでしょう。その際は.envをリポジトリに含めてはいけません。

おわりに

direnvは環境変数の管理を効率化し、開発プロセスをスムーズにする強力なツールです。適切に使用することで環境設定の管理が容易になり、チーム開発の効率も向上します。プロジェクトの規模や複雑さに関わらず、導入を検討する価値があります。

日本仮想化技術株式会社
ソーシャルゲーム業界で10年間インフラエンジニアとして活動し、現在は日本仮想化技術でOpsエンジニアを担当。DevOps支援サービス「かんたんDevOps」では仕組み作りや導入支援、技術調査などを行っている。

連載バックナンバー

開発ツール技術解説
第13回

WSLで「direnv」を活用してプロジェクト単位で環境変数を管理しよう

2025/5/27
第13回の今回は「direnv」を活用して、WSL2上でプロジェクトごとに環境変数を柔軟かつ安全に管理する方法を解説します。
開発ツール技術解説
第12回

バージョン管理を柔軟に! プロジェクト単位で「asdf」を使いこなす

2025/5/7
第12回目の今回は、プロジェクトごとにツールのバージョンを管理できるバージョンマネージャー「asdf」の導入と活用方法について解説します。
開発ツール
第11回

「mmdebstrap」でUbuntuをカスタマイズして、オリジナルのWSLディストリビューションを作ろう

2025/4/15
第11回の今回は、「mmdebstrap」を使ってUbuntuをカスタマイズし、独自のWSLディストリビューションを作成する方法を解説します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています