İçeriğe geç
Süreçlerinize uygun yazılımı birlikte planlayalım. Demo ve teklif için arayın: +90 546 737 48 29

TR EN DE

Nginx ve PHP-FPM: PHP siteleri Nginx ile nasıl çalışır?

Apache ile çalışan bir sitede PHP çoğunlukla "kendiliğinden" çalışır; çünkü Apache PHP'yi bir modül olarak kendi içinde çalıştırabilir. Nginx'te durum farklıdır: Nginx PHP kodunu çalıştıramaz. Onun yerine isteği, PHP'yi çalıştırmak için ayrı bir servis olarak bekleyen PHP-FPM'e (FastCGI Process Manager) iletir, yanıtı alır ve ziyaretçiye gönderir.

İkisi arasındaki konuşma dili FastCGI adlı protokoldür. Yani ortada iki ayrı yazılım, iki ayrı yapılandırma ve aralarında bir bağlantı vardır. PHP sitelerinde Nginx ile yaşanan sorunların çoğu ("502 Bad Gateway", boş sayfa, PHP dosyasının indirilmesi) bu bağlantının bir ucundaki ayardan kaynaklanır. Bu rehber önce düzenin nasıl işlediğini, sonra adım adım doğru yapılandırmayı anlatır. Nginx'e yeniyseniz önce Nginx nedir rehberine göz atın.

Kısaca

  • Nginx PHP çalıştırmaz; .php isteklerini FastCGI ile PHP-FPM'e iletir.
  • fastcgi_pass adresi, PHP-FPM havuzundaki listen değeriyle aynı olmalıdır.
  • try_files, var olmayan dosyaların PHP'ye gönderilmesini önler.
  • Soket yoksa ya da izinleri yanlışsa ziyaretçi 502 görür.

Gerekenler

  • Sunucuda yönetici (sudo) yetkisi
  • Kurulu Nginx ve PHP-FPM paketi
  • Sitenin Nginx yapılandırma dosyası ve yedeği
  • Nginx ve PHP-FPM günlüklerine erişim

Not

Bu rehberdeki soket ve dosya yolları örnektir. PHP-FPM'in soket yolu, servis adı ve yapılandırma klasörü dağıtıma ve PHP sürümüne göre değişir; kendi sunucunuzdaki değerleri 2. adımdaki gibi doğrulayın.

Bu sayfada

