Üç Uygulama Boyunca Ortam Değişkenlerini Tek Kaynaktan Yönetmek
Üç uygulama (apps/web, apps/api, apps/admin) çoğu ortam değişkenini paylaşıyor: DATABASE_URL, MINIO_*, ADMIN_API_TOKEN. Bunları üç ayrı .env dosyasında tekrar etmek yerine, tek bir kök .env dosyası var ve her uygulamanın dev script'i ona işaret ediyor:
// apps/web/package.json
"dev": "dotenv -e ../../.env -- next dev -p 3900"
dotenv-cli, süreç başlamadan önce kök .env'i process.env'e enjekte ediyor — Next.js/NestJS/Vite'ın kendi env-loading mekanizmalarına güvenmek yerine, üçü için de aynı davranışı garanti eden tek bir mekanizma.
NestJS'in kendi fallback zinciri neden hâlâ orada
// apps/api/src/app.module.ts
ConfigModule.forRoot({
isGlobal: true,
// dotenv-cli (see package.json scripts) already injects the right env file into
// process.env before this process starts. These paths are a fallback for when the
// app is launched directly (e.g. a systemd/pm2 service in prod without dotenv-cli).
envFilePath: [
`../../.env.${process.env.NODE_ENV ?? 'development'}`,
'../../.env',
`.env.${process.env.NODE_ENV ?? 'development'}`,
'.env',
],
}),
Geliştirme ortamında bu liste hiç kullanılmıyor — dotenv-cli zaten değişkenleri enjekte etmiş oluyor. Ama prod'da API'nin systemd/pm2 gibi bir process manager tarafından dotenv-cli olmadan doğrudan başlatılması ihtimaline karşı bir yedek: dört farklı yol sırayla deneniyor, ilk bulunan kullanılıyor. Kod içindeki yorum bu ayrımı açıkça not ediyor — aksi halde "zaten dotenv-cli var, bu neden burada" sorusu haklı bir kafa karışıklığı yaratırdı.
.env.production.example neden ayrı bir dosya
.env.example yerel geliştirme değerlerini gösteriyor (localhost origin'ler, local MinIO). Prod'da API_ORIGIN/ADMIN_ORIGIN gibi değerler gerçek domain'lere, NODE_ENV production'a dönüyor — iki dosyayı ayrı tutmak, "hangi değer hangi ortamda" sorusunu dosya adının kendisiyle cevaplıyor, tek bir örnek dosyada hepsini yorum satırlarıyla açıklamaya çalışmak yerine.