MENU

`.envファイルとは?環境変数の基本と安全な管理方法`

.envファイルとは?環境変数の基本と安全な管理方法

.env ファイルは、アプリごとに変わる設定値や秘密情報をコード本体から切り離して管理するためのファイルです。APIキー、データベース接続先、ポート番号のように、環境ごとに値が変わるものをまとめるときに使います。

実務で重要なのは、.env を「便利な設定ファイル」として雑に置くことではありません。公開してはいけない値をコードやGitに混ぜないこと、そして本番では .env 以外の仕組みも使い分けることです。ここを外すと、設定ミスより先に情報漏えいが起きます。

  • .env でできること: 開発環境ごとの差分をコードから分離できる
  • よく使う場面: ローカル開発、チーム開発、Docker実行、フレームワーク初期設定
  • まず押さえる結論: 秘密情報を直書きしない、.env をそのまま公開しない、公開側アプリでは秘密を置かない
  • この記事の例: 主に Node.js / Next.js / Docker / GitHub Actions を想定

ここがポイント: .env は「秘密を安全にしてくれる魔法の箱」ではありません。安全性は、Git無視、公開範囲の分離、CI/CDのSecrets管理まで含めて初めて成立します。

目次

.env ファイルと環境変数の関係

最初に区別したいのは、.env と環境変数は同じものではない、という点です。

環境変数は、OSや実行プロセスが持つ KEY=VALUE 形式の値です。アプリはそれを process.env などを通じて読み取ります。.env は、その環境変数をファイルとして書いておき、起動時に読み込むための補助的な仕組みです。

たとえば次のような設定は、コードに埋め込まず環境変数に向いています。

  • DATABASE_URL
  • API_KEY
  • APP_ENV
  • PORT
  • LOG_LEVEL

12-Factor App でも、デプロイごとに変わる設定はコードから分離して環境で管理する考え方が示されています。これは、開発用と本番用で値が違う現場ほど効きます。

.env が向いている値、向いていない値

向いている値

  • 環境ごとに変わる接続先
  • APIキーやトークン
  • ポート番号、ホスト名
  • 機能フラグ

向いていない値

  • 固定の業務ロジック
  • 大きな設定構造体を丸ごと置く運用
  • フロントエンドで隠したい秘密情報

後者を .env に寄せすぎると、設定の見通しが悪くなります。.env は万能な設定保管庫ではなく、変動する値の置き場所として使うのが基本です。

基本の書き方と最小例

Node.js の公式ドキュメントでは、.env はキーと値の組を1行ずつ書く形式として説明されています。Node.js には独自の .env 仕様もありますが、実務では多くのツールが似た形式を使います。

まずは最小例です。

APP_ENV=development
PORT=3000
DATABASE_URL=postgres://user:password@localhost:5432/sampledb
API_KEY=example_key_123

JavaScript 側では次のように読みます。

console.log(process.env.APP_ENV)
console.log(process.env.PORT)

想定される出力例です。

development
3000

命名ルールの目安

よく使われる書き方は次の通りです。

  • 変数名は大文字のスネークケース: DATABASE_URL
  • 値は = の右側に書く
  • コメントは # で始める
  • 意味が曖昧な短縮名は避ける

NG例も見ておくと実務で崩れにくくなります。

x=1
pass=abc123
url=localhost

これより、役割が分かる形のほうが安全です。

APP_PORT=3000
DB_PASSWORD=abc123
API_BASE_URL=http://localhost:8080

Node.js での読み込み方法

Node.js では、process.env で環境変数を参照できます。さらに、Node.js 20.6.0 で --env-file が追加され、最近のバージョンでは .env を標準機能で読み込みやすくなっています。

もっとも簡単な実行例

.env:

PORT=3000
APP_NAME=sample-app

app.js:

console.log(`name=${process.env.APP_NAME}`)
console.log(`port=${process.env.PORT}`)

実行コマンド:

node --env-file=.env app.js

出力例:

name=sample-app
port=3000

複数ファイルの読み込み

環境ごとの差分を分けたいなら、複数の --env-file を使えます。

node --env-file=.env --env-file=.env.development app.js

Node.js 公式では、後から指定したファイルが先の値を上書きします。また、同じ変数がOS側の環境変数にもある場合は、環境側の値が優先されます。

このルールを知らないまま調査すると、「.env を直したのに値が変わらない」という初歩的な詰まり方をしやすいです。

よくあるファイル構成

運用で使いやすいのは、役割ごとにファイルを分ける形です。

.env
.env.local
.env.development
.env.production
.env.example

それぞれの役割

  • .env: 共通の既定値
  • .env.local: 各開発者のローカル上書き
  • .env.development: 開発環境用
  • .env.production: 本番用の設定名の整理用
  • .env.example: 配布用の見本。秘密の実値は入れない

特に重要なのが .env.example です。新しく参加した人が必要な設定名を把握でき、値だけ自分で埋めれば動かせます。

例:

APP_ENV=
PORT=
DATABASE_URL=
API_KEY=

実務での使いどころ

概念だけだと使い分けが曖昧になるので、場面ごとに整理します。

ローカル開発

もっとも典型的です。各自のPCで接続先やAPIキーが違っても、コードを変えずに実行できます。

  • 開発者AはローカルDBへ接続
  • 開発者Bは検証用APIへ接続
  • アプリ本体のコードは同じ

ステージングと本番の切り替え

同じアプリでも、URLや認証情報は環境ごとに違います。

  • ステージング: テスト用DB、開発者向け通知
  • 本番: 本番DB、本番通知先、監視設定あり

この差分をコードの if で埋めるより、環境変数として切り出したほうが管理しやすくなります。

Docker 実行