Adım adım Nginx ve PHP-FPM yapılandırması

  1. Akışı anlayın: kim ne yapıyor?

    Bir istek geldiğinde iş bölümü şöyledir:

    • Statik dosyalar (görsel, CSS, JavaScript): Nginx diskten okur ve doğrudan gönderir; PHP-FPM hiç devreye girmez.
    • PHP istekleri: Nginx isteği, hangi dosyanın çalıştırılacağı bilgisiyle birlikte PHP-FPM'e iletir. PHP-FPM, bekleyen işçi süreçlerinden biriyle dosyayı çalıştırır ve çıktıyı Nginx'e geri verir.

    Nginx ile PHP-FPM iki yoldan biriyle konuşur:

    • Unix soketi: Disk üzerinde özel bir dosyadır (ör. /run/php/php-fpm.sock). Yalnızca aynı makinedeki süreçler kullanabilir; erişim dosya izinleriyle denetlenir.
    • TCP adresi: 127.0.0.1:9000 gibi bir adres ve bağlantı noktası. PHP-FPM başka bir makinede ya da kapsayıcıda (container) çalışıyorsa bu yol gerekir.

    İkisi aynı makinedeyse Unix soketi yaygın tercihtir; hangisini seçerseniz seçin, iki tarafta aynı değer yazmalıdır.

    Şema: tarayıcı isteği Nginx'e gelir; statik dosyaları Nginx verir, PHP isteklerini FastCGI ile soket üzerinden PHP-FPM havuzuna iletir : Büyüt
  2. PHP-FPM'in çalıştığını ve nerede dinlediğini bulun

    Önce PHP-FPM servisinin çalıştığından emin olun, sonra havuz dosyasındaki listen satırını bulun. Bu satır, Nginx'in bağlanacağı soketi ya da adresi gösterir.

    Bash
    # PHP-FPM çalışıyor mu? (servis adı dağıtıma göre değişir)
    systemctl status php-fpm           # RHEL, AlmaLinux ve benzerleri
    systemctl status 'php*-fpm'        # Debian, Ubuntu: adında sürüm bulunur
    
    # Havuz hangi soketi ya da adresi dinliyor?
    sudo grep -R "^listen" /etc/php-fpm.d/ /etc/php/ 2>/dev/null
    
    # Soket dosyası var mı, sahibi ve izinleri ne?
    ls -l /run/php/ /run/php-fpm/ 2>/dev/null

    Servis adı ve yollar dağıtıma göre değişir: Debian ve Ubuntu'da servis adında ve yollarda PHP sürümü bulunur (ör. /run/php/ altında sürüm numaralı bir soket, /etc/php/<sürüm>/fpm/pool.d/ altında havuz dosyaları); RHEL, AlmaLinux ve benzerlerinde servis çoğunlukla php-fpm, havuz klasörü /etc/php-fpm.d/, soket ise /run/php-fpm/ altındadır. Barındırma panelleri kendi yollarını kullanabilir. Tahmin etmeyin; listen satırında ne yazıyorsa onu kullanın.

  3. server bloğunda PHP isteklerini PHP-FPM'e yönlendirin

    Aşağıdaki server bloğu PHP ile çalışan bir site için temel düzeni gösterir.

    Nginx
    server {
        listen 80;
        server_name ornek.com www.ornek.com;
    
        root /var/www/ornek.com/public;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ =404;
        }
    
        location ~ \.php$ {
            # Dosya diskte yoksa PHP'ye gönderme
            try_files $uri =404;
    
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    
            # Soket yolu dağıtıma göre değişir; havuzdaki "listen" değeriyle aynı olmalı
            fastcgi_pass unix:/run/php/php-fpm.sock;
            # TCP ile dinleyen havuz için: fastcgi_pass 127.0.0.1:9000;
        }
    }

    Satır satır anlamı:

    • index index.php index.html; Bir klasör istendiğinde (ör. /) hangi dosyanın aranacağını söyler. index.php listede yoksa ana sayfa açılmaz ya da 403 döner.
    • location / içindeki try_files: İstenen adres gerçek bir dosya ya da klasörse onu sunar; değilse 404 döndürür.
    • location ~ \.php$: Adresi .php ile biten istekleri yakalar.
    • fastcgi_pass: İsteğin iletileceği PHP-FPM adresi. Unix soketi için unix: önekiyle yol, TCP için 127.0.0.1:9000 biçiminde yazılır.

    Tüm istekleri tek bir index.php dosyasında karşılayan uygulamalarda (çoğu çatı ve hazır içerik yönetim sistemi) location / bloğu biraz farklıdır: dosya bulunamazsa istek 404 yerine index.php'ye yönlendirilir.

    Nginx
    # "location /" bloğunun içi: dosya ya da klasör yoksa isteği index.php'ye ver
    try_files $uri $uri/ /index.php?$query_string;

    Bu blok yoksa ana sayfa açılır ama alt sayfalar 404 verir. Apache'de aynı işi .htaccess içindeki yeniden yazma kuralları yapar; taşıma için Apache'den Nginx'e geçiş rehberine bakın.

    Akış şeması: istek gelir, location seçilir, try_files dosyanın varlığını denetler, fastcgi_pass isteği PHP-FPM'e iletir, yanıt döner : Büyüt
  4. fastcgi_params ve SCRIPT_FILENAME'i doğru verin

    Nginx, PHP-FPM'e yalnızca "bir istek var" demez; isteğin ayrıntılarını FastCGI parametreleri olarak gönderir: istek yöntemi, sorgu dizgisi, ziyaretçinin IP adresi, sunucu adı ve benzerleri. PHP tarafında bunlar $_SERVER dizisinde görünür.

    • include fastcgi_params; Nginx ile birlikte gelen ve bu standart parametreleri tanımlayan dosyayı içeri alır.
    • SCRIPT_FILENAME PHP-FPM'e hangi dosyanın çalıştırılacağını tam yoluyla söyleyen parametredir. $document_root$fastcgi_script_name değeri, root ile verdiğiniz klasörü ve istenen dosya adını birleştirir.

    fastcgi_params dosyası genellikle SCRIPT_FILENAME satırını içermez; bu yüzden örnekte ayrıca yazılmıştır. Nginx ile gelen fastcgi.conf adlı dosya ise bu satırı da içerir; onu kullanıyorsanız satırı ikinci kez yazmanız gerekmez. Debian ve Ubuntu paketlerinde bu ayarları toplayan hazır bir parça dosya da bulunur. Hangisini kullanırsanız kullanın, parametrenin bir kez ve doğru tanımlandığını denetleyin.

    SCRIPT_FILENAME eksik ya da yanlışsa PHP-FPM dosyayı bulamaz: ziyaretçi boş bir sayfa ya da "File not found." yanıtı görür. En sık nedeni root yönergesinin yanlış klasörü göstermesi ya da location içinde farklı bir root tanımlanmasıdır.

  5. Var olmayan dosyaları PHP'ye göndermeyin

    Örnekteki PHP bloğunun ilk satırı try_files $uri =404; bir savunma önlemidir. İstenen .php dosyası diskte yoksa Nginx isteği PHP-FPM'e hiç iletmez, doğrudan 404 döndürür.

    Bu neden önemli? Denetim olmadığında, gerçekte var olmayan bir .php adresi PHP'ye ulaşır ve PHP'nin yol çözümleme ayarına bağlı olarak başka bir dosya PHP olarak çalıştırılabilir. Sitenizde kullanıcıların dosya yükleyebildiği bir alan varsa bu, yüklenmiş bir dosyanın kod gibi çalıştırılmasına kadar gidebilir. Tek satırlık denetim bu kapıyı kapatır.

    • Bu denetim, Nginx ile PHP-FPM aynı dosya sistemini gördüğünde çalışır. PHP-FPM ayrı bir makinede ya da kapsayıcıdaysa Nginx dosyayı göremez ve her istek 404 olur; o düzende denetim PHP tarafında yapılmalıdır.
    • Ek katman olarak PHP-FPM havuzundaki security.limit_extensions ayarı, hangi uzantıların PHP olarak çalıştırılabileceğini sınırlar; bu sınırı gevşetmeyin.
  6. Havuz (pool) ayarlarını tanıyın

    PHP-FPM, işçi süreçlerini havuz (pool) adı verilen gruplar hâlinde yönetir. Her havuzun kendi dinleme adresi, kendi kullanıcısı ve kendi süreç sınırları vardır. Aynı sunucuda birden fazla site varsa her birine ayrı havuz ve ayrı kullanıcı tanımlamak, bir sitedeki sorunun diğerinin dosyalarına ulaşmasını zorlaştırır.

    PHP-FPM
    ; Havuz dosyası (ör. www.conf); yolu dağıtıma göre değişir
    [ornek]
    user = ornek
    group = ornek
    
    ; Nginx'teki fastcgi_pass ile aynı olmalı
    listen = /run/php/php-fpm.sock
    
    ; Soketin sahibi ve izinleri: Nginx'in kullanıcısı erişebilmeli
    ; (Debian, Ubuntu: www-data; RHEL, AlmaLinux: nginx)
    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0660
    
    ; Süreç yönetimi (sayılar öneri değil, sözdizimi örneğidir)
    pm = dynamic
    pm.max_children = 10
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    AyarNe belirler?
    listenPHP-FPM'in dinlediği soket ya da adres. Nginx'teki fastcgi_pass ile aynı olmalıdır.
    user, groupPHP kodunun hangi kullanıcıyla çalışacağı. Dosya okuma ve yazma izinleri bu kullanıcıya göre işler.
    pmSüreç yönetim kipi: static (sabit sayıda süreç), dynamic (yüke göre alt ve üst sınır arasında) ya da ondemand (istek geldikçe başlatılır, boşta kalınca kapatılır).
    pm.max_childrenAynı anda çalışabilecek işçi süreç sayısının üst sınırı; yani aynı anda işlenebilecek PHP isteği sayısı.

    pm.max_children için herkese uyan bir sayı yoktur. Her işçi süreç bellek kullanır; sınır çok yüksekse yoğun anda sunucunun belleği tükenir, çok düşükse istekler sırada bekler ve PHP-FPM günlüğünde sınıra ulaşıldığını bildiren bir uyarı görülür. Doğru değer, sunucunun boş belleğine ve uygulamanızın süreç başına kullandığı belleğe bakılarak, ölçülerek bulunur. Örnekteki sayıları öneri olarak değil, sözdizimi örneği olarak okuyun.

    Şema: PHP-FPM havuzunun temel ayarları; listen, user ve group, pm kipleri ve pm.max_children : Büyüt
  7. Soket izinlerini ve 502 hatasını denetleyin

    "502 Bad Gateway", Nginx'in arkadaki servisten geçerli bir yanıt alamadığı anlamına gelir. PHP sitelerinde en sık nedeni, Nginx'in PHP-FPM'e bağlanamamasıdır. Nedenini tahmin etmeyin; Nginx hata günlüğü açıkça söyler.

    Günlükteki ifadeOlası nedenBakılacak yer
    No such file or directorySoket dosyası yok: PHP-FPM çalışmıyor ya da fastcgi_pass yolu yanlış (ör. PHP sürümü yükseltildi, soket adı değişti)Servis durumu; listen ile fastcgi_pass aynı mı?
    Permission deniedSoket var ama Nginx'in çalıştığı kullanıcının ona erişim izni yoklisten.owner, listen.group, listen.mode
    Connection refusedTCP adresinde dinleyen servis yokServis durumu; adres ve bağlantı noktası

    Unix soketi bir dosya olduğu için izinleri vardır. Havuzdaki listen.owner ve listen.group soketin sahibini, listen.mode ise izinlerini belirler. Nginx işçi süreçlerinin çalıştığı kullanıcı (dağıtıma göre çoğunlukla www-data ya da nginx) bu sokete okuma ve yazma izniyle erişebilmelidir. Soketi herkese açmak (0666) sorunu "çözer" ama sunucudaki her kullanıcının PHP-FPM'e istek göndermesine izin verir; bunun yerine sahibi ve grubu doğru ayarlayın.

    Sayfa bir süre bekledikten sonra hata veriyorsa (504) ya da 502 yalnızca yoğun anlarda görülüyorsa neden bağlantı değil, PHP tarafındaki yavaşlık ya da süreç sınırıdır. Ayrıntılı teşhis için 502 ve 504 hataları rehberine bakın.

    Şema: 502 hatasında Nginx hata günlüğündeki üç ifade ve anlamları; soket yok, izin yok, bağlantı reddedildi : Büyüt
  8. Yükleme klasöründe PHP çalıştırmayı kapatın

    Ziyaretçilerin ya da yöneticilerin dosya yüklediği klasörde (ör. /upload/) PHP çalışması için hiçbir neden yoktur. Yükleme denetiminizde bir açık olsa bile, o klasördeki dosyalar PHP-FPM'e gönderilmiyorsa yüklenen zararlı bir dosya çalıştırılamaz. Bu, tek başına yeterli olmayan ama etkili bir ikinci savunma hattıdır.

    Nginx
    # Genel "location ~ \.php$" bloğundan ÖNCE yazılmalıdır
    location ~* ^/upload/.*\.(php|phtml|phar)$ {
        return 403;
    }

    İki noktaya dikkat edin: klasör adını kendi sitenize göre değiştirin ve bu bloğu genel location ~ \.php$ bloğundan önce yazın. Nginx, düzenli ifadeli location bloklarını dosyadaki sırayla dener ve ilk eşleşeni kullanır; sıra tersse kural devreye girmez. Yükleme güvenliğinin bütünü için dosya yükleme güvenliği rehberine bakın.

    Karşılaştırma: yükleme klasöründe PHP açıkken yüklenen dosya çalışabilir; kapalıyken istek PHP-FPM'e gönderilmez ve 403 döner : Büyüt
  9. Test edin, yeniden yükleyin, doğrulayın

    Değişikliklerden sonra önce yapılandırmayı denetleyin, sonra ilgili servisi yeniden yükleyin. Nginx dosyasını değiştirdiyseniz Nginx'i, havuz dosyasını değiştirdiyseniz PHP-FPM'i yeniden yüklemeniz gerekir.

    Bash
    # Nginx yapılandırmasını denetle ve yeniden yükle
    sudo nginx -t
    sudo systemctl reload nginx
    
    # Havuz dosyası değiştiyse PHP-FPM'i yeniden yükle (servis adı dağıtıma göre değişir)
    sudo systemctl reload php-fpm
    
    # Sorun varsa son hata kayıtlarına bak
    sudo tail -n 50 /var/log/nginx/error.log

    Ardından tarayıcıdan sınayın: ana sayfa açılıyor mu, bir alt sayfa açılıyor mu, var olmayan bir .php adresi 404 veriyor mu, yükleme klasöründeki bir .php adresi 403 veriyor mu? Bir PHP dosyası çalışmak yerine indiriliyorsa ya da kaynak kodu ekranda görünüyorsa, istek PHP bloğuna hiç ulaşmıyordur: location ~ \.php$ bloğunun doğru server içinde olduğunu ve yeniden yükleme yapıldığını denetleyin.

