DevToolBox無料
ブログ

.envファイルガイド:環境変数のベストプラクティス

10分by DevToolBox

環境変数はシークレットをソースコードから分離し、再デプロイせずに設定を変更できます。.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.local

Next.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 に追加)。テストの決定性を保つため、テスト時にはこのファイルは読み込まれません。

どのファイルを何に使う?

FilePurposeGit
.envDefault values, non-secret configCommit
.env.exampleTemplate with empty valuesCommit
.env.localLocal secrets & overridesIgnore
.env.developmentDev-specific (shared)Commit
.env.productionProduction-specific (non-secret)Commit
.env.testTest environment configCommit
.env.production.localProduction 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/data

environment 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 の問題:

#エラー原因修正
1process.env.VAR が undefineddotenv が未読み込みまたは使用後に読み込みエントリファイルの最上部で dotenv.config() を呼び出す
2本番環境で変数が空.env ファイル未デプロイ、ファイルに依存しているホスティングプラットフォーム(Vercel、AWS 等)で環境変数を設定
3.env の値に引用符が含まれるパーサーが引用符をリテラル文字として扱うパーサーのドキュメントを確認
4間違った .env ファイルが読み込まれる作業ディレクトリが想定パスと異なるpath オプションを使用: dotenv.config({ path: ".env.local" })
5複数行の値が切り捨てられる値が正しくダブルクォートされていない複数行の値をダブルクォートで囲む
6特殊文字が値を壊す$ や # が展開/コメントとして解釈されるシングルクォートで展開を防止、または \ でエスケープ
7BOM エンコーディングエラーWindows エディタが UTF-8 BOM で .env を保存BOM なしの UTF-8 で保存。そうしないと最初の変数が読めなくなる可能性あり
8Docker コンテナの環境変数が空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_ プレフィックスを使います。プレフィックス付きの変数のみがクライアントバンドルに埋め込まれます。

𝕏 Twitterin LinkedIn
この記事は役に立ちましたか?

最新情報を受け取る

毎週の開発ヒントと新ツール情報。

スパムなし。いつでも解除可能。

Try These Related Tools

🐳Docker Compose Generator.gi.gitignore GeneratorNXNginx Config Generator

Related Articles

Docker Compose チートシート:サービス、ボリューム、ネットワーク

Docker Compose リファレンス:サービス定義、ボリューム、ネットワーク、環境変数、スタック例。

Docker Compose env_file vs environment:使い分けガイド(例付き)

Docker Composeのenv_fileとenvironmentの違いを理解。使い分け、変数の優先順位、.envファイルの挙動、マルチ環境設定。