Docker は --env-file や Compose の env_file で環境変数を読み込めます。ただし Docker Docs では、パスワードのような機密情報を環境変数でコンテナに渡すより secrets を使うべきと明示しています。

つまり、ローカル開発では .env、本番寄りでは secrets という切り分けが現実的です。

Next.js やフロントエンドでの注意点

ここは誤解が多い部分です。フロントエンド系では、.env に書いたから安全になるわけではありません。

Next.js では NEXT_PUBLIC_ で始まる変数はブラウザ側に公開されます。つまり、次のような値は公開対象です。

NEXT_PUBLIC_API_BASE_URL=https://example.com

一方で、秘密にしたい値は NEXT_PUBLIC_ を付けず、サーバー側だけで使う必要があります。

STRIPE_SECRET_KEY=...

フロントエンドでやってはいけないこと

  • 公開バンドルに入る変数へAPIシークレットを書く
  • .env にあるから見えないはず」と思い込む
  • クライアント側コードで秘密鍵を参照する

Next.js の公式でも、ブラウザに束ねられるのは NEXT_PUBLIC_ の付いた変数だと明記されています。公開アプリでは、どの値がブラウザへ出るかを名前で見分ける癖が必要です。

安全に管理するための基本ルール

ここがこの記事の本題です。.env の事故は、文法より運用で起きます。

1. .env をGitにコミットしない

最低限、.gitignore に入れます。

.env
.env.*
!.env.example

ただし、この書き方を採用するなら、共有したい .env.production などを本当に除外してよいかはチームで決めてください。無条件で広く除外すると、必要なテンプレートまで消えます。

2. 実値ではなく .env.example を共有する

チームへ渡すのは「項目名の一覧」です。実際の値は共有チャットに貼らず、パスワードマネージャーやSecrets機能で渡します。

3. 本番はSecrets管理を使う

GitHub Actions なら Secrets が使えます。リポジトリ、環境、組織単位で保持でき、ワークフローから明示的に参照します。

.env をそのままリポジトリに置く運用より、漏えい面でも権限面でもこちらが適切です。

4. ログに出さない

デバッグ中に次のようなコードを書くと、秘密情報がそのまま出ます。

console.log(process.env)

一時的でも避けるべきです。必要なら、キー名だけ出す、マスクする、長さだけ確認する、といった方法に変えます。

5. 使い終わったキーはローテーションする

一度でも誤って公開したら、.gitignore に追加して終わりではありません。すでに履歴やログへ残っている可能性があるため、値自体を再発行する必要があります。

よくある失敗と対処法

初心者が詰まりやすい点はかなり共通しています。

変数名を変えたのに反映されない

原因として多いもの:

  • 開発サーバーを再起動していない
  • 既存の環境変数が優先されている
  • 別の .env.* が上書きしている

確認ポイント:

  • 実行し直したか
  • シェルで同名の環境変数を export していないか
  • フレームワークの読み込み順を確認したか

.env を置いたのに読まれない

原因として多いもの:

  • ファイルの置き場所が違う
  • ツール側が自動読込しない
  • ファイル名が期待と違う

Next.js では .env* はプロジェクトルート基準です。src 配下に置いても読まれません。Node.js でも --env-file を付けなければ、自動では読み込みません。

数値や真偽値だと思っていたら文字列だった

環境変数は基本的に文字列です。たとえば次はそのままだと文字列です。

PORT=3000
DEBUG=false

JavaScript 側では必要に応じて変換します。

const port = Number(process.env.PORT)
const debug = process.env.DEBUG === 'true'

ここを曖昧にすると、false のつもりが真扱いになる事故が起きます。

NG例から見る安全な改善

NG例1: コードへ秘密情報を直書きする

const apiKey = 'sk_live_xxxxx'

改善例:

const apiKey = process.env.API_KEY

意味が大きく違います。コード共有やレビューの時点で秘密が広がらなくなります。

NG例2: フロントエンド公開変数へ秘密を書く

NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_live_xxxxx

改善例:

NEXT_PUBLIC_API_BASE_URL=https://example.com
STRIPE_SECRET_KEY=sk_live_xxxxx

公開してよい値と秘密を分離します。

NG例3: .env を共有ドライブやチャットへ平文で貼る

改善例:

  • 項目名は .env.example で共有
  • 実値は Secrets 管理やパスワードマネージャーで配布
  • 失効できる鍵は短命にする

代替手段と使い分け

.env だけで全部回そうとすると、どこかで無理が出ます。用途ごとに分けると整理しやすくなります。

.env が向く場面

  • ローカル開発
  • 小規模な検証環境
  • サンプルアプリのセットアップ

Secrets管理が向く場面

  • GitHub Actions
  • クラウド上の本番環境
  • 権限分離が必要なチーム運用
  • 監査ログやローテーションが必要な案件

Docker secrets などが向く場面

  • コンテナ運用で機密情報を安全に渡したい
  • 環境変数に載せたくない値がある

.env は入口として非常に便利ですが、本番運用の終着点ではないと考えると判断しやすくなります。

まず試せる最小手順

最後に、手元で試すための最短手順をまとめます。

  1. プロジェクト直下に .env を作る
  2. 次の内容を書く
APP_NAME=my-sample
PORT=3000
  1. app.js を作る
console.log(process.env.APP_NAME)
console.log(process.env.PORT)
  1. Node.js 20.6.0 以降で実行する
node --env-file=.env app.js
  1. .gitignore.env を追加する
  2. チーム共有用に .env.example を作る

これだけで、.env の役割と基本的な安全運用はひと通りつかめます。次に見るべき点は、自分のプロジェクトでどこまでを .env に置き、どこからSecrets管理へ切り替えるかです。ここを曖昧にしないことが、実務では一番効きます。

参照リンク

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次