Sık görülen belirtiler ve nedenleri

BelirtiOlası neden
502 Bad GatewayPHP-FPM çalışmıyor, soket yolu yanlış ya da soket izinleri Nginx'e erişim vermiyor
Boş sayfa ya da "File not found."SCRIPT_FILENAME eksik ya da yanlış; root yanlış klasörü gösteriyor
PHP dosyası indiriliyorPHP için location bloğu yok ya da istek başka bir bloğa düşüyor
Ana sayfa açılıyor, alt sayfalar 404Ön denetleyici (index.php) için try_files yönlendirmesi eksik
Ana sayfada 403index yönergesinde index.php yok ya da klasör izinleri Nginx'in okumasına izin vermiyor
Dosya yüklerken 413Nginx'in istek gövdesi sınırı (client_max_body_size, varsayılanı 1m) aşılıyor; PHP'nin kendi yükleme sınırları da ayrıca geçerlidir

Her durumda ilk bakılacak yer günlüklerdir: Nginx hata günlüğü (çoğunlukla /var/log/nginx/error.log) ve PHP-FPM günlüğü. Konumları yapılandırmaya göre değişebilir.

Güvenlik için kısa kontrol listesi

  • PHP bloğunda try_files $uri =404; var; var olmayan dosyalar PHP'ye gitmiyor.
  • Yükleme klasörlerinde PHP çalıştırma kapalı.
  • Soket izinleri dar: yalnızca Nginx'in kullanıcısı ya da grubu erişebiliyor.
  • PHP-FPM TCP ile dinliyorsa yalnızca 127.0.0.1 ya da iç ağ adresinde dinliyor; internete açık değil.
  • Her site kendi havuzunda ve kendi kullanıcısıyla çalışıyor; PHP süreçleri yönetici (root) olarak çalışmıyor.
  • PHP kullanıcısı yalnızca gereken klasörlere yazabiliyor.
  • Hata ayrıntıları ziyaretçiye değil günlüğe yazılıyor.

