環境変数はシークレットをソースコードから分離し、再デプロイせずに設定を変更できます。.env ファイルはローカルで環境変数を管理する標準的な方法です。このガイドでは構文規則、フレームワーク設定、セキュリティ、環境別ファイル、Docker 統合、よくあるエラー、本番環境の代替手段を解説します。
.env 構文規則
.env ファイルは1行に1変数のプレーンテキストファイルです。すべての開発者が知っておくべきルール:
基本構文
各行は KEY=VALUE パターンに従います。等号の前後にスペースは入れません。
# .env
DATABASE_URL=postgres://localhost:5432/mydb
API_KEY=sk-1234567890abcdef
PORT=3000
DEBUG=trueクォート規則
値はクォートなし、シングルクォート、ダブルクォートが使えます。動作が異なります:
# Unquoted — trailing whitespace trimmed
APP_NAME=My Application
# Single quotes — literal, no interpolation
PASSWORD='p@$$w0rd#123'
# Double quotes — escape sequences + interpolation
GREETING="Hello\nWorld"
FULL_URL="${BASE_URL}/api/v1"- クォートなし:末尾の空白は除去、エスケープシーケンスなし。
- シングルクォート:値はリテラルとして扱われ、展開やエスケープなし。
- ダブルクォート:エスケープシーケンス(\n, \t)と変数展開をサポート。
複数行の値
ダブルクォートと \n で改行を表すか、ダブルクォート内で実際の改行を使用:
# Method 1: \n in double quotes
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIB...\n-----END RSA PRIVATE KEY-----"
# Method 2: actual newlines in double quotes
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"コメント
# で始まる行はコメントです。一部のパーサーではクォートなしの値でインラインコメントが使えます:
# This is a full-line comment
DATABASE_URL=postgres://localhost/mydb # inline comment (some parsers)
# Empty lines are ignored
API_KEY=abc123 # This may or may not work depending on the parser変数展開
${VAR} 構文で他の変数を参照(ほとんどのパーサーがダブルクォート内でサポート):
BASE_URL=https://api.example.com
API_V1=${BASE_URL}/v1
API_V2=${BASE_URL}/v2
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DATABASE_URL=postgres://${DB_HOST}:${DB_PORT}/${DB_NAME}フレームワーク設定
Node.js (dotenv)
Node.js で最も人気のある .env ローダー。インストールと設定:
# Install
npm install dotenv
# --- app.js (CommonJS) ---
require('dotenv').config();
console.log(process.env.DATABASE_URL);
# --- app.ts (ES Modules) ---
import 'dotenv/config';
console.log(process.env.DATABASE_URL);
# --- Or load from CLI ---
node -r dotenv/config app.js
node -r dotenv/config app.js dotenv_config_path=.env.localNext.js、Vite、Create React App は .env ファイルを自動的に読み込みます。パッケージのインストールは不要です。
Python (python-dotenv)
Python プロジェクトで .env を読み込む:
# Install
pip install python-dotenv
# --- app.py ---
from dotenv import load_dotenv
import os
load_dotenv() # loads .env from current directory
# load_dotenv('.env.local') # or specify a path
database_url = os.getenv('DATABASE_URL')
print(database_url)
# --- Django: manage.py or settings.py ---
from dotenv import load_dotenv
from pathlib import Path
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)Go (godotenv)
Go プロジェクトで .env を読み込む:
// Install
// go get github.com/joho/godotenv
package main
import (
"fmt"
"log"
"os"
"github.com/joho/godotenv"
)
func main() {
err := godotenv.Load() // loads .env
if err != nil {
log.Fatal("Error loading .env file")
}
dbURL := os.Getenv("DATABASE_URL")
fmt.Println(dbURL)
}PHP (vlucas/phpdotenv)
Laravel やほとんどの PHP フレームワークで使用:
// Install
// composer require vlucas/phpdotenv
<?php
require 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
// Access variables
$dbUrl = $_ENV['DATABASE_URL'];
// or
$dbUrl = getenv('DATABASE_URL');
// Required variables (throws exception if missing)
$dotenv->required(['DATABASE_URL', 'API_KEY']);Ruby (dotenv gem)
Rails やその他の Ruby プロジェクトで使用:
# Gemfile
gem 'dotenv-rails', groups: [:development, :test]
# Or for non-Rails Ruby:
gem 'dotenv'
# --- app.rb ---
require 'dotenv/load'
puts ENV['DATABASE_URL']
# --- Rails: .env is loaded automatically ---
# Access via ENV['DATABASE_URL'] anywhere in your appセキュリティ:.env ファイルを絶対にコミットしない
.env ファイルにはシークレット(API キー、データベースパスワード、トークン)が含まれます。バージョン管理にコミットすることは最大のセキュリティミスです。
.gitignore パターン
以下のパターンをすぐに .gitignore ファイルに追加してください:
# .gitignore
# Ignore all .env files
.env
.env.local
.env.*.local
.env.development
.env.production
# More aggressive pattern — ignore all .env variants
.env*
# But DO commit the example file
!.env.example.env.example を使う
値を空にした .env.example ファイルをコミットして、チームメンバーに必要な変数を知らせます:
# .env.example — commit this file
# Copy to .env and fill in your values
DATABASE_URL=
API_KEY=
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
REDIS_URL=
JWT_SECRET=
# Optional
DEBUG=false
LOG_LEVEL=infoすでに .env をコミットした場合
誤って .env ファイルをコミットした場合、トラッキングから削除してすべてのシークレットをローテーションしてください:
# Step 1: Remove .env from Git tracking (keeps local file)
git rm --cached .env
# Step 2: Add to .gitignore
echo ".env" >> .gitignore
# Step 3: Commit the removal
git add .gitignore
git commit -m "Remove .env from tracking, add to .gitignore"
# Step 4: CRITICAL — Rotate ALL secrets in the .env file
# Every API key, password, and token that was exposed
# must be regenerated immediately環境別ファイル
ほとんどのフレームワークは異なる環境用に複数の .env ファイルをサポートしています。読み込み順序の理解が重要です。
読み込み順序(Next.js / Vite / CRA)
ファイルは以下の優先順位で読み込まれます(後のファイルが前のファイルを上書き):
# Loading priority (highest to lowest):
# 1. Shell environment variables (always win)
# 2. .env.{NODE_ENV}.local (e.g. .env.production.local)
# 3. .env.local (NOT loaded in test)
# 4. .env.{NODE_ENV} (e.g. .env.production)
# 5. .env (default fallback)
# Example for NODE_ENV=production:
# .env → loaded first (base defaults)
# .env.production → overrides .env
# .env.local → overrides .env.production
# .env.production.local → overrides everything above.env.local は常に git で無視されます(.gitignore に追加)。テストの決定性を保つため、テスト時にはこのファイルは読み込まれません。
どのファイルを何に使う?
| File | Purpose | Git |
|---|---|---|
| .env | Default values, non-secret config | Commit |
| .env.example | Template with empty values | Commit |
| .env.local | Local secrets & overrides | Ignore |
| .env.development | Dev-specific (shared) | Commit |
| .env.production | Production-specific (non-secret) | Commit |
| .env.test | Test environment config | Commit |
| .env.production.local | Production secrets (local only) | Ignore |
Docker と Docker Compose の統合
env_file ディレクティブ
Docker Compose は .env ファイルをコンテナに直接読み込めます:
# docker-compose.yml (or compose.yml)
services:
web:
image: node:20-alpine
env_file:
- .env # base defaults
- .env.production # production overrides
ports:
- "3000:3000"
db:
image: postgres:16
env_file:
- .env.db # separate file for DB secrets
volumes:
- pgdata:/var/lib/postgresql/dataenvironment vs env_file
環境変数をインラインで設定することもできます。違いは次の通り:
# Using env_file (loads from file)
services:
web:
env_file:
- .env
# Using environment (inline)
services:
web:
environment:
- NODE_ENV=production
- PORT=3000
- DATABASE_URL=${DATABASE_URL} # from shell or .env
# Using environment (mapping syntax)
services:
web:
environment:
NODE_ENV: production
PORT: 3000- env_file:ファイルから読み込み、compose.yml をきれいに保ち、環境ごとに簡単に切り替え可能。
- environment:compose.yml 内で確認可能、シークレットでない値に適し、変数置換をサポート。
Docker Compose 変数用 .env
Docker Compose はプロジェクトルートの .env ファイルを自動読み込みし、compose.yml 内の変数置換に使用:
# .env (in same directory as compose.yml)
POSTGRES_VERSION=16
NODE_VERSION=20
APP_PORT=3000
# compose.yml — uses .env for variable substitution
services:
web:
image: node:${NODE_VERSION}-alpine
ports:
- "${APP_PORT}:3000"
db:
image: postgres:${POSTGRES_VERSION}
environment:
POSTGRES_DB: myappよくある .env エラー10選と修正方法
開発者が最も頻繁に遭遇する .env の問題:
| # | エラー | 原因 | 修正 |
|---|---|---|---|
| 1 | process.env.VAR が undefined | dotenv が未読み込みまたは使用後に読み込み | エントリファイルの最上部で dotenv.config() を呼び出す |
| 2 | 本番環境で変数が空 | .env ファイル未デプロイ、ファイルに依存している | ホスティングプラットフォーム(Vercel、AWS 等)で環境変数を設定 |
| 3 | .env の値に引用符が含まれる | パーサーが引用符をリテラル文字として扱う | パーサーのドキュメントを確認 |
| 4 | 間違った .env ファイルが読み込まれる | 作業ディレクトリが想定パスと異なる | path オプションを使用: dotenv.config({ path: ".env.local" }) |
| 5 | 複数行の値が切り捨てられる | 値が正しくダブルクォートされていない | 複数行の値をダブルクォートで囲む |
| 6 | 特殊文字が値を壊す | $ や # が展開/コメントとして解釈される | シングルクォートで展開を防止、または \ でエスケープ |
| 7 | BOM エンコーディングエラー | Windows エディタが UTF-8 BOM で .env を保存 | BOM なしの UTF-8 で保存。そうしないと最初の変数が読めなくなる可能性あり |
| 8 | Docker コンテナの環境変数が空 | env_file のパスが不正、またはファイルがビルドコンテキスト外 | パスが compose.yml の場所からの相対パスであることを確認 |
| 9 | = 前後のスペースでパースが失敗 | KEY=VALUE ではなく KEY = VALUE | 等号の前後のスペースを削除 |
| 10 | ブラウザで変数が利用不可(React/Next) | 必要なプレフィックス(NEXT_PUBLIC_ または REACT_APP_)がない | フレームワークが要求するプレフィックスを追加してクライアント側コードに公開 |
本番環境の代替手段
本番環境では .env ファイルは推奨されません。以下の代替手段を使用してください:
プラットフォーム環境変数
すべての主要ホスティングプラットフォームが環境変数設定用の UI または CLI を提供:
# Vercel
vercel env add DATABASE_URL production
vercel env ls
# AWS (Parameter Store)
aws ssm put-parameter \
--name "/myapp/prod/DATABASE_URL" \
--value "postgres://..." \
--type SecureString
# Heroku
heroku config:set DATABASE_URL=postgres://...
heroku config
# Railway
railway variables set DATABASE_URL=postgres://...
# Fly.io
fly secrets set DATABASE_URL=postgres://...Docker Secrets
Docker Swarm または Compose では、機密データに secrets を使用:
# compose.yml with Docker secrets
services:
web:
image: myapp:latest
secrets:
- db_password
- api_key
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./secrets/db_password.txt # for Compose
# external: true # for Swarm
api_key:
file: ./secrets/api_key.txt
# In your app, read from file:
# const secret = fs.readFileSync('/run/secrets/db_password', 'utf8').trim();シークレットマネージャー(Vault, AWS Secrets Manager)
エンタープライズアプリケーションには専用のシークレットマネージャーを使用:
# HashiCorp Vault
vault kv put secret/myapp/production \
DATABASE_URL="postgres://..." \
API_KEY="sk-..."
# Read in application
vault kv get -field=DATABASE_URL secret/myapp/production
# AWS Secrets Manager
aws secretsmanager create-secret \
--name "myapp/production/db" \
--secret-string '{"url":"postgres://...","password":"..."}'
# Read in Node.js with AWS SDK
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManager({ region: 'us-east-1' });
const { SecretString } = await client.getSecretValue({
SecretId: 'myapp/production/db'
});
const secrets = JSON.parse(SecretString);シークレットマネージャーはローテーション、監査ログ、アクセス制御、保存時の暗号化を提供します。これらは .env ファイルでは実現できない機能です。
よくある質問
.env ファイルを Git にコミットすべきですか?
シークレット(API キー、パスワード、トークン)を含む .env ファイルは絶対にバージョン管理にコミットしないでください。代わりに、値を空にした .env.example ファイルをコミットしてください。.gitignore に .env* パターンを追加してください。
.env、.env.local、.env.production の違いは?
.env はすべての環境で読み込まれるデフォルト値を含みます。.env.local はローカルの上書き値を含み、git にコミットしません。.env.production は NODE_ENV=production 時のみ読み込まれる本番固有の値を含みます。読み込み順序は:.env、.env.local、.env.[環境]、.env.[環境].local で、後のファイルが前のファイルを上書きします。
Node.js で process.env.MY_VAR が undefined なのはなぜ?
最も一般的な原因:1) エントリファイルの先頭で require("dotenv").config() を呼び忘れ、2) .env ファイルが Node の実行ルートにない、3) 変数名のタイプミス、4) ES モジュールを使用していて "import dotenv/config" が必要。
Docker Compose で .env 変数を使うには?
Docker Compose は compose.yml と同じディレクトリの .env ファイルを自動的に読み込み、${VAR} 構文で変数置換を行います。コンテナに変数を渡すには、env_file ディレクティブでファイルから読み込むか、environment キーで compose.yml にインラインで設定します。
本番環境で .env ファイルを使えますか?
推奨されません。本番環境では、プラットフォーム提供の環境変数(Vercel、AWS、Heroku ダッシュボード)、Docker secrets、または HashiCorp Vault や AWS Secrets Manager などのシークレットマネージャーを使用してください。
React や Next.js で .env 変数をブラウザに公開するには?
Next.js では変数名に NEXT_PUBLIC_ プレフィックスを付けます(例:NEXT_PUBLIC_API_URL)。Create React App では REACT_APP_ プレフィックス、Vite では VITE_ プレフィックスを使います。プレフィックス付きの変数のみがクライアントバンドルに埋め込まれます。