Nginx yapılandırması büyüdükçe tek bir nginx.conf dosyasını yönetmek kabus haline gelir. Yüzlerce satırlık bir yapılandırma dosyasında bir şey aramak, değiştirmek ya da sorun gidermek gerçekten sinir bozucudur. İşte tam bu noktada include direktifi devreye girer ve her şeyi değiştirir. Bu yazıda Nginx’in include direktifini kullanarak yapılandırmanızı nasıl modüler, okunabilir ve yönetilebilir hale getirebileceğinizi gerçek dünya senaryolarıyla anlatacağım.
include Direktifi Nedir ve Neden Önemlidir?
include direktifi, bir yapılandırma dosyasının içine başka bir dosyanın ya da dosya grubunun içeriğini dahil etmenizi sağlar. Kavramsal olarak programlamadaki import ya da require ifadelerine benzer. Nginx bu direktifi işlerken adeta “şu dosyayı al, tam buraya yapıştır” mantığıyla çalışır.
Neden bu kadar önemli?
- Büyük yapılandırmaları mantıksal parçalara bölebilirsiniz
- Farklı ekip üyeleri farklı dosyalar üzerinde çalışabilir
- Ortak ayarları tek bir yerde tutup her yerden kullanabilirsiniz
- Hata ayıklama çok daha kolay hale gelir
- Bir virtual host’u devre dışı bırakmak için tek bir symlink silmek yeterli olur
Nginx’i kaynak koddan derlemiş olsanız da paket yöneticisiyle kurmuş olsanız da include direktifi her zaman kullanılabilir, herhangi bir ek modül gerektirmez.
Temel Syntax
include direktifinin kullanımı son derece basittir:
# Tek bir dosyayı dahil etmek
include /etc/nginx/mime.types;
# Glob pattern ile birden fazla dosyayı dahil etmek
include /etc/nginx/conf.d/*.conf;
# nginx.conf'a göre göreli yol kullanmak
include sites-enabled/*;
Glob pattern kullanırken dikkat etmeniz gereken bir nokta var: Eşleşen dosya yoksa Nginx hata verir. Bunu önlemek için dosya adlarınızı tutarlı tutun ya da her zaman en az bir dosyanın mevcut olduğundan emin olun.
Varsayılan Nginx Yapılandırma Yapısı
Ubuntu/Debian tabanlı sistemlerde Nginx kurulduğunda zaten bir include mantığı vardır. Bunu anlamak, kendi modüler yapınızı kurmanın başlangıç noktasıdır:
# /etc/nginx/nginx.conf içindeki varsayılan include satırları
http {
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Bu yapıda sites-available dizininde tanımladığınız virtual host’ları sites-enabled dizinine sembolik link oluşturarak aktifleştirirsiniz. Bu aslında include direktifinin en klasik kullanım örneğidir.
CentOS/RHEL tabanlı sistemlerde ise durum biraz farklıdır, sadece conf.d/*.conf pattern’i kullanılır. İkisi arasında geçiş yapıyorsanız bu farkın farkında olun.
Gerçek Dünya Senaryosu: Büyük Bir Web Sunucusu Yapılandırması
Diyelim ki 10 farklı domain’i, 3 farklı uygulama sunucusunu ve çeşitli SSL sertifikalarını yöneten bir web sunucusunuz var. Tek dosyada yönetmek yerine şu yapıyı kuralım:
/etc/nginx/
├── nginx.conf # Ana yapılandırma
├── mime.types # MIME type tanımları
├── conf.d/
│ ├── gzip.conf # Sıkıştırma ayarları
│ ├── ssl-params.conf # Ortak SSL parametreleri
│ ├── security-headers.conf # Güvenlik başlıkları
│ └── proxy-params.conf # Proxy ayarları
├── sites-available/
│ ├── example.com.conf
│ ├── api.example.com.conf
│ └── static.example.com.conf
└── sites-enabled/
├── example.com.conf -> ../sites-available/example.com.conf
└── api.example.com.conf -> ../sites-available/api.example.com.conf
Bu yapıyı oluşturalım:
# Dizinleri oluştur
sudo mkdir -p /etc/nginx/conf.d
sudo mkdir -p /etc/nginx/sites-available
sudo mkdir -p /etc/nginx/sites-enabled
# Ana nginx.conf'u düzenle
sudo nano /etc/nginx/nginx.conf
Ana nginx.conf Yapılandırması
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
}
http {
# Temel ayarlar
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# MIME types
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Loglama
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Modüler yapılandırma dosyaları
include /etc/nginx/conf.d/*.conf;
# Virtual hostlar
include /etc/nginx/sites-enabled/*;
}
Dikkat edin, nginx.conf çok sade. Asıl iş conf.d altındaki dosyalara yüklenmiş durumda.
Ortak Modüllerin Oluşturulması
Gzip Sıkıştırma Modülü
# /etc/nginx/conf.d/gzip.conf
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json
image/svg+xml;
gzip_min_length 1024;
gzip_disable "msie6";
SSL Parametreleri Modülü
# /etc/nginx/conf.d/ssl-params.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
Güvenlik Başlıkları Modülü
# /etc/nginx/conf.d/security-headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Proxy Parametreleri Modülü
# /etc/nginx/conf.d/proxy-params.conf
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 90;
proxy_connect_timeout 90;
Virtual Host Yapılandırmasında include Kullanımı
Şimdi bu modülleri bir virtual host içinde nasıl kullanacağımızı görelim. Hem http context’inde tanımladığımız global ayarlar hem de server bloğu içinde kullanacağımız include direktifleri farklı çalışır.
# /etc/nginx/sites-available/example.com.conf
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.php;
# SSL sertifikaları
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Ortak SSL ayarlarını dahil et
include /etc/nginx/conf.d/ssl-params.conf;
# Güvenlik başlıklarını dahil et
include /etc/nginx/conf.d/security-headers.conf;
# Location blokları
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
# Statik dosyalar için cache
location ~* .(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
access_log /var/log/nginx/example.com-access.log;
error_log /var/log/nginx/example.com-error.log;
}
Buradaki kritik nokta şu: ssl-params.conf ve security-headers.conf dosyalarını her virtual host için ayrı ayrı yazmak yerine tek bir yerden include ediyoruz. Yarın SSL protokol ayarını değiştirmeniz gerekirse sadece bir dosyayı düzenlemeniz yeterli.
Snippets Kullanımı ile İleri Seviye Modülerlik
Ubuntu/Debian sistemlerinde /etc/nginx/snippets/ dizini bu iş için özel olarak ayrılmıştır. Küçük, tekrar kullanılabilir yapılandırma parçaları burada yaşar.
# /etc/nginx/snippets/rate-limiting.conf
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=3r/m;
limit_conn_zone $binary_remote_addr zone=addr:10m;
# /etc/nginx/snippets/cache-control.conf
location ~* .(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
location ~* .(html|xml)$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
}
Bu snippet’leri bir API sunucusunda kullanmak için:
# /etc/nginx/sites-available/api.example.com.conf
# Rate limiting zone'larını tanımla (http context'te gerekli)
# Bu dosya sites-available altında olduğundan
# http context'e eklenmesi için conf.d altında da bir dosya gerekebilir
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
include /etc/nginx/conf.d/ssl-params.conf;
include /etc/nginx/conf.d/security-headers.conf;
include /etc/nginx/snippets/cache-control.conf;
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_conn addr 10;
# Proxy ayarlarını dahil et
include /etc/nginx/conf.d/proxy-params.conf;
proxy_pass http://127.0.0.1:3000;
}
location /auth/ {
limit_req zone=login burst=5;
include /etc/nginx/conf.d/proxy-params.conf;
proxy_pass http://127.0.0.1:3000;
}
}
Upstream Gruplarını Ayrı Dosyalarda Yönetmek
Load balancing yapıyorsanız upstream tanımlarını da ayrı dosyalara taşıyabilirsiniz. Bu özellikle dinamik olarak değişen backend’ler için çok işe yarar:
# /etc/nginx/conf.d/upstreams.conf
upstream backend_web {
least_conn;
server 10.0.0.1:8080 weight=3;
server 10.0.0.2:8080 weight=3;
server 10.0.0.3:8080 weight=1 backup;
keepalive 32;
}
upstream backend_api {
ip_hash;
server 10.0.0.4:3000;
server 10.0.0.5:3000;
server 10.0.0.6:3000;
keepalive 16;
}
upstream backend_static {
server 10.0.0.7:80;
server 10.0.0.8:80;
}
Bir backend sunucusunu geçici olarak devre dışı bırakmak istediğinizde sadece bu dosyayı düzenleyip nginx -s reload komutunu çalıştırmanız yeterli. Hiçbir virtual host dosyasına dokunmanıza gerek yok.
Virtual Host Aktifleştirme ve Devre Dışı Bırakma
sites-available ve sites-enabled pattern’ini pratikte nasıl kullanıyoruz:
# Yeni bir site eklemek
sudo ln -s /etc/nginx/sites-available/yenisite.com.conf /etc/nginx/sites-enabled/
# Yapılandırmayı test et
sudo nginx -t
# Nginx'i yeniden yükle
sudo systemctl reload nginx
# Bir siteyi geçici olarak devre dışı bırakmak
sudo rm /etc/nginx/sites-enabled/yenisite.com.conf
sudo nginx -t && sudo systemctl reload nginx
# Tekrar aktifleştirmek
sudo ln -s /etc/nginx/sites-available/yenisite.com.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Bu yaklaşımın güzelliği: sites-available altındaki orijinal dosyaya hiç dokunmadan bir siteyi kapatıp açabiliyorsunuz. Bakım penceresi sırasında bir siteyi hızlıca devre dışı bırakmak için birebir.
Ortama Göre Farklı Yapılandırma Dahil Etmek
Geliştirme, test ve prodüksiyon ortamları için farklı yapılandırmalar gerekebilir. Bunu environment-specific include dosyalarıyla çözebilirsiniz:
# /etc/nginx/conf.d/environment.conf - Production ortamı için
# Bu dosyanın içeriği ortama göre farklılaşır
# Production: Strict cache, no debug headers
proxy_cache_valid 200 1d;
proxy_cache_valid 404 1m;
# /etc/nginx/conf.d/logging.conf - Production loglama ayarları
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format json_combined escape=json
'{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":"$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.log json_combined;
error_log /var/log/nginx/error.log warn;
Yapılandırmayı Doğrulama ve Sorun Giderme
Modüler yapılandırmada en kritik adım her değişiklikten sonra test yapmaktır:
# Yapılandırmayı test et (hata varsa dosya ve satır numarasını gösterir)
sudo nginx -t
# Daha ayrıntılı çıktı için
sudo nginx -T
# Hangi dosyaların include edildiğini görmek için
sudo nginx -T 2>&1 | grep "# configuration file"
# Yapılandırma yüklemek zorunda kalmadan sözdizimini kontrol et
sudo nginx -t -c /etc/nginx/nginx.conf
nginx -T komutu tüm include edilmiş dosyaları birleştirerek size gösterir. Bir yapılandırma sorununun tam olarak nerede olduğunu bulmak için bu komut altın değerindedir.
Sık karşılaşılan bir hata: include ile dahil ettiğiniz dosyada http {} bloğu açmak. Bu dosyalar zaten bir blok içinde include edildiğinden tekrar blok açmayın. Örneğin conf.d altındaki dosyalar http {} bloğu içinde include ediliyorsa, bu dosyaların içinde ayrıca http {} yazmamalısınız.
# YANLIS - conf.d altındaki bir dosyada bu olmamali:
http {
gzip on;
}
# DOGRU - sadece direktifler:
gzip on;
gzip_vary on;
İzin ve Güvenlik Konuları
Include edilen dosyaların izinlerinin doğru olması gerekir:
# Nginx yapılandırma dosyalarının sahipliği ve izinleri
sudo chown root:root /etc/nginx/conf.d/*.conf
sudo chmod 644 /etc/nginx/conf.d/*.conf
# sites-available ve sites-enabled
sudo chown root:root /etc/nginx/sites-available/*.conf
sudo chmod 644 /etc/nginx/sites-available/*.conf
# Symlink'lerin durumunu kontrol et
ls -la /etc/nginx/sites-enabled/
# Kırık symlink'leri tespit et
find /etc/nginx/sites-enabled/ -xtype l
Kırık symlink varsa Nginx başlarken ya da reload sırasında hata verir. find /etc/nginx/sites-enabled/ -xtype l komutu hedefi olmayan symlink’leri listeler.
Yapılandırma Değişikliklerini Git ile Takip Etmek
Modüler yapı oluşturduğunuza göre bunu versiyon kontrolü altına almanın tam zamanı:
# /etc/nginx dizinini git deposuna al
cd /etc/nginx
sudo git init
sudo git add .
sudo git commit -m "Initial modular nginx configuration"
# Bir değişiklik yaparken
sudo nano /etc/nginx/conf.d/ssl-params.conf
sudo nginx -t
sudo git diff
sudo git add -p
sudo git commit -m "TLS 1.0 ve 1.1 devre disi birakildi"
sudo systemctl reload nginx
Bu yaklaşım hem takım çalışmasını kolaylaştırır hem de bir şeyler ters gittiğinde önceki sürüme dönmenizi sağlar.
Sonuç
Nginx’in include direktifi, ilk bakışta basit bir sözdizimi özelliği gibi görünse de doğru kullanıldığında yapılandırma yönetimini tamamen dönüştürür. Yüzlerce satırlık monolitik bir nginx.conf dosyasından, her parçası kendi işini yapan, test edilebilir ve yeniden kullanılabilir modüllere geçmek hem günlük operasyonları kolaylaştırır hem de hata yapma olasılığını ciddi ölçüde azaltır.
Özetle uygulamanız gereken pratikler şunlardır:
- conf.d/ altında gzip, SSL, güvenlik başlıkları, proxy parametreleri gibi global ayarları ayrı dosyalarda tutun
- sites-available/ ve sites-enabled/ pattern’ini kullanarak virtual host’ları sembolik linklerle yönetin
- snippets/ dizinini küçük, tekrar kullanılabilir parçalar için kullanın
- Her değişiklikten sonra
nginx -tile yapılandırmayı test edin - Yapılandırma dosyalarını Git ile versiyon kontrolü altında tutun
- Include edilen dosyalarda hangi context içinde olduğunuzu unutmayın, yanlış blok açmaktan kaçının
Küçük bir VPS’te tek site çalıştırıyor olsanız bile modüler yapıyı benimsemeye değer. Sistem büyüdüğünde baştan bu alışkanlığa sahip olmak, sonradan her şeyi yeniden düzenlemek zorunda kalmaktan çok daha kolaydır.