Sunucunun geneli için Nginx güvenlik ayarları ve sunucu ve barındırma güvenliği rehberlerine bakın.

Sık sorulan sorular

Nginx'te PHP dosyası çalışmak yerine indiriliyor, neden?

İstek PHP-FPM'e iletilmiyor demektir. Sitenin server bloğunda .php uzantısını yakalayan bir location bloğu ve içinde fastcgi_pass bulunmalıdır. Blok varsa doğru server içinde olduğunu, yapılandırmanın test edilip yeniden yüklendiğini ve tarayıcının eski yanıtı önbellekten göstermediğini denetleyin.

Unix soketi mi, 127.0.0.1:9000 mi kullanmalıyım?

Nginx ve PHP-FPM aynı makinedeyse Unix soketi yaygın tercihtir; ağ bağlantı noktası açmaz ve erişim dosya izinleriyle denetlenir. PHP-FPM ayrı bir makinede ya da kapsayıcıda çalışıyorsa TCP gerekir. Hangisini seçerseniz seçin fastcgi_pass ile havuzdaki listen aynı olmalıdır.

PHP sürümünü yükselttim, site 502 vermeye başladı. Neden?

Bazı dağıtımlarda soket dosyasının ve servisin adında PHP sürümü bulunur. Sürüm değişince soket yolu da değişir, Nginx ise eski yola bağlanmaya çalışır. Yeni havuz dosyasındaki listen değerini bulun, fastcgi_pass satırını ona göre güncelleyin, test edip yeniden yükleyin.

pm.max_children kaç olmalı?

Herkese uyan bir değer yoktur. Sunucunun kullanılabilir belleğine ve uygulamanızın süreç başına kullandığı belleğe bağlıdır. Çok yüksek değer belleği tüketir, çok düşük değer istekleri bekletir. Kendi sunucunuzda ölçerek ve PHP-FPM günlüğündeki uyarılara bakarak ayarlayın.

Apache'deki .htaccess kurallarım PHP-FPM ile çalışır mı?

Hayır. .htaccess Apache'ye özgüdür; ne Nginx ne de PHP-FPM bu dosyayı okur. Yönlendirme, erişim kısıtı ve adres yeniden yazma kurallarının Nginx yapılandırmasına taşınması gerekir.

BYK Yazılım Destek Ekibi
Bu rehber BYK Yazılım destek ekibi tarafından hazırlanır ve düzenli olarak gözden geçirilir. Son güncelleme: 04.10.2026.

İlgili rehberler

Web sitenizin altyapısını birlikte konuşalım

BYK Yazılım kurumsal web siteleri geliştirir. Sitenizle ilgili sorularınız için bize yazabilirsiniz.

Bize ulaşın Kurumsal web sitesi hizmetimiz