Heroku 創辦人 Adam Wiggins 在 The Twelve-Factor App(十二要素應用程式宣言,SaaS 的方法論)主張雲端原生應用程式應該在環境中儲存組態(Config)而非寫死在程式裡,最早由 Ruby 圈的 dotenv 函式庫將此概念發揚光大,用 KEY=VALUE 格式將設定寫成 .env 檔案:

PORT=3000
DATABASE_URL=postgres://user:password@localhost:5432/mydb
MY_API_KEY=sk_test_4eC39ThisIsABook7dc

之後,各大主流程式語言(Node.js, Python, PHP, Go 等)紛紛加入支援,讓 .env 成為通用標準。以 Node.js 為例,先 npm install dotenv 安裝,程式使用 require('dotenv').config() 載入 .env,之後便可以透過 process.env.PORT 取得設定值;Python 則是 pip install python-dotenv 安裝,

import os
from dotenv import load_dotenv
load_dotenv()

port = os.getenv("PORT")
# ...

在 .NET 裡,也有對映的組態管理概念,IConfiguration 機制會依據以下順序讀取參數

  1. appsettings.json
  2. appsettings..json
  3. 使用者祕密
  4. 環境變數設定
  5. 命令列引數

在這些來源中,環境變數算是最直接的簡便做法,在簡單應用中不必動用 IConfiguration、不需要安裝程式庫用,使用內建 API Environment.GetEnvironmentVariable() 即可存取,設定值並可多專案共用。當程式被打包放進 Docker 容器,在 docker-compose.yaml 可透過 environment 改用正式環境設定,實現測試環境與

services:
  webapp:
    environment:
      - PORT=3000
      - STRIPE_API_KEY=sk_test_4eC39HqLyjWDarjtT1zdp7dc

最近常寫 AI 相關應用程式,模型 End Point 及 API Key 是必備設定值,程式範例都是用 Environment.GetEnvironmentVariable() 取值,若不修改寫法,需要用 setx 指定設定、用 set 指令查詢,不夠直覺方便,於是我想到能不能比照其他程式用 .env 將專案相關設定集中管理,好改也好查。

要在 .NET 使用 .env,最簡單的做法是用 NuGet 安裝 DotNetEnv 程式庫 (dotnet package add DotNetEnv),在程式一開始呼叫 DotNetEnv.Env.Load();,DotNetEnv 將自動載入並解析同目錄下的 .env,之後依原本做法 System.Environment.GetEnvironmentVariable("Port"); 取值即可。DotNetEnv.Env.TraversePath().Load(); 會一路往父目錄向上找 .env,方便多專案共用;另外也可指定 .env 路徑用 DotNetEnv.Env.Load("./path/to/.env"); 載入。

使用 .env 的一個重要注意事項是不可以 Commit 丟進版控,以免全天下跟你一起共用帳號密碼 API Key,類以的裸奔案例屢見不鮮,.NET 專案用 dotnet new gitignore 產生的 .gitignore,開宗名義第一條就是 .env,可見這是很容易發生的高風險漏洞。由於 .env 不會附在專案裡,要告知開發者如何設定,可放個 .env.example,列舉程式用到的設定項目,值的部分填說明或範例。

Introduces using .env files in .NET to manage configuration via environment variables. Demonstrates DotNetEnv for loading .env, compares with other languages, and highlights best practices like avoiding commits and using .env.example.


Comments

Be the first to post a comment

Post a comment