Node.js Uygulamasını Canlı Ortamda Yayınlama: PM2, Nginx ve Systemd ile Sürdürülebilir Mimari
Yerel makamda kusursuz çalışan bir Node.js uygulamasını üretim ortamına taşırken dikkat edilmesi gerekenler, süreç yönetimi ve ters proxy yapılandırması üzerine adım adım rehber.
Caner Serbest
Sistem ve Altyapı
4 min read
Node.js Uygulamasını Canlı Ortamda Yayınlama: PM2, Nginx e Systemd ile Sürdürülebilir Mimari
Geliştirme ortamında node app.js veya npm run dev komutlarıyla ayağa kaldırdığımız bir uygulamayı canlı (production) ortama taşımak, yazılım yaşam döngüsünün en kritik eşiklerinden biridir. Yerel makinelerde karşılaşılan hatalar genellikle anlık olarak çözülürken, canlı sistemlerde kesintisiz çalışabilirlik (high availability), güvenlik ve kaynak yönetimi ön plana çıkar.
Bu rehberde, bir Node.js uygulamasını sıfırdan kurulan bir Linux sunucuda, endüstri standardı araçlar olan PM2, Nginx ve Systemd kullanarak nasıl güvenli ve sürdürülebilir bir şekilde yayınlayacağımızı adım adım inceleyeceğiz.
1. Hazırlık ve Sunucu Ortamı
Uygulamamızı yayına almadan önce sunucumuzun güncel olduğundan ve gerekli Node.js sürümünün kurulu olduğundan emin olmalıyız. Bu rehber için Ubuntu Server kullanacağız.
Öncelikle paket listemizi güncelleyelim:
sudo apt update && sudo apt upgrade -y
Node.js kurulumu için NodeSource deposunu kullanmak en sağlıklı yöntemdir. LTS (Long Term Support) sürümünü kurmak kararlılık açısından her zaman ilk tercihimiz olmalıdır:
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
Kurulumun ardından sürüm kontrolü yaparak her şeyin yolunda gittiğini doğrulayalım:
node -v
npm -v
2. Uygulamanın Sunucuya Taşınması ve Bağımlılıklar
Uygulama kodlarımızı sunucuya genellikle Git aracılığıyla çekeriz. /var/www dizini altında projemiz için bir klasör oluşturalım ve yetkilendirmeyi yapalım:
sudo mkdir -p /var/www/my-app
sudo chown -R $USER:$USER /var/www/my-app
Proje dizinine giderek kodlarımızı klonlayalım ve bağımlılıkları yükleyelim. Canlı ortamda sadece üretim bağımlılıklarını (dependencies) kurmak, gereksiz şişmeyi önler:
cd /var/www/my-app
git clone https://github.com/kullaniciadi/proje-adi.git .
npm ci --production
Not: npm ci, package-lock.json dosyasına sadık kalarak kararlı bir kurulum sağlar ve canlı ortamlar için önerilir.
3. PM2 ile Süreç Yönetimi (Process Management)
node app.js komutuyla uygulamayı başlattığımızda, terminal kapandığında uygulama da kapanacaktır. Ayrıca uygulama hata alıp çöktüğünde (crash) otomatik olarak yeniden başlamaz. İşte bu noktada PM2 devreye girer.
PM2’yi küresel (global) olarak kuralım:
sudo npm install -g pm2
Uygulamamızı doğrudan başlatmak yerine, proje kök dizininde bir yapılandırma dosyası (ecosystem.config.js) oluşturmak uzun vadede işimizi kolaylaştırır. Bu dosya, uygulamanın kaç örnekle (instance) çalışacağını, hata loglarının nereye yazılacağını ve ortam değişkenlerini yönetmemizi sağlar.
ecosystem.config.js dosyasını oluşturalım:
module.exports = {
apps: [
{
name: 'my-app',
script: './index.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 3000
},
error_file: './logs/err.log',
out_file: './logs/out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss',
max_memory_restart: '500M'
}
]
};
Bu yapılandırmada dikkat çeken detaylar:
- instances: ‘max’: Sunucunun sahip olduğu CPU çekirdek sayısı kadar uygulama örneği çalıştırarak yük dengelemesi (load balancing) yapar.
- max_memory_restart: ‘500M’: Uygulama herhangi bir nedenle bellek sızıntısı (memory leak) yaşar ve 500 MB RAM sınırını aşarsa, PM2 uygulamayı güvenli bir şekilde yeniden başlatır.
Uygulamayı bu dosyayla başlatalım:
pm2 start ecosystem.config.js
Sunucu yeniden başladığında PM2’nin uygulamamızı otomatik olarak ayağa kaldırması için şu komutu çalıştıralım ve çıktısındaki komutu kopyalayıp terminale yapıştıralım:
pm2 startup
Son olarak mevcut durumu kaydetmek için:
pm2 save
4. Nginx ile Ters Proxy (Reverse Proxy) Yapılandırması
Node.js uygulamamız şu anda localhost:3000 adresinde çalışıyor. Ancak kullanıcıların bu uygulamaya doğrudan http://alanadiniz.com:3000 şeklinde erişmesi hem güvenlik hem de kullanıcı deneyimi açısından uygun değildir. Ayrıca 80 (HTTP) ve 443 (HTTPS) portlarını doğrudan Node.js’e açmak root yetkileri gerektirdiği için güvenlik açığı yaratabilir.
Bu sorunu çözmek için Nginx’i bir ters proxy olarak yapılandıracağız. Nginx dışarıdan gelen HTTP/HTTPS isteklerini karşılayacak ve bunları güvenli bir şekilde arka plandaki Node.js uygulamasına (localhost:3000) iletecektir.
Nginx’i kuralım:
sudo apt install -y nginx
Uygulamamız için yeni bir Nginx yapılandırma dosyası oluşturalım:
sudo nano /etc/nginx/sites-available/my-app
Dosyanın içine aşağıdaki yapılandırmayı ekleyelim (alan adınızı kendi alan adınızla değiştirmeyi unutmayın):
server {
listen 80;
server_name alanadiniz.com www.alanadiniz.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Bu yapılandırmayı aktif hale getirmek için sites-enabled dizinine bir sembolik bağ (symlink) oluşturalım:
sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
Nginx yapılandırmasında syntax hatası olup olmadığını test edelim:
sudo nginx -t
Herhangi bir hata yoksa Nginx servisçisini yeniden başlatalım:
sudo systemctl restart nginx
Artık alan adınıza girdiğinizde, Nginx isteği alacak ve arkadaki Node.js uygulamanıza yönlendirecektir.
5. Güvenlik ve SSL Sertifikası (Certbot)
Canlı bir sistemin olmazsa olmazı HTTPS protokolüdür. Let’s Encrypt ve Certbot kullanarak ücretsiz ve otomatik bir SSL sertifikası kuralım.
Certbot ve Nginx eklentisini kuralım:
sudo apt install -y certbot python3-certbot-nginx
Sertifika oluşturma ve Nginx yapılandırmasını otomatik güncelleme komutunu çalıştıralım:
sudo certbot --nginx -d alanadiniz.com -d www.alanadiniz.com
Certbot, e-posta adresinizi isteyecek ve kullanım şartlarını onaylamanızı bekleyecektir. İşlem tamamlandığında Nginx yapılandırmanız otomatik olarak HTTPS yönlendirmesini içerecek şekilde güncellenecektir.
Let’s Encrypt sertifikaları 90 günde bir yenilenmelidir. Certbot bu süreci otomatik yönetmek için bir systemd timer kurar. Durumu test etmek için şu komutu çalıştırabilirsiniz:
sudo certbot renew --dry-run
6. Güvenlik Duvarı (UFW) Yapılandırması
Sunucumuzun dış dünyaya sadece gerekli portları açması gerekir. UFW (Uncomplicated Firewall) kullanarak sadece SSH, HTTP ve HTTPS trafiğine izin verelim:
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
Durumu kontrol etmek için:
sudo ufw status
Node.js uygulamamızın çalıştığı 3000 numaralı portu dış dünyaya kapatmış olduk; çünkü artık dış dünya doğrudan Node.js ile değil, sadece Nginx ile konuşuyor. Node.js ise yerel ağda (localhost) güvenli bir şekilde çalışmaya devam ediyor.
Sonuç
Bu rehberde, bir Node.js uygulamasını geliştirme ortamından çıkarıp, canlı ve kurumsal standartlara uygun bir üretim ortamına nasıl taşıyacağımızı ele aldık. PM2 ile süreç sürekliliğini sağlarken, Nginx ile ters proxy mimarisini kurduk ve Certbot ile şifrelenmiş güvenli bir iletişim katmanı oluşturduk.
Bu katmanları doğru yapılandırmak, uygulamanızın ölçeklenebilirliğini artırır, olası çökme senaryolarında sistemin kendi kendini onarmasına olanak tanır ve en önemlisi son kullanıcılarınıza güvenli bir deneyim sunar.
Bu yazı Gemini ile otomatik oluşturulmuştur.