.envファイルに書いたAPIキーをそのままGitにコミットしてしまい、慌てて履歴を消した——。 逆に、ローカルでは.envで動いていたのに、Docker用の設定にはJSON形式が必要だと言われて手が止まった——。 設定ファイルにまつわるこうした「あるある」の背景には、.env・JSON・YAMLという3つの形式が それぞれ違う目的で生まれ、違う得意分野を持っているという事情があります。 この記事では3形式の違いと、環境変数を安全に管理するための実務的なポイントを解説します。
.env・JSON・YAMLの違い
まずは3形式の構文的な特徴を比較します。同じ設定情報でも、書き方も得意分野もまったく異なります。
| 項目 | .env | JSON | YAML |
|---|---|---|---|
| 構文 | KEY=VALUE | { "key": "value" } | key: value |
| コメント | 対応(# のみ) | 非対応 | 対応(# のみ) |
| 階層構造 | 表現不可(フラットのみ) | 可能(ネストしたオブジェクト) | 可能(インデントで表現) |
| 配列 | 非対応(カンマ区切り文字列で代用) | 対応 | 対応 |
| 型 | すべて文字列 | 文字列・数値・真偽値・null | 文字列・数値・真偽値・null |
| 可読性・主な用途 | 環境変数として直接読み込み | プログラム間のデータ交換・API | 人間が編集する設定ファイル |
JSON(JavaScript Object Notation)はJavaScriptのオブジェクト記法をベースにしたデータ形式です。 YAML(YAML Ain't Markup Language)はインデントで階層を表現する人間向けの設定記述形式です。 一方.envは特定の団体が定めた正式規格ではなく、dotenvライブラリなどの普及によって定着した慣習的な形式で、 名前の「env」はenvironment(環境)に由来します。
.envは「シェルの環境変数をそのままファイルに書き出したもの」に近い形式で、process.env.API_KEY のようにコードから直接参照できる手軽さが強みです。 一方でJSONは構造化データをプログラム同士でやり取りするのに適し、YAMLは人間が手で編集・レビューする設定ファイルに向いています。 この3つは優劣ではなく、用途に応じた住み分けだと理解しておくと迷いません。
なぜ環境変数を分離するのか — Twelve-Factor Appの思想
クラウド時代のアプリケーション設計指針としてよく引用される「The Twelve-Factor App」では、 「設定(Config)をコードから厳密に分離する」ことが原則の1つとして挙げられています。 APIキー・データベースの接続文字列・外部サービスのエンドポイントなどは、 開発環境・ステージング環境・本番環境で異なる値を持つべきものです。 これらをソースコードに直接書き込んでしまうと、環境ごとに異なるコードを管理する羽目になります。
環境変数として外部化しておけば、同じビルド成果物を環境ごとに異なる設定だけ差し替えてデプロイできます。 これがDocker・Kubernetesなどのコンテナ基盤で環境変数管理が重視される理由であり、 .env / ConfigMap / Secretといった仕組みはすべてこの思想の実装形態と言えます。
.gitignoreへの登録とAPIキー漏洩対策
.envファイルには機密情報が含まれるため、プロジェクト作成時点で.gitignoreに追加することが鉄則です。
# .gitignore に追加
.env
.env.local
.env.*.local
代わりに、キーの値を空またはダミー値にした.env.exampleを リポジトリにコミットし、チームメンバーがどんな設定項目が必要かを把握できるようにするのが定番の運用です。
誤ってコミットしてしまった場合の対処
①漏洩したAPIキー・パスワードはすべて発行し直す(ローテーション)。 一度公開されたキーは、後から履歴を消しても「漏洩済み」として扱うべきです。 ②git filter-repoやBFG Repo-Cleanerを使ってGit履歴からファイルを完全に削除し、リモートへ強制pushします。 次のコミットでファイルを削除するだけでは、過去のコミットに平文のまま残り続けます。
形式変換が必要になる実務シーン
1つのプロジェクトでも、ツールやインフラが変わるたびに設定を別形式で書き直す必要が出てきます。
| シーン | 使う形式 | 理由 |
|---|---|---|
| ローカル開発(Node.js等) | .env | dotenvで即読み込み・手軽 |
| Docker Compose | .env + YAML | env_fileで.envを読込、compose本体はYAML |
| Kubernetes | YAML(ConfigMap/Secret) | マニフェストとしてYAMLで宣言的に管理 |
| CI/CDのシークレット管理 | JSON / YAML | GitHub Actions等のワークフロー設定がYAML |
| フロントエンドの設定オブジェクト | JSON | JavaScriptのオブジェクトとして直接扱える |
KubernetesのConfigMapは機密性のない設定値(APIのURLなど)を、SecretはBase64エンコードされた機密情報(パスワード・トークンなど)を管理するリソースです。 どちらもYAML形式のマニフェストとして記述します。 .envで管理していたローカル環境の設定を、そのままKubernetesのYAMLに移植したい場面は非常に多く、 手作業で書き写すとキーの記述ミスや値の取り違えが起きがちです。
ブラウザ完結でAPIキーを外部に送らず変換する
.env・JSON・YAML間の形式変換は構文が単純なため、オンライン変換ツールも多く存在します。 ただし変換対象はAPIキーやデータベースのパスワードを含むファイルであるため、どこにデータが送信されるかは無視できないポイントです。
.env↔JSON↔YAML変換ツールはファイルをサーバーに送信せず、すべてブラウザ内のJavaScriptで変換処理を完結します。 機密情報を含む設定ファイルでも、外部に送信することなくその場で形式変換できます。 変換後のJSONの構文チェックにはJSON整形/検証ツールが便利です。また、.envファイルそのものを共有・保管する際にAPIキー部分だけを暗号化しておきたい場合はテキスト暗号化/復号ツールでAES-256暗号化しておく方法もあります。
まとめ
- .envは環境変数をそのまま書けるフラットな形式、JSONはプログラム間のデータ交換向き、YAMLは人間が編集する設定ファイル向き
- .envとYAMLはコメント(#)を書けるが、JSONはコメントを書けない
- 階層構造・配列を表現できるのはJSONとYAMLのみで、.envはフラットな値しか持てない
- Twelve-Factor Appの原則に基づき、設定はコードから分離して環境ごとに差し替える
- .envは必ず.gitignoreに登録し、代わりに.env.exampleを共有する
- 誤ってコミットした場合は、キーのローテーションとGit履歴からの完全削除の両方が必要
- Docker Compose・Kubernetesなど基盤が変わるたびに形式変換が発生し、ブラウザ完結ツールなら機密情報を外部に送らず変換できる