Nginx Kurulum ve Temel Yapılandırma Rehberi

Web sunucu dünyasında Nginx, son yıllarda Apache’nin tahtını ciddi şekilde sarsmayı başardı. Yüksek eşzamanlı bağlantıları düşük bellek tüketimiyle yönetebilme yeteneği, onu özellikle yoğun trafikli siteler için vazgeçilmez kıldı. Bu rehberde sıfırdan Nginx kurulumu yapacak, temel yapılandırma dosyalarını anlayacak ve gerçek dünyada karşılaşacağınız senaryolara hazırlanacaksınız.

Nginx Nedir ve Neden Tercih Edilmeli?

Nginx (okunuşu: “engine-x”), Igor Sysoev tarafından 2002 yılında C10K problemini çözmek amacıyla geliştirildi. C10K, tek bir sunucunun aynı anda 10.000 bağlantıyı yönetmesi problemidir. Apache’nin her bağlantı için yeni bir süreç veya thread oluşturması yerine, Nginx event-driven (olay tabanlı) mimari kullanarak çok daha az kaynakla bu hedefi aşıyor.

Pratik açıdan baktığımızda:

  • Düşük bellek tüketimi: Aynı yük altında Apache’ye göre belirgin şekilde az RAM kullanır
  • Yüksek eşzamanlılık: Binlerce eşzamanlı bağlantıyı tek bir worker process ile yönetebilir
  • Reverse proxy yetenekleri: Node.js, Python, PHP uygulamalarının önüne kolayca konumlandırılabilir
  • Statik dosya sunumu: Statik içerik servisinde son derece hızlıdır
  • Load balancing: Dahili load balancer ile ek yazılıma gerek kalmaz
  • SSL/TLS termination: HTTPS yönetimi merkezi olarak yapılabilir

Kurulum

Ubuntu/Debian Sistemlerde Kurulum

Ubuntu ve Debian tabanlı dağıtımlarda Nginx’i iki şekilde kurabilirsiniz: dağıtımın kendi deposundan veya Nginx’in resmi deposundan. Resmi depo her zaman daha güncel sürüm sunar, bu yüzden production ortamlar için önerilir.

# Sistem güncellemesi
sudo apt update && sudo apt upgrade -y

# Gerekli bağımlılıkları kur
sudo apt install -y curl gnupg2 ca-certificates lsb-release

# Nginx resmi GPG anahtarını ekle
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor 
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# Nginx stable deposunu ekle
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] 
http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" 
    | sudo tee /etc/apt/sources.list.d/nginx.list

# Paket listesini güncelle ve kur
sudo apt update
sudo apt install -y nginx

# Servisi başlat ve otomatik başlatmayı etkinleştir
sudo systemctl start nginx
sudo systemctl enable nginx

CentOS/RHEL/Rocky Linux Sistemlerde Kurulum

# EPEL deposunu ekle (gerekiyorsa)
sudo dnf install -y epel-release

# Nginx resmi repo dosyasını oluştur
sudo tee /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

# Kurulum
sudo dnf install -y nginx

# Servisi başlat
sudo systemctl start nginx
sudo systemctl enable nginx

# Firewall kurallarını ayarla
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Kurulumun başarılı olduğunu doğrulamak için:

# Nginx sürümünü kontrol et
nginx -v

# Servis durumunu kontrol et
sudo systemctl status nginx

# Hangi portu dinlediğini görüntüle
sudo ss -tlnp | grep nginx

Tarayıcınızdan sunucunuzun IP adresine gittiğinizde “Welcome to nginx!” sayfasını görüyorsanız kurulum başarılıdır.

Dizin Yapısını Anlamak

Nginx’i yönetmeden önce dosya yapısını kavramak gerekiyor. Bu yapı dağıtıma göre küçük farklılıklar gösterse de genel mantık aynıdır.

/etc/nginx/
├── nginx.conf          # Ana yapılandırma dosyası
├── conf.d/             # Ek yapılandırma dosyaları (.conf uzantılı)
├── sites-available/    # Tanımlanmış sanal hostlar (Debian/Ubuntu)
├── sites-enabled/      # Aktif sanal hostlar (symlink)
├── snippets/           # Yeniden kullanılabilir yapılandırma parçaları
├── mime.types          # MIME türleri tanımları
└── fastcgi_params      # FastCGI parametreleri

Debian/Ubuntu sistemlerde sites-available ve sites-enabled dizinleri vardır. CentOS/RHEL’de ise genellikle her şey conf.d/ altında toplanır. İkisi de aynı mantıkla çalışır.

Ana Yapılandırma Dosyası: nginx.conf

/etc/nginx/nginx.conf dosyasını bir metin editörüyle açtığınızda üç ana blok görürsünüz: events, http ve içinde server blokları.

# /etc/nginx/nginx.conf - Optimize edilmiş temel yapılandırma

user nginx;

# CPU çekirdeği sayısı kadar worker process
worker_processes auto;

# Hata loglarının konumu ve seviyesi
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    # Her worker için maksimum eşzamanlı bağlantı
    worker_connections 1024;
    
    # Linux'ta en verimli I/O yöntemi
    use epoll;
    
    # Birden fazla bağlantıyı aynı anda kabul et
    multi_accept on;
}

http {
    # MIME türlerini dahil et
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # Log formatı
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    # Performans ayarları
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Güvenlik: Nginx sürümünü gizle
    server_tokens off;

    # Gzip sıkıştırma
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml application/json 
               application/javascript application/xml+rss;

    # Sanal host yapılandırmalarını dahil et
    include /etc/nginx/conf.d/*.conf;
}

Önemli direktifleri inceleyelim:

  • worker_processes auto: Sistemdeki CPU çekirdeği sayısını otomatik algılar
  • worker_connections: Her worker process’in aynı anda yönetebileceği bağlantı sayısı
  • sendfile on: Dosyaları kernel space’de aktarır, CPU kullanımını düşürür
  • keepalive_timeout: Bağlantının açık kalacağı süre (saniye)
  • server_tokens off: HTTP response header’larında Nginx sürümünü gizler

Temel Server Block Yapılandırması

Server block, Apache’deki VirtualHost direktifinin Nginx karşılığıdır. Her domain veya subdomain için ayrı bir server block oluşturursunuz.

# /etc/nginx/conf.d/example.com.conf

server {
    listen 80;
    listen [::]:80;  # IPv6 desteği
    
    server_name example.com www.example.com;
    
    # Web kökü dizini
    root /var/www/example.com/html;
    index index.html index.htm;
    
    # Erişim ve hata logları
    access_log /var/log/nginx/example.com.access.log main;
    error_log /var/log/nginx/example.com.error.log warn;
    
    # Temel location bloğu
    location / {
        try_files $uri $uri/ =404;
    }
    
    # Statik dosyalar için cache ayarı
    location ~* .(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
        access_log off;
    }
    
    # Gizli dosyalara erişimi engelle
    location ~ /. {
        deny all;
        access_log off;
        log_not_found off;
    }
}

Yapılandırmayı test ettikten sonra servisi yeniden yükleyin:

# Yapılandırma dosyasını sözdizimi açısından kontrol et
sudo nginx -t

# Hata yoksa servisi yeniden yükle (downtime olmadan)
sudo systemctl reload nginx

nginx -t komutu production ortamda altın değerindedir. Servisi yeniden başlatmadan önce her zaman bu kontrolü yapın.

PHP Uygulamaları için FastCGI Yapılandırması

WordPress, Laravel veya benzeri PHP uygulamaları çalıştıracaksanız PHP-FPM ile entegrasyon şarttır.

# PHP-FPM kurulumu (Ubuntu örneği, PHP 8.2)
sudo apt install -y php8.2-fpm php8.2-mysql php8.2-xml php8.2-mbstring php8.2-curl

# PHP-FPM servisini başlat
sudo systemctl start php8.2-fpm
sudo systemctl enable php8.2-fpm
# /etc/nginx/conf.d/wordpress.example.com.conf

server {
    listen 80;
    server_name wordpress.example.com;
    
    root /var/www/wordpress;
    index index.php index.html;
    
    access_log /var/log/nginx/wordpress.access.log;
    error_log /var/log/nginx/wordpress.error.log;
    
    # WordPress permalink yapısı için
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    # PHP dosyalarını PHP-FPM'e ilet
    location ~ .php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        
        # Timeout ayarları
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
    }
    
    # WordPress güvenlik ayarları
    location = /wp-login.php {
        # Brute force koruması için rate limiting
        limit_req zone=login burst=3 nodelay;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    # Hassas dosyalara erişimi engelle
    location ~* /(wp-config.php|.htaccess|readme.html|license.txt) {
        deny all;
    }
}

Reverse Proxy Yapılandırması

Nginx’in en yaygın kullanım senaryolarından biri, Node.js veya Python/Gunicorn uygulamalarının önüne reverse proxy olarak konumlandırılmasıdır.

# /etc/nginx/conf.d/nodeapp.example.com.conf
# 3000 portunda çalışan bir Node.js uygulaması için

upstream nodejs_backend {
    server 127.0.0.1:3000;
    # Birden fazla instance için:
    # server 127.0.0.1:3001;
    # server 127.0.0.1:3002;
    keepalive 32;
}

server {
    listen 80;
    server_name app.example.com;
    
    # İstemci maksimum yükleme boyutu
    client_max_body_size 10M;
    
    location / {
        proxy_pass http://nodejs_backend;
        
        # Gerekli header'ları ilet
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # WebSocket desteği
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Timeout ayarları
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # Buffer ayarları
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }
    
    # Statik dosyalar Nginx'ten servis edilsin
    location /static/ {
        alias /var/www/nodeapp/static/;
        expires 7d;
    }
}

SSL/TLS ile HTTPS Yapılandırması

Günümüzde HTTP üzerinden servis vermek kabul edilemez. Let’s Encrypt ile ücretsiz SSL sertifikası alıp yapılandıralım.

# Certbot kurulumu
sudo apt install -y certbot python3-certbot-nginx

# Sertifika al ve Nginx'i otomatik yapılandır
sudo certbot --nginx -d example.com -d www.example.com

# Otomatik yenilemeyi test et
sudo certbot renew --dry-run

Certbot her şeyi otomatik yapılandırsa da neyin eklendiğini anlamak için manuel HTTPS yapılandırmasını da bilmekte fayda var:

# HTTP'den HTTPS'e yönlendirme
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    
    # ACME challenge için istisna
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    
    # Diğer tüm trafiği HTTPS'e yönlendir
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;
    
    root /var/www/example.com/html;
    index index.html;
    
    # SSL sertifika dosyaları
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # Modern SSL yapılandırması (Mozilla SSL Config Generator'dan)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    
    # SSL session cache
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    
    # HSTS - tarayıcıya her zaman HTTPS kullanmasını söyle
    add_header Strict-Transport-Security "max-age=63072000" always;
    
    # Diğer güvenlik header'ları
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    
    location / {
        try_files $uri $uri/ =404;
    }
}

Rate Limiting ile Güvenlik

Brute force saldırıları ve API kötüye kullanımına karşı rate limiting kritik bir savunma katmanıdır.

# nginx.conf içindeki http bloğuna ekle
http {
    # Login endpointi için: dakikada 5 istek
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    
    # Genel API için: saniyede 30 istek
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
    
    # Bağlantı limiti
    limit_conn_zone $binary_remote_addr zone=addr:10m;
}

# Server bloğu içinde kullanımı
server {
    location /api/ {
        limit_req zone=api burst=50 nodelay;
        limit_conn addr 10;
        proxy_pass http://backend;
    }
    
    location /login {
        limit_req zone=login burst=5;
        # 429 Too Many Requests döndür
        limit_req_status 429;
        proxy_pass http://backend;
    }
}

Yaygın Sorunlar ve Çözümleri

502 Bad Gateway Hatası

PHP-FPM veya backend uygulama çalışmıyorsa bu hatayla karşılaşırsınız.

# PHP-FPM durumunu kontrol et
sudo systemctl status php8.2-fpm

# Socket dosyasının varlığını doğrula
ls -la /var/run/php/php8.2-fpm.sock

# Nginx hata logunu incele
sudo tail -f /var/log/nginx/error.log

# PHP-FPM logunu incele
sudo tail -f /var/log/php8.2-fpm.log

403 Forbidden Hatası

Genellikle dosya izinleri veya SELinux/AppArmor sorunundan kaynaklanır.

# Nginx kullanıcısını öğren
ps aux | grep nginx | grep worker

# Web dizini izinlerini düzenle
sudo chown -R nginx:nginx /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} ;
sudo find /var/www/example.com -type f -exec chmod 644 {} ;

# SELinux aktifse (CentOS/RHEL)
sudo chcon -Rt httpd_sys_content_t /var/www/example.com
sudo setsebool -P httpd_can_network_connect 1

Yapılandırma Değişikliklerini Uygulamak

# Sözdizimi kontrolü her zaman önce
sudo nginx -t

# Sıfırdan yükleme (kısa downtime)
sudo systemctl restart nginx

# Canlı yeniden yükleme (downtime yok, production için tercih edilmeli)
sudo systemctl reload nginx

# Nginx process'lerine sinyal gönder
sudo nginx -s reload    # Yapılandırmayı yeniden yükle
sudo nginx -s reopen    # Log dosyalarını yeniden aç
sudo nginx -s quit      # Mevcut istekleri tamamlayıp dur

Log Analizi

Nginx logları sorun tespitinde birincil kaynağınızdır.

# En çok istek gelen IP'leri listele
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# HTTP durum kodlarına göre istatistik
sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# En çok istenen URL'leri bul
sudo awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# Son 1 saatin hata loglarını izle
sudo journalctl -u nginx --since "1 hour ago"

Performans Optimizasyonu: Gerçek Dünya Senaryosu

Bir e-ticaret sitesi yönettiğinizi ve ani trafik artışlarıyla başa çıkmanız gerektiğini düşünün. Aşağıdaki ayarlar bu tür ortamlar için kanıtlanmış bir temel oluşturur:

# /etc/nginx/conf.d/ecommerce.conf - Yüksek trafik optimizasyonu

# Upstream tanımı - birden fazla uygulama sunucusu
upstream app_servers {
    least_conn;  # En az bağlantılı sunucuya yönlendir
    server 10.0.0.10:8080 weight=3;
    server 10.0.0.11:8080 weight=2;
    server 10.0.0.12:8080 backup;  # Diğerleri çökerse devreye girer
    keepalive 64;
}

server {
    listen 443 ssl http2;
    server_name shop.example.com;
    
    # Büyük dosya yüklemeleri için (ürün fotoğrafları vb.)
    client_max_body_size 20M;
    client_body_buffer_size 128k;
    
    # Proxy buffer optimizasyonu
    proxy_buffer_size 4k;
    proxy_buffers 16 4k;
    proxy_busy_buffers_size 8k;
    
    # Mikro önbellek - 1 saniyelik cache bile yüksek trafikte büyük fark yaratır
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=microcache:10m max_size=1g;
    
    location / {
        proxy_pass http://app_servers;
        proxy_cache microcache;
        proxy_cache_valid 200 1s;
        proxy_cache_use_stale error timeout updating;
        add_header X-Cache-Status $upstream_cache_status;
    }
    
    # Sepet ve ödeme sayfaları cache'lenmesin
    location ~* ^/(cart|checkout|account) {
        proxy_pass http://app_servers;
        proxy_no_cache 1;
        proxy_cache_bypass 1;
    }
}

Sonuç

Nginx’i kurmak birkaç komutla halledilen kolay bir iş, ama onu gerçekten iyi yapılandırmak deneyim ve ortama özgü kararlar gerektiriyor. Bu rehberde temel kurulumdan PHP-FPM entegrasyonuna, reverse proxy’den SSL yapılandırmasına kadar gerçek projelerinizde ihtiyaç duyacağınız konuları ele aldık.

Production ortamında dikkat etmeniz gereken birkaç kritik nokta:

  • Her yapılandırma değişikliğinden önce mutlaka nginx -t çalıştırın
  • Log dosyalarını düzenli olarak izleyin, anormal pattern’ları erken fark edin
  • SSL sertifikalarının yenilenmesini otomatikleştirin, süresi dolan sertifika felakete yol açar
  • Rate limiting’i ihmal etmeyin, saldırı altındaki bir sunucuyu kurtarmak kurulu bir korumadan çok daha zordur
  • server_tokens off her zaman açık olsun, gereksiz bilgi vermeyin

Nginx’in derinliklerine indikçe load balancing algoritmaları, gelişmiş caching stratejileri ve stream modülüyle TCP/UDP proxy gibi konularla karşılaşacaksınız. Ama sağlam bir temel olmadan o ileri konular havada kalır. Bu rehberdeki yapılandırmaları kendi test ortamınızda uygulayın, log’ları okumayı alışkanlık haline getirin ve zamanla Nginx sizin için siyah bir kutu olmaktan çıkacak.

Yorum yapın