farkmt2official 1
farkmt2official
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Hikaye Ekle

[NODE JS] dotenv ile Konfigürasyon Yönetimi

nodejs.png


[NODE JS] dotenv ile Konfigürasyon Yönetimi​


Merhaba arkadaşlar, bir önceki konuda environment variable'ların ne olduğunu anlatmıştım. Şimdi pratikte en çok kullanılan dotenv paketini detaylıca ele alacağız. dotenv, .env dosyasındaki key-value çiftlerini process.env'e yükler ve kullanıma hazır hale getirir.

dotenv Node.js ekosisteminin en popüler paketlerinden biri, haftalık 40 milyondan fazla indirmesi var. Sıfır bağımlılık, sıfır konfigürasyon, sadece yap ve kullan mantığıyla çalışır. Projenizin kök dizinine bir .env dosyası koyarsınız, uygulamanızın en başında require('dotenv').config() çağırırsınız, bitir. Tüm değişkenler process.env üzerinden erişilebilir olur.

Ama dotenv'in bazı incelikleri var. Mesela hangi sırayla yüklenir, var olan değişkenlerin üzerine yazar mı, birden fazla .env dosyası nasıl yönetilir, production'da nasıl davranır... Bu detayları bilmezseniz beklenmedik davranışlarla karşılaşırsınız.

Ben projelerimde genelde şöyle bir yapı kurarım: .env.development, .env.test, .env.production dosyaları oluştururum. NODE_ENV'e göre doğru dosyayı yükleyen bir config modülü yazarım. Bu şekilde her ortamın konfigürasyonu ayrı ayrı yönetilir ve karışma riski olmaz.

Temel Kullanım​


JavaScript:
// Kurulum: npm install dotenv

// En basit kullanim - uygulamanin en basinda
require('dotenv').config();

// Artik .env dosyasindaki tum degiskenler process.env'de
console.log(process.env.DB_HOST);
console.log(process.env.API_KEY);

// Farkli dosya yuklemek
require('dotenv').config({ path: '.env.production' });

// Override: var olan degiskenlerin ustune yazma
require('dotenv').config({ override: true });

// Debug modu: hangi degiskenlerin yuklendigini gor
require('dotenv').config({ debug: true });

// ES Modules ile kullanim
// import 'dotenv/config';

// -----------------------------------------------
// Gelismis config modulu
// -----------------------------------------------
const path = require('path');
const dotenv = require('dotenv');

class Config {
    constructor() {
        const ortam = process.env.NODE_ENV || 'development';

        // Once genel .env dosyasini yukle
        dotenv.config({ path: path.resolve(process.cwd(), '.env') });

        // Sonra ortama ozel dosyayi yukle (ustune yazar)
        const ortamDosyasi = path.resolve(process.cwd(), '.env.' + ortam);
        dotenv.config({ path: ortamDosyasi, override: true });

        // Lokal override dosyasi (gitignore'da olmali)
        const lokalDosya = path.resolve(process.cwd(), '.env.local');
        dotenv.config({ path: lokalDosya, override: true });

        this.dogrula();
    }

    get(anahtar, varsayilan = undefined) {
        const deger = process.env[anahtar];
        if (deger === undefined && varsayilan === undefined) {
            throw new Error('Eksik environment variable: ' + anahtar);
        }
        return deger || varsayilan;
    }

    getInt(anahtar, varsayilan) {
        return parseInt(this.get(anahtar, String(varsayilan)), 10);
    }

    getBool(anahtar, varsayilan = false) {
        const deger = this.get(anahtar, String(varsayilan));
        return deger === 'true' || deger === '1';
    }

    dogrula() {
        const zorunlular = ['DB_HOST', 'DB_PASSWORD', 'JWT_SECRET'];
        const eksikler = zorunlular.filter(key => !process.env[key]);
        if (eksikler.length > 0) {
            console.error('\nEksik environment variable\'lar:');
            eksikler.forEach(key => console.error('  - ' + key));
            console.error('\n.env dosyanizi kontrol edin veya .env.example\'dan kopyalayin.\n');
            process.exit(1);
        }
    }

    get db() {
        return {
            host: this.get('DB_HOST', 'localhost'),
            port: this.getInt('DB_PORT', 5432),
            name: this.get('DB_NAME', 'myapp'),
            user: this.get('DB_USER', 'postgres'),
            password: this.get('DB_PASSWORD'),
            pool: {
                min: this.getInt('DB_POOL_MIN', 2),
                max: this.getInt('DB_POOL_MAX', 10)
            }
        };
    }

    get jwt() {
        return {
            secret: this.get('JWT_SECRET'),
            expiresIn: this.get('JWT_EXPIRES_IN', '24h'),
            refreshExpiresIn: this.get('JWT_REFRESH_EXPIRES_IN', '7d')
        };
    }

    get isProduction() {
        return this.get('NODE_ENV', 'development') === 'production';
    }
}

module.exports = new Config();

Bu Config class'ı dotenv'in üzerine tip dönüşümü, varsayılan değer ve zorunluluk kontrolü ekliyor. Projenin her yerinde config.db.host gibi kullanabilirsiniz. String'den integer veya boolean'a dönüşümü otomatik yapıyor, hata vermek yerine varsayılan değer döndürüyor.

Kullanım Örneği: Express Uygulaması​


JavaScript:
// app.js
const config = require('./config');
const express = require('express');
const mongoose = require('mongoose');

const app = express();

// MongoDB baglantisi
mongoose.connect(
    'mongodb://' + config.db.user + ':' + config.db.password + '@' + config.db.host + ':' + config.db.port + '/' + config.db.name
).then(() => {
    console.log('MongoDB baglandi');
}).catch(err => {
    console.error('MongoDB baglanti hatasi:', err.message);
    process.exit(1);
});

// JWT middleware
const jwt = require('jsonwebtoken');
function authMiddleware(req, res, next) {
    const token = req.headers.authorization;
    if (!token) return res.status(401).json({ hata: 'Token gerekli' });

    try {
        const decoded = jwt.verify(token.replace('Bearer ', ''), config.jwt.secret);
        req.user = decoded;
        next();
    } catch (e) {
        res.status(401).json({ hata: 'Gecersiz token' });
    }
}

app.get('/api/profil', authMiddleware, (req, res) => {
    res.json({ kullanici: req.user });
});

app.listen(config.getInt('PORT', 3000), () => {
    console.log('Ortam:', config.get('NODE_ENV', 'development'));
    console.log('Port:', config.getInt('PORT', 3000));
    if (!config.isProduction) {
        console.log('DB:', config.db.host + ':' + config.db.port);
    }
});

Best Practices​


dotenv kullanırken dikkat etmeniz gereken şeyler var. .env dosyasını asla git'e commit etmeyin, bunu her seferinde söylüyorum çünkü hala yapan var. .env.example dosyasını oluşturup commit edin ki yeni geliştirici hangi değişkenlere ihtiyaç olduğunu bilsin. Production'da dotenv yerine gerçek environment variable'ları tercih edin, Docker ve Kubernetes ortamlarında .env dosyası kullanmak anti-pattern sayılır.

require('dotenv').config() çağrısını mümkün olan en erken noktada yapın, herhangi bir modül import edilmeden önce. Yoksa bazı modüller environment variable'ları kendi init aşamalarında okumaya çalışır ve undefined bulur.

Kolay gelsin!
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst