Node.js Projelerinde Bakım: Adım Adım Bir Rehber
Bu yazıda, üç ayrı Node.js projesini nasıl "bakımdan geçirdiğimi" adım adım anlatıyorum: her komutu neden çalıştırdığımı, çıkan sonucu nasıl okuduğumu, ve hangi durumda "dur, burada dikkatli olmam lazım" dediğimi. Terminal komutu daha önce hiç kullanmamış biri bile takip edebilsin diye yazdım.
1. Adım: Projeniz Git'te mi?
Bakıma başlamadan önce sorulacak en temel soru bu. Git, kodunuzun her değişikliğini kaydeden bir zaman makinesi gibi düşünülebilir. Projeniz git'te değilse, sunucunuzun diski bozulduğu ya da yanlışlıkla bir dosyayı sildiğiniz an, o kod bir daha geri gelmez.
Bir klasörün git deposu olup olmadığını şöyle kontrol edersiniz:
cd benim-projem
git status
Eğer "not a git repository" gibi bir hata alıyorsanız, projeniz hiç versiyon kontrolü altında değil demektir. Şöyle başlarsınız:
git init
git add .
git commit -m "İlk sürüm"
Ama dikkat: git add . demeden önce mutlaka bir sonraki adımı (.gitignore) tamamlayın. Yoksa şifrelerinizi, gerçek müşteri verilerinizi, hatta gigabaytlarca gereksiz dosyayı yanlışlıkla kod deposuna gömebilirsiniz — ve bir kere git geçmişine giren bir şeyi tamamen silmek gerçekten zahmetlidir.
.gitignore: Neyi asla depoya almamalı?
Projenizin kök klasöründe .gitignore adında bir dosya, git'e "şunları asla takip etme" der. Bakım yaparken en çok karşıma çıkan, gitignore'a eklenmesi gereken şeyler şunlar:
node_modules/— kütüphanelerin indirildiği klasör. Devasa olabilir (yüzlerce MB) vepackage.json'dan her zaman yeniden indirilebilir, o yüzden depoda taşımaya gerek yok..env— veritabanı şifreniz, API anahtarlarınız gibi gizli bilgilerin durduğu dosya. Bunu asla git'e eklemeyin (private bir depo bile olsa).- Gerçek kullanıcı verisi içeren dosyalar — Excel çıktıları, veritabanı dökümleri, yüklenen fotoğraflar. Kod ile veri farklı şeylerdir; veri koda değil, yedeğe gider.
- Tarayıcı otomasyonu oturum klasörleri — eğer botunuz Puppeteer/Selenium gibi bir araçla tarayıcı açıyorsa, oturum bilgilerinin tutulduğu klasörler hem devasa boyuta ulaşabilir hem de içinde oturum çerezleri (şifre muadili hassas veri) barındırabilir.
- Çöküş dökümleri (
coredosyaları) — bir program çöktüğünde işletim sisteminin bıraktığı, genelde yüz megabaytları bulan dosyalar. Koda ait değiller, silinebilirler.
Örnek bir .gitignore:
node_modules/
.env
core
*.xlsx
logs/
oturum_verisi_*/
Bunu ekledikten sonra git add . çalıştırıp git status ile "hangi dosyalar işleme eklenecek" listesine bakın. Beklemediğiniz büyüklükte bir dosya ya da isim görürseniz, önce onu neden gördüğünüzü anlayın, sonra devam edin.
Kodun bir kopyası da GitHub'da dursun
Git, tek başına sadece yerel bir geçmiş tutar — sunucunun diski giderse o geçmiş de gider. Bu yüzden kodu ayrıca GitHub gibi bir yere de gönderin (push edin). Gerçek kullanıcı verisi barındırmayan ama iş mantığınızı içeren bir proje için depoyu private (özel) yapmayı unutmayın — bu sayede kod sizin kontrolünüzde kalır ama internete açık olmaz.
2. Adım: Kütüphaneleriniz Ne Kadar Eski?
Bir Node.js projesi, package.json dosyasında listelenen onlarca-yüzlerce dış kütüphaneye dayanır. Bunlar zamanla güncellenir; siz güncellemezseniz projeniz "donmuş" bir zaman diliminde kalır. Mevcut durumu görmek için:
npm outdated
Bu komut size üç sütun gösterir:
- Current — şu an kurulu olan sürüm.
- Wanted —
package.json'daki kurala göre (örn.^3.1.0) izin verilen en güncel sürüm. - Latest — paketin gerçekten en güncel sürümü (Wanted'dan büyük olabilir, çünkü bazen kural o kadar ileriye izin vermez).
Burada bilmeniz gereken bir kavram var: semver (semantic versioning). Bir sürüm numarası 4.19.2 gibi üç parçadan oluşur:
| Parça | Anlamı | Kırılma riski |
|---|---|---|
| 4.19.2 — Major | Büyük, uyumsuz değişiklikler | Yüksek — kodunuz bozulabilir |
| 4.19.2 — Minor | Yeni özellik, geriye uyumlu | Düşük |
| 4.19.2 — Patch | Hata düzeltmesi | Neredeyse yok |
Yani npm outdated çıktısında Current ile Wanted arasındaki fark küçükse (patch/minor), rahatça güncelleyebilirsiniz. Current ile Latest arasında bir major fark varsa (örneğin 4.x'ten 5.x'e), acele etmeyin — o kütüphanenin "neler değişti" (changelog) sayfasına bakmadan güncellemeyin.
Basit güncelleme
Sadece patch/minor farkları için:
npm update
Bu, package.json'daki kurallara sadık kalarak (majör sürüm atlamadan) her şeyi en güncel izin verilen sürüme çeker.
3. Adım: Güvenlik Açıklarını Bulmak
Kütüphanelerin sadece "eski" olması bir sorun değildir; asıl önemlisi içlerinde bilinen bir güvenlik açığı olup olmadığıdır. Bunu şöyle öğrenirsiniz:
npm audit
Çıktı size her açığı bir önem derecesiyle listeler: low → moderate → high → critical. En altta da bir özet görürsünüz, örneğin:
12 vulnerabilities (4 moderate, 7 high, 1 critical)
Bu rakamı görünce panik yapmayın — genelde göründüğünden çok daha az kaynağa iniyor. Detaylı, makine tarafından okunabilir hâlini görmek için:
npm audit --json
"via" ne demek? Zincirleme bağımlılık
Az önce yaşadığım gerçek bir örnekle anlatayım. Bir projede npm audit 12 açık buldu. İlk bakışta korkutucu görünüyordu: sequelize (bir veritabanı kütüphanesi), exceljs (Excel dosyası oluşturan kütüphane), connect-session-sequelize (oturum yönetimi) hepsi "açıklı" görünüyordu.
Ama detaya bakınca gerçek tablo şuydu: bu üç kütüphanenin kendisinde hiçbir sorun yoktu — hepsi zaten en güncel sürümdeydi. Sorun, bu kütüphanelerin arka planda kullandığı, çok daha küçük ve genelde fark edilmeyen dört pakette gizliydi: tar, nanoid, brace-expansion, uuid. Yani sequelize, kendi içinde eski bir uuid sürümü taşıdığı için "açıklı" görünüyordu — sequelize'in kendi kodunda bir sorun yoktu.
Bunu anlamanın yolu, her açığın via (üzerinden, aracılığıyla) alanına bakmak:
sequelize (moderate)
-> via dep: uuid
connect-session-sequelize (moderate)
-> via dep: sequelize
Bu, bir zincir gösteriyor: connect-session-sequelize → sequelize'e bağımlı → sequelize da uuid'e bağımlı → asıl sorun uuid'de. Zinciri takip ettiğinizde, kaç "açık" göründüğü değil, kaç gerçek kaynak olduğu ortaya çıkıyor. Az önceki örnekte 12 görünen açık, aslında sadece 4 kaynağa iniyordu.
"fixAvailable" alanına dikkat — kör kör güncellemeyin
npm audit her açık için bir "düzeltme mevcut mu" bilgisi de verir. İki türü var:
tar | critical | fixAvailable: true
puppeteer | high | fixAvailable: {"name":"puppeteer","version":"19.8.0","isSemVerMajor":true}
Birinci örnekte fixAvailable: true — bu, "majör sürüm değiştirmeden, package.json kurallarına sadık kalarak güvenle düzeltebilirim" demek. İkincisinde ise bir obje var ve içinde "isSemVerMajor":true yazıyor — bu da "düzeltmek için bu paketi başka bir majör sürüme geçirmem lazım" demek.
Burada durup düşünün. npm bazen "düzeltme" olarak paketi ileri değil geriye götürmenizi önerir — çünkü kendi bağımlılık çözücüsü, "hiç açık kalmasın" diye bazen paketi eskiye, açığın henüz eklenmediği bir sürüme çekmeyi tercih eder. Gerçek bir örnekte npm banasequelize'i güncel 6.x sürümünden 3.x'e (yıllar öncesine) düşürmemi önerdi. Bunu kör kör kabul etseydim, tüm veritabanı kodum çalışmaz hâle gelirdi.npm audit fix --forcekomutu tam olarak bunu yapar — sormadan, "en kolay" çözümü uygular. Production'da asla ilk elden kullanmayın.
4. Adım: Güvenli Bir Şekilde Düzeltme
İşte gerçekte izlediğim, güvenli sıra:
Önce, force'suz dene
npm audit fix
Bu, sadece fixAvailable: true olan (majör değiştirmeyen) açıkları düzeltir. Genelde açık sayınızı ciddi oranda azaltır, hiçbir şeyi kırma riski neredeyse sıfırdır.
Kalanlar için: "overrides" ile hedefli müdahale
Yukarıdaki uuid örneğine dönelim. sequelize zaten en güncel sürümdeydi ama içinde hâlâ eski bir uuid taşıyordu ve npm bunu "düzeltmek" için sequelize'i düşürmemi öneriyordu. Bunun yerine package.json'a şunu ekledim:
{
"overrides": {
"uuid": "^11.1.1"
}
}
Bu satır npm'e şunu söyler: "Kim uuid isterse istesin, ona en az 11.1.1 sürümünü ver — package.json'da öyle yazmasa bile." npm install çalıştırdığınızda bu, tüm bağımlılık ağacında zorla uygulanır. uuid gibi API'si çok stabil, basit paketlerde bu genelde güvenlidir (temel fonksiyonlar sürümler arası neredeyse hiç değişmez). Karmaşık, çok özellikli bir pakette (örneğin bir web framework'ünde) aynı şeyi yapmadan önce daha dikkatli olun.
Gerçekten düzeltmesi olmayan açıklar da var
Bazen karşınıza çıkan açığın hiçbir güncel çözümü olmadığını görürsünüz. Bunu anlamanın yolu basit — paketin gerçekten en güncel sürümünün ne olduğuna bakmak:
npm view paket-adi version
Eğer bu komutun döndürdüğü sürüm, sizde zaten kurulu olan sürümle aynıysa — yani "en güncel" dediği paket zaten elinizdeki paketse — o açığın gerçekten upstream'de (paketi yazan kişide) henüz bir çözümü yok demektir. Bu durumda iki seçeneğiniz var:
- Alternatif bir pakete geçmek (varsa ve geçiş maliyeti makulse).
- Riski bilinçli olarak kabul etmek — ama bunu sessizce değil, gerekçesiyle not ederek yapın: bu açık ne işlemiyor, gerçekte kimden gelen veriyi işliyor, kötüye kullanılma ihtimali ne kadar gerçekçi?
Örneğin bir projede extract-zip paketinde çözümsüz bir "sembolik link" açığı buldum. Ama bu paket sadece kendi sunucumun, güvendiğim bir kaynaktan (tarayıcı yazılımının resmi indirme adresinden) indirdiği bir dosyayı açmak için kullanılıyordu — dışarıdan, bir kullanıcının yüklediği bir dosyayı değil. Yani gerçek saldırı yüzeyi çok dardı. Bunu riski kabul edip ilerleyerek not aldım; eğer aynı paket kullanıcıdan gelen dosyaları açıyor olsaydı, karar tamamen farklı olurdu.
5. Adım: Değiştirdikten Sonra Doğrulayın — "Dua Etmeyin"
Bir bağımlılığı güncelledikten sonra iş bitmiyor. Şunları yapmadan "tamamdır" demeyin:
-
Söz dizimi kontrolü. Dosyada bariz bir yazım hatası var mı, hızlıca bakın:
node --check src/server.js -
Uygulamayı yeniden başlatın. Sunucunuzda uygulamaları pm2 gibi bir "process manager" ile çalıştırıyorsanız:
pm2 restart uygulama-adi -
Hata loglarına bakın. Yeniden başlattıktan hemen sonra:
Burada veritabanı bağlantı hatası, "bulunamadı" hatası gibi bir şey görürseniz, güncelleme bir şeyi kırmış demektir.pm2 logs uygulama-adi --err --lines 30 -
Gerçek bir işlemi deneyin. Uygulamanızda bir sayfayı açın, bir formu gönderin, bir kaydı kaydedin — "çalışıyor" demeden önce gerçekten çalıştığını görün. Loglarda
"Veritabanı bağlantısı başarılı"gibi olumlu bir satır ya da gerçek bir isteğin (200 OK) geçtiğini görmek, en güvenilir kanıttır.
İpucu: Değişiklik yapmadan hemen öncepackage.jsonvepackage-lock.json'un bir kopyasını alın (cp package.json package.json.yedek). Bir şeyler ters giderse eski hâline dönmek saniyeler sürer. Zaten git kullanıyorsanız bu adım gereksiz —git checkout -- package.json package-lock.jsonaynı işi görür.
6. Adım: Loglarınız Diskinizi Doldurmasın
Uzun süre çalışan bir sunucu, sürekli log (kayıt) dosyası üretir. Bunlara dokunmazsanız bir gün diskiniz dolar ve tüm sunucu çöker. pm2 kullanıyorsanız, pm2-logrotate modülünü kurup şu ayarları yapmak yeterli:
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 30
Bu, her log dosyası 10MB'ı geçtiğinde otomatik olarak döndürür (eskisini sıkıştırıp yeni bir dosyaya geçer) ve en fazla 30 günlük geçmiş tutar. Kurduktan sonra unutabilirsiniz — arka planda kendi kendine çalışır.
7. Adım: Yedekleme — Git Tek Başına Yeterli Değil
Git, kodunuzu korur ama veritabanınızı korumaz. Kullanıcı kayıtları, işlem geçmişi gibi veriler ayrı bir yedekleme gerektirir. Basit bir başlangıç: sunucunuzda bir cron job (zamanlanmış görev) ile her gece veritabanının bir dökümünü almak:
# crontab -e ile açıp şu satırı eklemek, her gece 03:00'te yedek alır
0 3 * * * mysqldump -u kullanici -p'sifre' veritabani_adi > /yedekler/$(date +\%F).sql
Bu yedeklerin de sunucunun dışında bir yerde durması önemli — sunucu tamamen kaybolursa, yedek de onunla beraber gitmesin diye.
Özet: Bakım Kontrol Listesi
Elinizdeki her Node.js projesi için, ayda bir bu adımları takip edin:
- ☐ Proje git'te mi, son değişiklikler push edildi mi?
- ☐
.gitignoregüncel mi — yeni eklenen bir klasör/dosya türü var mı? - ☐
npm outdated— patch/minor farkları içinnpm update. - ☐
npm audit— kaç gerçek kaynak var, kaçında "fixAvailable: true"? - ☐ Force'suz
npm audit fixile güvenli olanları temizle. - ☐ Kalanlar için: majör sürüm gerektiren her paketi tek tek değerlendir, kör kör
--forcekullanma. - ☐ Değişiklik sonrası: syntax kontrolü, restart, log kontrolü, gerçek işlem testi.
- ☐ Log rotasyonu kurulu mu, disk dolmuyor mu?
- ☐ Veritabanı yedeği düzenli alınıyor mu, sunucu dışında bir yerde duruyor mu?
Bu adımların hiçbiri tek başına karmaşık değil — asıl beceri, hangi sonucun güvenle uygulanabileceğini, hangisinin dikkat istediğini ayırt edebilmek. Bir sonraki bakımınızda, her "majör sürüm" uyarısında durup bir nefes alın, önce ne değiştiğini okuyun, sonra karar verin.



