mcpField
D
direnv

direnv

github.com/julianobarbosa開発14119 回インストール2 日前に更新
リポジトリ

direnv について

プロジェクトごとのシェル環境を管理する開発者向けに、direnv の導入、設定、トラブルシューティングを案内するスキルです。.envrc の設定例、言語別レイアウト、安全機能、注意点を扱います。

主な機能

  1. 01インストールとシェルフックの設定
  2. 02`.envrc` 設定と許可リストによる保護
  3. 03環境変数と標準ライブラリ関数
  4. 04言語別レイアウトと Nix 連携
  5. 05トラブルシューティングと設定の実践

活用シーン

  1. 01シェルに direnv を設定
  2. 02プロジェクトごとの変数やパスを設定
  3. 03言語別または Nix の環境を読み込む
  4. 04環境の読み込み問題を調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/julianobarbosa/claude-code-skills --skill direnv

インストール後、Claude Code で/direnvを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
installation.md
stdlib-functions.md
troubleshooting.md

詳細

direnv スキル

このスキルでは、インストール、設定、標準ライブラリ関数、プロジェクトごとの環境管理のベストプラクティスなど、direnv を使用するための包括的なガイダンスを提供します。

このスキルを使用するタイミング

次の場合にこのスキルを使用してください:

  • macOS または Linux で direnv をインストールして設定するとき
  • プロジェクトの .envrc ファイルを作成または変更するとき
  • プロジェクトごとの環境変数を設定するとき
  • 言語固有のレイアウト(Python、Node.js、Ruby、Go、Perl)を設定するとき
  • direnv を Nix または Nix Flakes と統合するとき
  • チームでシークレットと環境設定を管理するとき
  • 環境の読み込みに関する問題をトラブルシューティングするとき
  • カスタム direnv 拡張機能を作成するとき

基本概念

direnv とは?

direnv は、現在のディレクトリに応じて環境変数を読み込み、読み込み解除するシェル拡張機能です。.envrc ファイルがあるディレクトリに cd すると、direnv が環境を自動的に読み込みます。そのディレクトリを離れると、変更が読み込み解除されます。

セキュリティモデル

direnv は、許可リストに基づくセキュリティ方式を採用しています:

  • 新規または変更された .envrc ファイルは、direnv allow で明示的に許可する必要があります
  • 信頼できないスクリプトが自動実行されるのを防ぎます
  • アクセスを取り消すには direnv deny を使用します
動作の仕組み
  1. シェルフックがディレクトリの変更を検知します
  2. 現在のディレクトリまたは親ディレクトリに .envrc ファイルがあるか確認します
  3. 許可されている場合、bash サブシェルで .envrc を実行します
  4. エクスポートされた変数を取得し、現在のシェルに適用します

インストール

macOS(Homebrew - 推奨)
brew install direnv
Linux
# Ubuntu/Debian
sudo apt install direnv

# Fedora
sudo dnf install direnv

# Arch
sudo pacman -S direnv

# Binary installer (any system)
curl -sfL https://direnv.net/install.sh | bash
インストールの確認
direnv version

シェルの設定

シェルの設定ファイルにフックを追加します。direnv を機能させるには、これが必須です。

Zsh(~/.zshrc)
eval "$(direnv hook zsh)"

Oh My Zsh を使用する場合:

plugins=(... direnv)
Bash(~/.bashrc)
eval "$(direnv hook bash)"

重要: rvm、git-prompt、その他のプロンプトを変更する拡張機能の後に配置してください。

Fish(~/.config/fish/config.fish)
direnv hook fish | source
設定後

シェルを再起動します:

exec $SHELL

.envrc ファイルの基本

.envrc の作成
# In your project directory
touch .envrc

# Edit with your preferred editor
vim .envrc
基本構文
# Export environment variables
export NODE_ENV=development
export API_URL=http://localhost:3000
export DATABASE_URL=postgres://localhost/myapp

# The export keyword is required for direnv to capture variables
.envrc の許可
# Allow current directory
direnv allow

# Allow specific path
direnv allow /path/to/project

# Deny/revoke access
direnv deny

標準ライブラリ関数

direnv には強力な標準ライブラリが含まれています。手動でエクスポートするより、常に標準ライブラリ関数を優先してください。

PATH の管理
# Prepend to PATH (safer than manual export)
PATH_add bin
PATH_add node_modules/.bin
PATH_add scripts

# Add to arbitrary path-like variable
path_add PYTHONPATH lib
path_add LD_LIBRARY_PATH /opt/lib

# Remove from PATH
PATH_rm "*/.git/bin"
環境ファイルの読み込み
# Load .env file (current directory)
dotenv

# Load specific file
dotenv .env.local

# Load only if exists (no error)
dotenv_if_exists .env.local
dotenv_if_exists .env.${USER}

# Source another .envrc
source_env ../.envrc
source_env /path/to/.envrc

# Search upward and source parent .envrc
source_up

# Source if exists
source_env_if_exists .envrc.local
言語別レイアウト

Node.js:

# Adds node_modules/.bin to PATH
layout node

Python:

# Creates virtualenv in .direnv/python-X.X/
layout python

# Use specific Python version
layout python python3.11

# Shortcut for Python 3
layout python3

# Use Pipenv (reads from Pipfile)
layout pipenv

Ruby:

# Sets GEM_HOME to project directory
layout ruby

Go:

# Modifies GOPATH and adds bin to PATH
layout go

Perl:

# Configures local::lib environment
layout perl
Nix の統合
# Load nix-shell environment
use nix

# With specific file
use nix shell.nix

# Load from Nix flake
use flake

# Load specific flake
use flake "nixpkgs#hello"
use flake ".#devShell"

Nix Flakes のサポートを強化するには、nix-direnv をインストールします:

# Provides faster, cached use_flake implementation
# https://github.com/nix-community/nix-direnv
バージョン管理ツール
# rbenv
use rbenv

# Node.js (with fuzzy version matching)
use node 18
use node 18.17.0

# Reads from .nvmrc if version not specified
use node

# Julia
use julia 1.9
検証
# Require environment variables (errors if missing)
env_vars_required API_KEY DATABASE_URL SECRET_KEY

# Enforce minimum direnv version
direnv_version 2.32.0

# Check git branch
if on_git_branch main; then
  export DEPLOY_ENV=production
fi
if on_git_branch develop; then
  export DEPLOY_ENV=staging
fi
ファイルの監視
# Reload when files change
watch_file package.json
watch_file requirements.txt
watch_file .tool-versions
watch_file config/*.yaml

# Watch entire directory
watch_dir config
watch_dir migrations
ユーティリティ関数
# Check if command exists
if has docker; then
  export DOCKER_HOST=unix:///var/run/docker.sock
fi

# Expand relative path to absolute
expand_path ./bin

# Find file searching upward
find_up package.json

# Enable strict mode (exit on errors)
strict_env

# Load prefix (configures CPATH, LD_LIBRARY_PATH, etc.)
load_prefix /usr/local/custom

# Load remote script with integrity verification
source_url https://example.com/script.sh "sha256-HASH..."

ベストプラクティス

推奨する .envrc テンプレート
#!/usr/bin/env bash
# .envrc - Project environment configuration

# Enforce direnv version for team consistency
direnv_version 2.32.0

# Load .env if exists
dotenv_if_exists

# Load local overrides (not committed to git)
source_env_if_exists .envrc.local

# Language-specific layout
layout node  # or: layout python3

# Add project bin directories
PATH_add bin
PATH_add scripts

# Development defaults
export NODE_ENV="${NODE_ENV:-development}"
export LOG_LEVEL="${LOG_LEVEL:-debug}"

# Watch for dependency changes
watch_file package.json
watch_file .nvmrc
Git の設定

.gitignore:

# Environment files with secrets
.env
.env.local
.envrc.local

# direnv virtualenv/cache
.direnv/

リポジトリにコミットするもの:

  • .envrc(シークレットを含まない基本設定)
  • .env.example(チームメンバー向けのテンプレート)
シークレットの管理

シークレットは絶対にコミットしないでください。 環境変数のフォールバックを使用します:

# .envrc (committed)
export DATABASE_URL="${DATABASE_URL:-postgres://localhost/dev}"
export API_KEY="${API_KEY:-}"

# Validate required secrets
env_vars_required API_KEY

# .envrc.local (gitignored)
export DATABASE_URL="postgres://user:secret@prod/app"
export API_KEY="actual-secret-key"
階層化された設定
# ~/projects/.envrc (global dev settings)
export EDITOR=vim

# ~/projects/api/.envrc
source_up
export API_PORT=3000

# ~/projects/api/feature/.envrc
source_up
export FEATURE_FLAG=true
プロジェクト構成
my-project/
├── .envrc           # Base environment (committed)
├── .envrc.local     # Local overrides (gitignored)
├── .env             # Environment variables (gitignored)
├── .env.example     # Template for team (committed)
└── .direnv/         # direnv cache (gitignored)

カスタム拡張機能

カスタム関数を作成するには、~/.config/direnv/direnvrc を作成します:

#!/usr/bin/env bash
# ~/.config/direnv/direnvrc

# Custom function: Use specific Kubernetes context
use_kubernetes() {
  local context="${1:-default}"
  export KUBECONFIG="${HOME}/.kube/config"
  kubectl config use-context "$context" >/dev/null 2>&1
  log_status "kubernetes context: $context"
}

# Custom function: Load from AWS Secrets Manager
use_aws_secrets() {
  local secret_name="$1"
  local region="${2:-us-east-1}"
  eval "$(aws secretsmanager get-secret-value \
    --secret-id "$secret_name" \
    --region "$region" \
    --query SecretString \
    --output text | jq -r 'to_entries | .[] | "export \(.key)=\"\(.value)\""')"
  log_status "loaded secrets from: $secret_name"
}

# Custom function: Use asdf versions from .tool-versions
use_asdf() {
  watch_file .tool-versions
  source_env "$(asdf direnv local)"
}

.envrc での使用方法:

use kubernetes dev-cluster
use aws_secrets myapp/dev
use asdf

コマンドリファレンス

コマンド説明
direnv allow現在の .envrc を許可します
direnv deny.envrc へのアクセスを取り消します
direnv reload環境を強制的に再読み込みします
direnv status現在の状態を表示します
direnv dump現在の環境をダンプします
direnv editエディターで .envrc を開きます
direnv versiondirenv のバージョンを表示します

トラブルシューティング

環境が読み込まれない
# Check status
direnv status

# Force reload
direnv reload

# Re-allow .envrc
direnv allow

# Check if hook is installed
echo $DIRENV_DIR
シェルフックの問題
  1. シェルの設定ファイルにフックがあることを確認します
  2. ファイルの末尾にあることを確認します
  3. シェルを完全に再起動します:exec $SHELL
  4. エラーを確認します:direnv hook zsh
パフォーマンスの問題
# Show what's being evaluated
direnv show_dump

# For Nix, use nix-direnv for caching
# https://github.com/nix-community/nix-direnv
デバッグ
# Verbose output
export DIRENV_LOG_FORMAT='%s'

# Show exported variables
direnv dump | jq

# Test .envrc syntax
bash -n .envrc

IDE との統合

VS Code

統合ターミナルで環境を自動的に読み込むには、direnv 拡張機能をインストールします。

JetBrains

direnv integration pluginをインストールします。

Neovim

direnv.vimを使用するか、luaで設定します。

よく使われるパターン

開発環境と本番環境
# .envrc
export NODE_ENV="${NODE_ENV:-development}"

if [[ "$NODE_ENV" == "development" ]]; then
  export DEBUG=true
  export LOG_LEVEL=debug
else
  export DEBUG=false
  export LOG_LEVEL=info
fi
マルチサービスプロジェクト(モノレポ)
# root/.envrc
export PROJECT_ROOT="$(pwd)"
export COMPOSE_PROJECT_NAME=myapp

# services/api/.envrc
source_up
export SERVICE_NAME=api
export SERVICE_PORT=3000

# services/web/.envrc
source_up
export SERVICE_NAME=web
export SERVICE_PORT=8080
Dockerとの連携
# .envrc
export COMPOSE_FILE=docker-compose.yml
export COMPOSE_PROJECT_NAME="${PWD##*/}"

if has docker-compose; then
  export DOCKER_HOST="${DOCKER_HOST:-unix:///var/run/docker.sock}"
fi

# Add Docker bin for containers that install CLI tools
PATH_add .docker/bin

参考資料


注意点

  • direnvはcd時に再読み込みしますが、ディレクトリに入り直さない限り.envrcの編集時には再読み込みしません: .envrcを変更しても、適用されたように見えます(エラーは出ません)が、cd .またはdirenv reloadを実行するまでは反映されません。編集中に変更を検知するには、.envrc自体にwatch_fileを使用してください。
  • direnv allowはパスではなくファイル内容のハッシュに基づいています: .envrc.devを.envrcに名前変更してから戻しても、許可状態は維持されます。一方、エディターを変えて保存した際に余分な末尾の改行が入るなど、1バイトでも編集すると許可が取り消されます。
  • layout pythonが作成する.direnv/python-X.Y/は、ホストのPythonバージョンに紐づいています: Pythonをアップグレードすると、仮想環境が気付かないうちに動作しなくなります。layout python python3.11でバージョンを固定するか、rm -rf .direnv && direnv reloadで再構築してください。
  • source_upは直近の親ディレクトリだけでなく、祖先ディレクトリも検索します: ~/や~/Projects/に残った.envrcが、すべてのサブディレクトリのプロジェクトに影響することがあります。ツリーの深い階層からdirenv statusを実行し、連鎖しているファイルをすべて確認してください。
  • .zshrcでのフックの配置順は重要です: eval "$(direnv hook zsh)"は、プロンプトやp10kの設定後に配置してください。それより前に配置すると、precmdフックがプロンプトの準備前に実行され、direnvの出力がプロンプトの再描画に隠れてしまいます。
  • PATH_add binで追加されるプロジェクト相対パスは、スクリプトが別の場所にcdすると問題になることがあります: PATHのエントリーは読み込み時に解決された絶対パスなので、cd /tmp && project-binaryは引き続き動作します。ただし、実行時に$PWD/binを読み取るバイナリは動作しません。

コメント