🗝️

dotenvxを使って環境変数を暗号化して管理する

に公開

皆さんは、チームで開発する際に環境変数が書かれている .env ファイルをどのようにして管理・共有してますか?

私の経験上は安全面を考慮して Git の管理下に置かずに個々のローカルに作成して、チャットなどで環境変数が共有されることが多いのですが、環境変数が増えていくと共有漏れなどが起きたりしてちょっと面倒だなと思っています。

そこで今回は、dotenvx を使用して環境変数を暗号化することで .env ファイル を安全に Git で管理する方法をサンプルコードと一緒にご紹介したいと思います。

記事内に掲載しているソースコードは Github でも公開しています。

https://github.com/twosun-8-git/dotenvx

dotenvx とは 🤔

dotenvx は、従来の dotenv ライブラリの進化版で、環境変数を暗号化して管理できる機能が特徴です。

  • 🔐 暗号化機能: 環境変数を公開鍵暗号方式で暗号化
  • 🔄 複数環境対応: 開発・本番など環境ごとに異なる暗号化キーを使用
  • 🛡️ 安全性: 暗号化された状態でリポジトリにコミット可能
  • 📦 簡単導入: 既存の dotenv から簡単に移行可能

公式サイトはこちら → 🗝️ dotenvx 公式サイト

開発環境 🛠️

では、開発環境を準備していきたいと思います。今回は複数の .env ファイルを作成して最終的に Next.js で "開発環境"と"本番環境" それぞれの値が適切に出力されているところまで確認します。Node や Next.js などの詳しいバージョンは下記のようになっています。

各種バージョン情報

  • Node.js(18.20.4)
  • React ( ^19.0.0 )
  • Next ( 15.3.5 )
  • dotenvx ( ^1.47.5 )

では、まず create-next-app で Next アプリの雛形を作ります。アプリ名は my-dotenvx としました。

npx create-next-app

