1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

direnv で実現するストレスフリーな環境変数管理

Posted at

はじめに

前回記事「git-duet で3人以上のモブプロコミットを表現する」を書く中で、git-duet のような「チームで共有したいツール設定」を、個人のローカル環境(~/.zshrcなど)にグローバルに設定してしまうことに抵抗を感じました。
この設定は、チーム共通のルールとしてプロダクトディレクトリ内に閉じ込め、そこに入ったときだけ自動で有効・解除されるスコープ管理を実現したいと考えました。
この課題を解決するため、以前 Tips で紹介した direnv を本格的に試したところ、期待通りに環境変数を管理できました。
本記事では、この自動切り替えを実現するための direnv の具体的な導入・設定手順を備忘録として残します。

動作環境

  • macOS 15.7.2
  • シェル zsh 5.9
  • direnv 2.37.1
  • パッケージ管理 Homebrew

direnv とは?

direnv は、ディレクトリの出入りをトリガーとして環境変数を自動で読み込み・解除するシェルの拡張ツールです。

プロダクトの環境変数は通常、プロダクト内の .env ファイルなどに集約されています。
しかし、その .env の内容を手動でシェルに読み込ませる手間や、ターミナルセッションを共有した場合に、環境変数が意図せず他のプロダクトに影響を与え続ける問題は解決できません。

direnv は、以下の仕組みでこの課題を解決します。

  1. 自動読み込み/解除: ディレクトリに cd で入った瞬間に設定を自動で有効化し、出た瞬間に無効化します。
  2. クリーンな分離: 必要な環境変数をそのプロダクト内でのみ有効にすることで、~/.zshrc などのグローバルな設定ファイルを汚さず、環境をクリーンに分離します。

この 「自動読み込みとクリーンな環境分離」 こそが、direnv の最大の利点です。

direnv の導入と基本設定

direnv の導入は、主に以下の2ステップで完了します。

  1. direnv の本体をインストールする
  2. zsh に direnv のフックを設定する

1. direnv の本体をインストールする

Homebrew を使ってインストールします。

$ brew install direnv

インストールが完了したら、バージョンを確認する。

$ direnv --version

今回は 2.37.1 で動作確認しています。

2. zsh に direnv のフックを設定する

direnv がディレクトリの出入りを監視できるように、現在使用しているシェル(zsh)に機能を組み込む(フックする)必要があります。
以下のコマンドを実行することで、設定ファイルである ~/.zshrc の末尾にフック設定を追記し、設定を即座に反映させます。

# 1. フック設定を .zshrc に追記
$ echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc

# 2. 設定の即時反映
$ source ~/.zshrc

環境変数の設定手順(.envrc の書き方)

ここからは、実際にプロダクト内で direnv を使うための核となる手順です。
今回は、チーム開発での運用を考慮し、設定を共有する .env.sample と、個人環境の設定を格納する .envrc を使い分けます。

1. .envrc の役割とファイル配置

direnv が正しく機能するため、およびチーム運用を円滑にするために、設定ファイルはプロダクトのルートディレクトリ直下に配置することが前提となります。
チームで運用する場合、個人の環境変数が誤ってGitにコミットされないよう、以下の手順で行います。

1. .gitignore の編集

まず、direnv の設定ファイルである .envrc をコミット対象から除外します。
この .gitignore ファイルも、プロダクトのルートディレクトリ直下にあることを想定しています。

.gitignore
.envrc

2. 共通設定の共有

git-duet に必要な設定など、チーム共通で必要な設定は、リポジトリにコミットされる .envrc.sample.envrc_common などに記述し、メンバー間で共有します。(ファイル名は任意)
.envrc の役割は、この共通設定を読み込み、さらに個人のローカル設定を上書き・追加することとなります。

git-duetの例

.envrc.sample
export GIT_DUET_ROTATE_AUTHOR=1
export GIT_DUET_ALLOW_MULTIPLE_COMMITTERS=1
export GIT_DUET_CO_AUTHORED_BY=1

2. .envrc の利用方法

1. 設定ファイルの作成とコピー

まず、プロダクトディレクトリ内で、.envrc.sample の内容をそのまま .envrc としてコピーします。

# プロダクトディレクトリ直下で実行
$ cp .envrc.sample .envrc

2. 個人設定の追記

次に、コピーした .envrc をエディタなどで開き、プロダクトに関係する個人の環境変数を必要に応じて追記します。

3. 許可コマンドの実行(direnv allow)

.envrc の利用を開始するには、セキュリティ上の理由から、そのファイルの内容を実行しても良いという許可を direnv に与える必要があります。
これは、悪意のあるシェルスクリプトが .envrc に紛れ込んでいた場合に、ディレクトリに入っただけで自動実行されるのを防ぐための非常に重要な仕組みです。
プロダクトディレクトリ内で、以下のコマンドを一度だけ実行してください。

$ direnv allow .

direnv allow を実行すると、direnv.envrc の実行を許可し、自動的に設定内容をカレントシェルに反映させます。

[補足] もし後から .envrc の内容を変更した場合は、変更が反映される前に direnv が警告を出します。その際は、再度 direnv allow コマンドを実行して、変更後のファイル内容を許可する必要があります。

4. 動作確認

設定が正しく反映され、意図通りに自動で切り替わるかを確認します。

1. 環境変数の設定確認:
現在、プロダクトディレクトリ内にいる状態で、env コマンドを使って GIT_DUET の設定が確認できれば成功です。

$ env | grep GIT_DUET
GIT_DUET_ROTATE_AUTHOR=1  # .envrc から読み込まれている
# ...その他の設定も表示

2. 自動解除の確認
プロダクトディレクトリから外(例: cd ..)に出ると、設定した環境変数が自動で解除されるかを確認します。

$ cd ..
direnv: unloading
$ env | grep GIT_DUET
# ↑ 何も表示されず、環境変数が解除されていれば成功

direnv: unloading と表示されると、環境変数が解除されています。

[注意] IntelliJ IDEA などの IDE に統合されたターミナルを利用している場合、環境変数が自動で解除されない場合があります。IDE自体を再起動 後、再度確認します。

おわりに

本記事では、git-duet のようなチームで共有したいツール設定を、個人のグローバルなシェル設定ファイル (~/.zshrc) に書かずに管理するため、direnv の導入手順をまとめました。

今回の設定により、以下のことが実現できました。

  • 環境のクリーン化: ~/.zshrc などの設定ファイルを汚さず、必要な設定だけをディレクトリ内に閉じ込められました。
  • 自動切り替え: プロダクトディレクトリに入るだけで環境変数が自動で有効になり、外に出ると自動で解除されるようになりました。
  • チーム運用への配慮: コミット対象の .envrc.sample と、Git管理対象外の .envrc を使い分けることで、チームでの運用に対応しました。

できる限り、個人のローカル環境を汚さずに、チーム開発したいですね。

Happy coding in a clean environment! 🌟

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?