こんにちは、かつコーチです。
前回は、Laravelアプリを本番環境にデプロイする一連の流れを解説しました。
その手順の中で何度も登場した .env ファイルですが、実は「開発環境と本番環境でどう使い分けるか」「パスワードなどの機密情報をどう安全に扱うか」は、初めてデプロイする人がつまずきやすいポイントです。
今回は、この .env ファイルの環境ごとの管理方法と、シークレット情報の安全な取り扱い方を掘り下げていきます。
.env ファイルの役割をおさらいする
環境によって変わる設定を1箇所に集める
.env ファイルは、データベースの接続情報やAPIキーなど、環境によって値が変わる設定をまとめて管理するファイルです。
# .env の例
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
APP_DEBUG=true
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
ソースコードの中に直接 password123 のような値を書いてしまうと、その値を変えるたびにコードを修正する必要が出てしまいます。
.env に切り出しておけば、環境ごとに違う値を設定でき、コード自体は一切変更せずに済みます。
.gitignore に含まれている理由
.env はLaravelの初期状態で .gitignore に登録されており、Gitの管理対象から外れています。
これは、データベースのパスワードやAPIキーといった機密情報が、そのままGitHubなどの公開リポジトリに載ってしまうのを防ぐためです。
代わりに、値の入っていない雛形として .env.example をリポジトリにコミットし、各環境でそれをコピーして値を埋める、という運用が基本になります。
環境ごとに .env を使い分ける
local / staging / production の違い
Laravelでは、APP_ENV の値によって「今どの環境で動いているか」を判定します。
| 環境 | APP_ENV | 用途 |
|---|---|---|
| ローカル開発 | local | 自分のPC上での開発 |
| ステージング | staging | 本番相当の環境で最終確認 |
| 本番 | production | 実際のユーザーが利用する環境 |
それぞれの環境ごとに、内容の異なる .env ファイルをサーバー側で個別に用意します。
# ローカルの.env(一部)
APP_ENV=local
APP_DEBUG=true
DB_HOST=127.0.0.1
DB_DATABASE=laravel_local
# 本番の.env(一部)
APP_ENV=production
APP_DEBUG=false
DB_HOST=db.internal.example.com
DB_DATABASE=laravel_production
重要なのは、この .env ファイル自体はどの環境でもGitの管理対象にせず、サーバーごとに直接配置する(またはCI/CDのシークレット機能経由で生成する)という点です。
APP_ENV を使ってコード側で環境判定する
.env の値は、コントローラやサービスクラスの中で app()->environment() を使って判定できます。
if (app()->environment('production')) {
// 本番環境でのみ実行したい処理
Log::channel('slack')->critical('重大なエラーが発生しました');
} else {
// ローカルやステージングではログに出すだけ
Log::debug('デバッグ情報');
}
「本番でだけ通知を飛ばす」「ローカルでだけデバッグ用のツールバーを表示する」といった環境依存の分岐は、この仕組みを使うのが基本です。
つまずきやすいポイント:.env を誤ってGitにコミットしてしまった経験
一度公開リポジトリに機密情報を上げてしまった話
私が実際にやってしまった大きな失敗が、.gitignore の設定前に一度だけ .env をコミットしてしまったことです。
❌ Before:.gitignore の設定を後回しにしてしまう
# プロジェクト作成直後、.gitignoreを確認せずにコミット
git init
git add .
git commit -m "initial commit"
git push origin main
このとき、.env の中にはローカル用とはいえデータベースのパスワードが書かれた状態のまま、リポジトリの履歴に残ってしまいました。
幸いプライベートリポジトリだったため実害はありませんでしたが、後から git log の履歴を確認して初めて気づき、青ざめた記憶があります。
✅ After:コミット前に .gitignore と git status を必ず確認する
git init
# .gitignoreに.envが含まれているか先に確認する
cat .gitignore | grep ".env"
# add前に何がステージされるか必ず確認する
git status
git add .
git commit -m "initial commit"
一度コミット履歴に混入した機密情報は、単に .env を削除するコミットを積んでも履歴には残り続けてしまいます。
この失敗以降、私は新規プロジェクトを作るたびに、最初のコミットの前に必ず git status で .env がステージされていないことを確認するようにしています。
もし誤ってコミットしてしまった場合は、git filter-repo などで履歴自体から該当ファイルを除去したうえで、該当のパスワードやAPIキーは速やかに再発行することが必須です。
本番のシークレット情報を安全に配置する方法
サーバーに直接SCPで送る方法
もっともシンプルなのは、.env ファイルをサーバーに直接転送する方法です。
scp .env.production user@your-server:/var/www/your-app/.env
小規模なプロジェクトであれば、この方法でも十分実用的です。
CI/CDのシークレット機能を使う方法
前回のCI連携の記事で登場したGitHub Actionsには、機密情報を安全に扱うためのSecretsという機能があります。
GitHubリポジトリの「Settings > Secrets and variables > Actions」から登録した値は、ワークフローの中で ${{ secrets.名前 }} として参照できます。
- name: 本番サーバーに.envを生成
run: |
echo "APP_ENV=production" > .env
echo "APP_KEY=${{ secrets.PROD_APP_KEY }}" >> .env
echo "DB_PASSWORD=${{ secrets.PROD_DB_PASSWORD }}" >> .env
Secretsに登録された値は暗号化されて保存され、ログにも自動的にマスクされて表示されるため、GitHub Actionsの実行ログを誰かが見ても値そのものは分かりません。
クラウドのシークレット管理サービスを使う方法
AWSやGCPを使う場合は、AWS Secrets ManagerやGoogle Secret Managerといった専用のサービスに機密情報を保管し、アプリ起動時に取得する構成もよく使われます。
規模が大きくなるほど、.env ファイル単体で管理するよりも、こうした専用サービスに一元化した方が、アクセス権限の管理やローテーション(定期的な値の更新)がしやすくなります。
応用:.env に頼りすぎない設計
設定値はできるだけ config/ 経由で参照する
Laravelのベストプラクティスとして、コントローラやサービスクラスの中で env() 関数を直接呼び出すのは推奨されていません。
// ❌ Before:env()を直接呼び出す
$apiKey = env('STRIPE_API_KEY');
// ✅ After:config/経由で取得する
$apiKey = config('services.stripe.key');
// config/services.php
return [
'stripe' => [
'key' => env('STRIPE_API_KEY'),
],
];
理由は、次回解説する config:cache を実行すると、キャッシュされた設定ファイルからは .env の値が読み込まれなくなるためです。
config/ の設定ファイル経由で一度値を受け取るようにしておけば、キャッシュを使った本番運用でも正しく値が反映されます。
まとめ
この記事のポイント
.envは環境によって変わる設定をまとめる仕組みで、.gitignoreによりGit管理から除外するのが基本APP_ENVの値(local / staging / production)で環境ごとの挙動をコード側で分岐できる- 一度Gitにコミットした機密情報は履歴に残り続けるため、コミット前の
git status確認が重要 - 本番のシークレットは、SCPでの直接転送、CI/CDのSecrets機能、クラウドのシークレット管理サービスなど規模に応じて選ぶ
env()の直接呼び出しは避け、config/の設定ファイル経由で値を参照するのがベストプラクティス
次に読むべき記事
環境変数の扱い方を理解したところで、次はその config:cache を含めた「Laravelのキャッシュ設定」について詳しく見ていきます。
→ 次の記事:Laravelのキャッシュ設定(config/route/viewキャッシュ)