/ /下記のように設定
What is your project named?  my-dotenvx
Would you like to use TypeScript?  Yes
Would you like to use ESLint?  Yes
Would you like to use Tailwind CSS?  Yes
Would you like to use `src/` directory?  Yes
Would you like to use App Router? (recommended)  Yes
Would you like to customize the default import alias (@/*)?  No
Would you like to use Turbopack for `next dev`?  No

続いて dotenvx をインストールします。

npm install @dotenvx/dotenvx --save

これで準備ができました。
まずはプロジェクトルート直下に ".env.development"".env.production" の 2 つのファイルを作成します。

root
  ├ .env.development // 開発用.env.prodction // 本番用

次にそれぞれに環境変数を定義します。 development と production で異なる値をこの時点では平文で設定しておきます。

// .env.development
USER_NAME = yamada;
PASSWORD = 12345678;
// .env.production
USER_NAME = tanaka;
PASSWORD = abcdefg;

環境変数を暗号化する 🗝️

下記のコマンドで環境変数を暗号化することができます。暗号化はファイル内の環境変数をすべて一括で暗号化する方法と、個別に暗号化してセットする方法があります。

# ファイルを指定して全ての環境変数を暗号化する
npx dotenvx encrypt -f <ファイル名>

# ファイルを指定しなければ .env ファイルが対象になる
npx dotenvx encrypt

# 環境変数を個別に暗号化してセットする ( MESSAGE=hello world )
npx dotenvx set MESSAGE hello world

.env.development を暗号化

npx dotenvx encrypt -f .env.development
  ↓
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
#/            public-key encryption for .env files          /
#/       [how it works](https://dotenvx.com/encryption)     /
#/----------------------------------------------------------/
DOTENV_PUBLIC_KEY_DEVELOPMENT="020000ebb5e570b716d7e5d27bd3c08b5626a3c9a70d3501afe8174f31ba28ade3"

USER_NAME=encrypted:BNzpaY7FgHW4sbmfXJ/zsZBLIcGrT1G1/NqGM235HAY6m/8kUpm2kmw8GK1dpVaXDMr1DerzAeVqPJqZXtx77rG07n1shno4TbGwwKji+hzxF+tzaMB5mn8RoFDvHpWoy6it1JG3XQ==
PASSWORD=encrypted:BIv/TJOpKtWocUPGgrahfU24cJT/ormTieHRuKMhgri8PzwT1QxrpklTxel5r4zcIGrU+vPD5i4LmJIUn0cYsQneLCJnwaUztGAlFEXRfFqvmvhVinOzILAlk3tlfxnvIXS6DPNqqQUQ

.env.production を暗号化

npx dotenvx encrypt -f .env.production
  ↓
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
#/            public-key encryption for .env files          /
#/       [how it works](https://dotenvx.com/encryption)     /
#/----------------------------------------------------------/
DOTENV_PUBLIC_KEY_PRODUCTION="030a768ff47322209505e40031574e3b3dad8964e885b79eddade8f88e3d580df9"

USER_NAME=encrypted:BOFLsHazOLI/ejD9QZquN1bhjId3EX8wV1rDKnsLB/aL2WK9YC2U971ecWytyp7/fUSY7t3zjTpq7AFRYDFDvAY61m5OPBk3CXP9+Wgvnn92SqX94264uRSxvBfFf0aJ9LjDRvDwtA==
PASSWORD=encrypted:BCukfebi9BoSwDfICgCC6/gVYkp7ueo8uMYGajjI+xgtUO/UMZirmKVyDPsQuWUIi4DH7evDm/RnX/V935MTn/XuVCbxxKOHYB1aYeNMx505llZHI2Qcq0yrKnjsDlSpny1w6XecRiQ=

環境変数の "USER_NAME", "PASSWORD" が暗号化されていることが確認できました。

復号化について 🔓

先ほどのnpx dotenvx encrypt 実行すると復号するためのマスターキーファイル ".env.keys" がルートディレクトリに生成されます。このファイルひとつで暗号化された複数の ".env" ファイルの復号を行うことができます。

root
  ├ .env.development.env.keys // 生成された復号化用マスターキーファイル.env.prodction

".env.keys" の中身は下記のようになっています。

#/------------------!DOTENV_PRIVATE_KEYS!-------------------/
#/ private decryption keys. DO NOT commit to source control /
#/     [how it works](https://dotenvx.com/encryption)       /
#/----------------------------------------------------------/

# .env.development
DOTENV_PRIVATE_KEY_DEVELOPMENT=40a5b7b45f0f44aa62d402204675fac6a2289e93e6fe076f7965465c01a6f10b

# .env.production
DOTENV_PRIVATE_KEY_PRODUCTION=441a61b7e6b117bdee6f67b33de94f5a6d882b198b7c367869a3655e2dddb100

暗号化された環境変数の値を確認する

暗号化した後は当然ですがエディターなどで env ファイルを開いても環境変数の値を確認することはできません。そんな時はnpx dotenvx getコマンドを使用すれば簡単に確認できます。

# .env.development の USER_NAME を確認
npx dotenvx get USER_NAME -f .env.production
-> yamada

Next.js で環境変数を使用する 🖥️

暗号化した環境変数を Next.js で使用して開発環境と本番環境で異なる値が出力されることを確認していきます。

まずは、デフォルトの npm run devnpm run build を実行しても暗号化された環境変数を読み込めないので "package.json" を下記のように修正します。

package.json
  "scripts": {
    "dev": "npx dotenvx run -f .env.development -- next dev",
    "build": "npx dotenvx run -f .env.production -- next build",
    "start": "npx dotenvx run -f .env.production -- next start",
    ...

上記のコマンドは下記のような動作の流れになっています。

1. dotenvx が.env.development(または .evn.production) ファイルを読み込む
2. ファイル内の環境変数をプロセスに設定
3. Next.js のサーバーを起動(または build or start)

続いて"Result"コンポーネントで環境変数を出力します(特にコンポーネント化する意味はありません)。

src/app/_components/Result.tsx
export function Result() {
  return (
    <div>
      <h2 className="text-[22px] font-bold">環境変数を出力</h2>
      <p className="mb-4 text-gray-500">
        <i>`.env.development``.env.production` で値が異なることを確認</i>
      </p>
      <table className="border-separate border border-gray-300 rounded-lg overflow-hidden text-lg">
        <thead>
          <tr>
            <th className="py-2 px-4 border-b border-gray-300">USER_NAME</th>
            <th className="py-2 px-4  border-l border-b border-gray-300">
              PASSWORD
            </th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td className="py-2 px-4 text-blue-500">{process.env.USER_NAME}</td>
            <td className="py-2 px-4 text-blue-500 border-l border-gray-300">
              {process.env.PASSWORD}
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  );
}

開発環境と本番環境での環境変数の値は次の表にように定義されていますので実際に正しく動作するかを確認していきます。

環境変数 開発環境 本番環境
USER_NAME yamada tanaka
PASSWORD 12345678 abcdefg

開発環境で確認

npm run dev を実行し localhost:3000 にアクセスします。
".env.development"に定義されている環境変数 が確認できました(下記画像を参照)。
開発環境での環境変数の確認用画像
.env.development に定義されている環境変数

本番環境で確認

今度はnpm run buildnpm run start の順で実行し localhost:3000 にアクセスします。
".env.production"に定義されている環境変数 が確認できました(下記画像を参照)。
本番環境での環境変数の確認用画像
.env.production に定義されている環境変数

終わりに 🙇‍♂️

以前からチーム開発で新しい人が入ってくるたびに環境変数を共有するのが面倒だったために "dotenvx" を使用することで少し楽になりました。 .env.keys の最適な管理方法がまだ定まっていませんがこちらは確立したら追記したいと思います。

これで "dotenvx を使って環境変数を暗号化して管理する" の記事は以上になります。
最後までお読みいただき、ありがとうございました。この記事が皆様のお役に立てば幸いです。

Discussion