MeWrite Docs

Environment variable not set

環境変数が設定されていない場合のエラー

概要

アプリケーションが必要とする環境変数が設定されていない場合に発生するエラーです。API キー、データベース接続文字列、シークレットなどの設定が不足しています。

エラーメッセージ

Error: Missing required environment variable: DATABASE_URL
TypeError: Cannot read properties of undefined (reading 'split')
Error: API_KEY is not defined
KeyError: 'SECRET_KEY' (Python)

原因

  1. .envファイルがない: 環境変数ファイルが作成されていない
  2. dotenv未読み込み: dotenvパッケージの初期化忘れ
  3. .envがgitignoreされていない: 本番にコピーされていない
  4. 変数名のタイプミス: 大文字小文字やスペルの間違い
  5. デプロイ先での設定忘れ: 本番環境での環境変数未設定

解決策

1. .envファイルの作成

1
2
3
4
5
# .env
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
API_KEY=your-api-key-here
NODE_ENV=development
PORT=3000
1
2
3
4
5
# .env.example(テンプレート、gitにコミット)
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
API_KEY=your-api-key
NODE_ENV=development
PORT=3000

2. Node.js(dotenv)

1
2
# dotenvをインストール
npm install dotenv
1
2
3
4
5
6
7
8
9
// アプリの最初に読み込む
require('dotenv').config();

// または ES Modules
import 'dotenv/config';

// 使用
const dbUrl = process.env.DATABASE_URL;
console.log(dbUrl);

3. バリデーション付きの読み込み

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// config.js
require('dotenv').config();

const requiredEnvVars = [
  'DATABASE_URL',
  'API_KEY',
  'JWT_SECRET'
];

for (const envVar of requiredEnvVars) {
  if (!process.env[envVar]) {
    throw new Error(`Missing required environment variable: ${envVar}`);
  }
}

module.exports = {
  databaseUrl: process.env.DATABASE_URL,
  apiKey: process.env.API_KEY,
  jwtSecret: process.env.JWT_SECRET,
  port: process.env.PORT || 3000,
  nodeEnv: process.env.NODE_ENV || 'development'
};

4. TypeScriptでの型安全な環境変数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// env.ts
import { z } from 'zod';

const envSchema = z.object({
  DATABASE_URL: z.string().url(),
  API_KEY: z.string().min(1),
  PORT: z.string().transform(Number).default('3000'),
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
});

export const env = envSchema.parse(process.env);

// 使用
import { env } from './env';
console.log(env.DATABASE_URL);  // 型安全

5. Python(python-dotenv)

1
pip install python-dotenv
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# settings.py
import os
from dotenv import load_dotenv

load_dotenv()

DATABASE_URL = os.getenv('DATABASE_URL')
if not DATABASE_URL:
    raise ValueError('DATABASE_URL is not set')

# デフォルト値付き
PORT = int(os.getenv('PORT', '8000'))
DEBUG = os.getenv('DEBUG', 'false').lower() == 'true'

6. Next.jsの環境変数

1
2
3
4
5
6
7
8
# .env.local(gitignore)
DATABASE_URL=...

# .env.development
NEXT_PUBLIC_API_URL=http://localhost:3000/api

# .env.production
NEXT_PUBLIC_API_URL=https://api.example.com
1
2
3
4
5
6
// 使用
// NEXT_PUBLIC_ プレフィックスはクライアントで利用可能
const apiUrl = process.env.NEXT_PUBLIC_API_URL;

// サーバーサイドのみ
const dbUrl = process.env.DATABASE_URL;

7. Docker での環境変数

1
2
3
# Dockerfile
ENV NODE_ENV=production
ENV PORT=3000
1
2
3
4
5
6
7
8
9
# docker-compose.yml
services:
  app:
    build: .
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb
      - API_KEY=${API_KEY}  # ホストの環境変数を使用
    env_file:
      - .env  # ファイルから読み込み
1
2
# コマンドラインから
docker run -e DATABASE_URL=... -e API_KEY=... myapp

8. GitHub Actions

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# .github/workflows/deploy.yml
jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      NODE_ENV: production
    steps:
      - name: Build
        env:
          API_KEY: ${{ secrets.API_KEY }}
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
        run: npm run build

9. Vercel/Netlify

1
2
3
4
5
# Vercel CLI
vercel env add DATABASE_URL production

# Netlify CLI
netlify env:set DATABASE_URL "your-value"

10. AWS Parameter Store / Secrets Manager

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// AWS SDK v3
import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm';

const client = new SSMClient({ region: 'ap-northeast-1' });

async function getSecret(name) {
  const command = new GetParameterCommand({
    Name: name,
    WithDecryption: true
  });
  const response = await client.send(command);
  return response.Parameter.Value;
}

const apiKey = await getSecret('/myapp/prod/api_key');

11. .gitignore の設定

# .gitignore
.env
.env.local
.env.*.local
.env.production

# .env.example はコミットする
!.env.example

12. デバッグ

1
2
3
4
5
6
7
8
// 環境変数の一覧を確認(開発時のみ)
if (process.env.NODE_ENV === 'development') {
  console.log('Environment variables:');
  console.log(Object.keys(process.env).filter(k => !k.startsWith('npm_')));
}

// 特定の変数を確認
console.log('DATABASE_URL:', process.env.DATABASE_URL ? '(set)' : '(not set)');

環境別ファイルの優先順位(Next.js)

  1. .env.$(NODE_ENV).local
  2. .env.local
  3. .env.$(NODE_ENV)
  4. .env

よくある間違い

  • .envファイルを本番サーバーにコピーし忘れる
  • NEXT_PUBLIC_プレフィックスをつけ忘れてクライアントで使えない
  • シークレットをクライアントサイドで使おうとする
  • .envファイルをgitにコミットしてしまう

関連エラー

参考リンク

最終更新: 2025-12-13