İçeriğe geç
Can Uğurlu
Geri dön

.env dosyasını sunucuya elle kopyalamayı bırakın

scp ile .env dosyasını sunucuya elle taşımak konfigürasyon yönetimi değil. Hangi değerin şu an production’da çalıştığını kimse bilmiyor, dosya hiçbir yerde versiyonlanmıyor, sunucu silinince dosya da onunla gidiyor.

Elle kopyalamanın kırdığı şey

Üç sunucu varsa üç ayrı .env dosyası var demektir. Biri güncellenip diğer ikisi unutulunca hangi sunucunun hangi değeri kullandığı bir tahmin işine dönüşür. Bir değişkeni değiştirmek için sunucuya bağlanıp dosyayı elle düzenlemek gerekiyorsa, o değer aslında yönetilmiyor demektir.

Git geçmişi yok, diff yok, “kim ne zaman değiştirdi” sorusuna cevap yok. Sızıntı olduğunda ilk soru “bu değer ne zamandır böyleydi” oluyor ve kimse bilmiyor.

Platform değişkeni enjekte etsin

Değeri platforma bırakın. Coolify, Docker Compose ya da systemd, hepsi ortam değişkenini süreç başlarken enjekte edebiliyor.

Coolify’da bu, uygulamanın Environment Variables sekmesinde tutuluyor ve container her başladığında ortama yazılıyor. Bu blogu Coolify’da nasıl kurduğumu bu blogu neden ve nasıl kurdum yazısında anlattım. Docker Compose’da environment anahtarı aynı işi görüyor:

services:
  app:
    image: registrydeki-imaj
    environment:
      APP_KEY: ${APP_KEY}
      DB_PASSWORD: ${DB_PASSWORD}

systemd’de aynı şey EnvironmentFile ile yapılıyor:

[Service]
EnvironmentFile=/etc/myapp/app.env
ExecStart=/usr/bin/myapp

Fark şu: değer artık dosya sistemine elle scp’lenen bir şey değil, platformun bir parçası. Yeni bir sunucuya taşınırken kopyalanacak dosya değil, girilecek bir arayüz var.

.env.example her key’i listeler, değer içermez

Commit’lenen tek dosya .env.example. İçinde her key var, değer yok:

APP_KEY=
DB_PASSWORD=
STRIPE_SECRET=

Yeni bir geliştirici ya da yeni bir sunucu kurulumu bu dosyayı okuyup hangi değişkenlerin gerekli olduğunu görüyor, tahmin etmiyor.

Eksik key’de sessizce varsayılana düşmeyin

Başlangıçta zorunlu değişkenleri kontrol edin, eksikse süreç başlamasın:

foreach (['APP_KEY', 'DB_PASSWORD', 'STRIPE_SECRET'] as $key) {
    if (empty(env($key))) {
        throw new RuntimeException("Eksik ortam değişkeni: {$key}");
    }
}

Eksik key’de null ya da boş string’e düşen kod, yanlış yapılandırmayı prod’da sessizce çalıştırır. Hata üç hafta sonra, farklı bir belirtiyle çıkar.

Build-time ile runtime’ı karıştırmayın

Bir statik sitede bir değer build sırasında HTML’e gömülüyorsa, o değeri değiştirip container’ı yeniden başlatmak hiçbir şeyi değiştirmez. Değer zaten dosyaya yazılmış durumda. Gerekli olan yeniden başlatma değil, yeniden build. Bu ayrım Docker imajınız neden 1,2 GB yazısındaki build/runtime katman ayrımıyla aynı yerden geliyor.

“Değeri değiştirdim ama hiçbir şey olmadı” şikayetinin sebebi neredeyse hep bu ayrımı atlamak. Runtime değişkeni, süreç her başladığında okunan DB_PASSWORD gibi bir değer, restart ister. Build-time değişkeni, bundle’a gömülen değer, rebuild ister.

CI’da secret nasıl geçer

GitHub Actions gibi bir CI kullanıyorsanız secret’lar repo ayarlarında tutulur, workflow dosyasına asla değer olarak yazılmaz:

jobs:
  deploy:
    steps:
      - name: Build
        env:
          APP_KEY: ${{ secrets.APP_KEY }}
        run: pnpm build

CI, secret’ı build adımına ortam değişkeni olarak enjekte ediyor ve log çıktısında değeri otomatik maskeliyor. Bu da aynı prensibin bir örneği: değer bir dosyada değil, platformun secret deposunda duruyor.

Sızan değeri commit’ten silmek yetmiyor

Gerçek .env asla commit’lenmez. .gitignore’a girer, girmemişse şimdi girer.

Zaten commit’lenmişse geçmişten silmek yeterli değil. Git geçmişi rewrite edilse bile fork’larda, clone’larda ve CI loglarında kopyası kalmış olabilir. Sızan her token ve şifre rotate edilir, silinen commit sızıntıyı geri almıyor. Rotate işlemi fark edildiği gün yapılır; “hafta sonuna bırakalım” diye ertelenen bir rotate, ertelendiği kadar açık bir pencere demektir.

Özet

Değeri platforma enjekte ettirin, .env.example’ı commit’leyin, eksik key’de süreç patlasın. Build-time değişkeni değiştirdiyseniz restart değil rebuild yapın. Sızan her değeri rotate edin, commit’i silmek yetmez.


Bu yazıyı paylaş:

Önceki Yazı
Lock dosyasını commit'leyin
Sonraki Yazı
LCP'yi bozan şey genelde font