Hosting

502 Bad Gateway Hatası: PHP-FPM ve Proxy Teşhisi

Hızlı özet

502 Bad Gateway, çoğu zaman DNS sorunu değildir. Reverse proxy’nin (Nginx veya Apache gibi ön web sunucusunun) PHP-FPM’e ya da arka uç uygulamasına geçerli bir yanıt alamadığını gösterir.

  • Önce 502 yanıtını hangi katmanın ürettiğini ve hata zamanını loglardan belirleyin.
  • Unix socket kullanıyorsanız socket dosyasının varlığını ve web sunucusunun erişim iznini kontrol edin.
  • TCP upstream kullanıyorsanız PHP-FPM’in gerçekten ilgili adres ve portta dinlediğini doğrulayın.
  • PHP-FPM havuzu doluysa veya süreçler kilitlenmişse bağlantı reddedilebilir ya da zaman aşımına uğrayabilir.
  • Değişiklikten sonra aynı URL’yi, PHP-FPM logunu ve proxy logunu birlikte kontrol ederek sonucu doğrulayın.

WordPress siteniz tarayıcıda 502 Bad Gateway gösteriyor ve DNS kayıtları doğru görünüyorsa sorunu DNS panelinde aramak yerine istek zincirini ayırmanız gerekir. Ziyaretçi önce DNS ile doğru sunucuya yönlenir, ardından reverse proxy isteği PHP-FPM’e iletir. Hata çoğunlukla bu ikinci aşamada ortaya çıkar.

Bu yazıda 502 Bad Gateway PHP-FPM hatasını socket erişimi, TCP upstream, PHP-FPM havuzu, zaman aşımı ve proxy yapılandırması üzerinden teşhis edeceksiniz. Amaç tüm sunucu ayarlarını değiştirmek değil, belirtiye uyan en dar düzeltmeyi yapıp sonucu doğrulamaktır.

502 hatasında DNS ile PHP-FPM’i nasıl ayırırsınız?

DNS, alan adının hangi IP adresine çözümleneceğini belirler. PHP-FPM ise web sunucusunun PHP kodunu çalıştırmak için bağlandığı FastCGI işlem yöneticisidir. DNS doğru sunucuya gidiyor ancak proxy bu sunucudaki PHP-FPM’e ulaşamıyorsa tarayıcı yine 502 görebilir.

İlk ayrım için aynı isteği alan adıyla ve mümkünse doğrudan yerel web sunucusuna gönderin. Aşağıdaki komut yalnızca gözlem yapar; alan adı, port ve Host başlığını kendi ortamınıza göre değiştirin.

curl -I https://ornekalanadiniz.tld/

Yanıtta 502 görüyorsanız tarih ve saati not edin. Yerel makinede çalışan web sunucusuna test yapabiliyorsanız doğru Host başlığıyla şu yaklaşımı kullanabilirsiniz:

curl -I -H 'Host: ornekalanadiniz.tld' http://127.0.0.1/

İki istek de aynı sunucudaki proxy’ye gidiyorsa bu test DNS’i tek başına kanıtlamaz; yalnızca isteğin yerel proxy’ye kadar ulaştığını gösterir. Daha güçlü teşhis için DNS çözümünü kontrol edin, ardından proxy access ve error loglarında aynı zaman aralığını arayın.

dig +short ornekalanadiniz.tld

Alan adı beklemediğiniz bir IP’ye çözülüyorsa önce DNS ve önbellek tarafını düzeltin. Beklenen IP’ye çözülüyor fakat proxy logunda upstream bağlantı hatası bulunuyorsa DNS’i değiştirmek sorunu çözmez. Bu noktada PHP-FPM bağlantısını inceleyin.

İpucu

HTTP durum kodu tek başına yeterli değildir. 502’nin üretildiği katmanı belirlemek için proxy error logu, PHP-FPM logu ve mümkünse uygulama logunu aynı saat dilimi ve zaman aralığıyla karşılaştırın.

Önce 502’nin gerçek nedenini loglardan bulun

Bir proxy, upstream’den (arka uçtan) geçerli HTTP veya FastCGI yanıtı alamadığında 502 döndürebilir. Ancak log satırındaki ayrıntı, düzeltmenin yönünü değiştirir. Connection refused, No such file or directory, Permission denied ve upstream timed out aynı sorunu anlatmaz.

Proxy logunda hangi ifadeler ne anlatır?

  • Connection refused: TCP ile bağlanılan portta dinleyen bir servis yoktur veya servis bağlantıyı kabul etmiyordur.
  • No such file or directory: Proxy yapılandırmasındaki Unix socket yolu mevcut değildir. PHP-FPM durmuş, farklı bir socket kullanıyor veya yol hatalı olabilir.
  • Permission denied: Socket mevcut olsa da web sunucusu kullanıcısı dosyaya ya da üst dizinlerden birine erişemiyordur.
  • Upstream timed out: PHP-FPM yanıt üretmeden önce süre dolmuştur. Yoğun havuz, yavaş sorgu, kilitlenen eklenti veya uzun süren PHP işlemi olası nedenlerdir.
  • Invalid response: Upstream yanıtı bozuk, eksik veya proxy’nin beklediği protokole uygun değildir.

Log dosyasının yolu dağıtıma, panel uygulamasına ve sanal host yapılandırmasına göre değişir. Dosya yolunu varsaymak yerine etkin sanal host yapılandırmasındaki error_log tanımını veya kullandığınız panelin log bölümünü kontrol edin. Sistem servisini yönetebildiğiniz bir VPS’te genel servis durumu ve son kayıtlar için şu komutlar kullanılabilir:

sudo systemctl status php8.2-fpm --no-pager
sudo journalctl -u php8.2-fpm --since "15 minutes ago" --no-pager

Buradaki php8.2-fpm adı örnektir. Sunucunuzda php8.1-fpm, php8.3-fpm veya farklı bir servis adı olabilir. Yanlış servis adını çalıştırmak gerçek durumu göstermez; servis yönetimi komutlarını kullanmadan önce etkin PHP-FPM sürümünü ve servis adını belirleyin.

WordPress’in kendi PHP hataları için uygulama logunu da kontrol edin. Bir eklentinin fatal error üretmesi çoğu zaman doğrudan 502 yerine 500 veya boş sayfa görülmesine neden olur. Yine de PHP-FPM worker’larının çökmesine ya da isteklerin uzamasına neden olabileceği için zaman eşleşmesi önemlidir. WordPress tarafındaki uygulama hatalarını ayırmak için WordPress beyaz ekran hatası çözümü konusundaki adımlar da yardımcı olabilir.

Unix socket kullanan PHP-FPM bağlantısını düzeltme

PHP-FPM ile proxy arasında Unix socket kullanılıyorsa iletişim bir dosya üzerinden kurulur. Bu yöntem yerel sunucularda yaygındır; fakat PHP-FPM’in oluşturduğu socket yolu ile proxy’nin bağlanmaya çalıştığı yol birebir aynı olmalıdır.

Socket gerçekten var mı?

Önce proxy yapılandırmasındaki fastcgi_pass veya eşdeğer upstream tanımında yazan yolu bulun. Ardından bu yolun mevcut olup olmadığını kontrol edin:

sudo ls -l /run/php/php8.2-fpm.sock
sudo stat /run/php/php8.2-fpm.sock

Dosya yoksa iki olasılığı ayırın: PHP-FPM çalışmıyordur veya PHP-FPM farklı bir socket yolu kullanıyordur. Havuz yapılandırmasındaki listen değerini kontrol edin:

sudo grep -R "^[[:space:]]*listen[[:space:]]*=" /etc/php/8.2/fpm/pool.d/

Dağıtım ve PHP sürümüne göre dizin değişebilir. Proxy’deki yol ile havuzdaki listen yolu aynı değilse önce hangi yolun standart ve etkin olduğunu belirleyin. Ardından yalnızca ilgili yapılandırmayı düzeltin; birden fazla havuzun socket yolunu topluca değiştirmeyin.

Socket izinlerini nasıl kontrol edersiniz?

Socket mevcut olduğu halde Permission denied alıyorsanız dosyanın sahibi, grubu ve modunu kontrol edin. Örnek bir çıktıdaki kullanıcı ve grup adları sisteminize göre farklı olabilir:

sudo ls -l /run/php/php8.2-fpm.sock
namei -l /run/php/php8.2-fpm.sock

Web sunucusunun worker süreçlerinin çalıştığı kullanıcı socket’e erişebilmelidir. Ancak doğrudan geniş izinler vermek güvenli bir varsayılan değildir. Önce web sunucusu kullanıcı adını, ardından PHP-FPM havuzunun listen.owner, listen.group ve listen.mode değerlerini karşılaştırın. Bu ayarlar genellikle havuz dosyasında bulunur.

İzin değişikliği yapmadan önce ilgili havuz dosyasını yedekleyin. Örneğin:

sudo cp /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/www.conf.bak

Sonra yalnızca gerekli owner, group veya mode değerini düzenleyin. Mode değerini herkes için yazılabilir hâle getirmek yerine proxy kullanıcısının gerekli grup erişimini sağlamak daha dar bir düzeltmedir. Yapılandırma sözdizimini dağıtımınızın desteklediği test komutuyla doğrulayın; ardından yalnızca PHP-FPM’i yeniden yükleyin veya yeniden başlatın.

sudo php-fpm8.2 -t
sudo systemctl reload php8.2-fpm

php-fpm8.2 ve test seçeneği sisteminizde farklı olabilir. Reload desteklenmiyorsa servis dokümantasyonundaki güvenli yöntemi kullanın. Değişiklikten sonra socket’in yeniden oluştuğunu ve izinlerinin beklediğiniz gibi kaldığını kontrol edin. Ardından sorunlu URL’yi tekrar çağırıp proxy error logunda yeni bir socket hatası oluşmadığını doğrulayın.

Dikkat

Socket için 777 gibi geniş izinler vermek 502’yi geçici olarak gizleyebilir, fakat PHP-FPM erişimini gereksiz biçimde açar. Önce doğru kullanıcı, grup ve üst dizin erişimini belirleyin; değişikliği geri alabileceğiniz yedeği saklayın.

TCP upstream ve PHP-FPM dinleme portunu inceleme

Bazı kurulumlarda proxy, Unix socket yerine 127.0.0.1:9000 gibi bir TCP adresine bağlanır. Bu durumda socket izinlerine bakmak sonuç vermez. PHP-FPM’in gerçekten beklenen adreste dinleyip dinlemediğini kontrol etmelisiniz.

sudo ss -ltnp | grep ':9000'

Çıktı yoksa PHP-FPM ilgili portta dinlemiyor olabilir. Havuz dosyasındaki listen değerini ve servis durumunu karşılaştırın:

sudo grep -R "^[[:space:]]*listen[[:space:]]*=" /etc/php/8.2/fpm/pool.d/
sudo systemctl status php8.2-fpm --no-pager

Proxy 127.0.0.1:9000‘a, PHP-FPM ise başka bir porta veya yalnızca Unix socket’e ayarlıysa iki tarafın bağlantı noktası eşleşmez. En dar çözüm, mevcut mimariyi koruyarak yalnızca yanlış upstream adresini düzeltmektir. Socket’ten TCP’ye geçmek gibi daha geniş bir değişiklik yapmadan önce bunun gerçekten gerekli olduğundan emin olun.

Port dinleniyor olsa bile bağlantı testi PHP-FPM’in HTTP sunucusu olmadığını unutmayın. Porta curl ile HTTP isteği göndermek anlamlı bir uygulama testi değildir. Burada amaç dinleme durumunu ve proxy logunu birlikte değerlendirmektir. Proxy’nin bağlantı reddedildiğini yazdığı anda ss çıktısında port yoksa servis veya listen ayarı öne çıkar; port mevcutsa yanlış adres, ağ politikası ya da havuz kapasitesi araştırılır.

PHP-FPM havuzu doluysa 502 neden oluşur?

PHP-FPM havuzu, PHP isteklerini çalıştıran worker süreçlerinin grubudur. pm.max_children bu havuzda aynı anda çalışabilecek üst sınırı belirler. Tüm worker’lar uzun süren isteklerle meşgulse yeni istekler bekler; proxy’nin bekleme süresi dolduğunda 502 veya bazı kurulumlarda 504 görülebilir.

Bu durum PHP-FPM’in tamamen durmuş olduğu anlamına gelmez. Servis aktif görünürken havuz kapasitesi dolmuş olabilir. FPM logunda server reached pm.max_children benzeri uyarılar proxy logundaki timeout kayıtlarıyla aynı zamana denk geliyorsa kapasite baskısı güçlenir.

Önce hangi isteklerin uzun sürdüğünü belirleyin. WordPress’te ağır eklentiler, dış API çağrıları, yavaş veritabanı sorguları veya büyük yönetim işlemleri bu tabloyu oluşturabilir. PHP-FPM web worker’ları ile CLI cron veya kuyruk worker’larını birbirine karıştırmayın. HTTP isteği yapmayan bir CLI cron işi FPM worker tüketmez; fakat aynı veritabanını kilitleyerek web isteklerini uzatabilir.

Bu noktada pm.max_children değerini rastgele yükseltmek dar bir teşhis değildir. Her yeni worker bellek tüketir. Önce RAM kullanımını, süreç sayısını, istek sürelerini ve PHP-FPM uyarılarını ölçün. Havuz ayarlarının hesaplanması için pm.max_children ve pm.max_requests hesaplama rehberi ilgili kapasite sınırlarını anlamanıza yardımcı olur.

Sorun tek bir eklentinin uzun isteğiyse eklentiyi devre dışı bırakmadan önce yedek ve geri dönüş planı oluşturun. Üretim WordPress sitesinde veri değiştiren bir işlem yapacaksanız veritabanı ve dosya yedeğinin kullanılabilir olduğunu kontrol edin. Daha düşük riskli ilk adım, yavaş isteği ve ilgili PHP hata kaydını belirlemek; ardından eklenti veya sorgu düzeltmesini kontrollü biçimde uygulamaktır.

Timeout, proxy yapılandırması ve uygulama hatasını ayırma

Proxy’nin upstream’e bağlanamaması ile bağlanıp zamanında yanıt alamaması farklıdır. Connection refused bağlantı aşamasını, timed out ise çoğu zaman yanıt süresinin dolduğunu işaret eder. Bu ayrım, servis yeniden başlatmak yerine önce uygulama ve kaynak kullanımını incelemenizi sağlar.

PHP-FPM’e bağlantı başarılı fakat WordPress isteği uzun sürüyorsa proxy timeout değerini artırmak yalnızca belirtinin görünmesini geciktirebilir. Önce PHP-FPM slow log, uygulama logu ve veritabanı yavaş sorgu kayıtlarında aynı isteği arayın. Sorun gerçekten beklenen uzun bir işlemse timeout değişikliği kontrollü ve gerekçeli yapılabilir; değerleri sınırsız yükseltmek havuzun daha uzun süre meşgul kalmasına neden olur.

Proxy yapılandırmasında FastCGI parametrelerinin eksik olması çoğu zaman 502’nin ana sebebi değildir; yine de yanlış SCRIPT_FILENAME, yanlış site kökü veya hatalı PHP sürümü farklı hatalara yol açabilir. Sanal hostun doğru PHP-FPM havuzuna bağlandığını ve başka bir sitenin socket’ini kullanmadığını kontrol edin.

Yapılandırmayı değiştirmeden önce etkin konfigürasyonu test edin. Nginx veya Apache için test komutları kurulumunuza göre değişebilir. Örnek olarak Nginx kullanılan bir VPS’te:

sudo nginx -t

Test başarısızsa reload yapmayın; önce gösterilen dosya ve satırdaki sözdizimini düzeltin. Test başarılı olduktan sonra kontrollü reload uygulayın ve aynı isteği yeniden deneyin. Değişiklikten sonra 502 devam ediyorsa eski yedeğe dönüp yeni hipotezi ayrı test etmek, üst üste ayar biriktirmekten daha sağlıklıdır.

Örnek senaryo

Varsayım: Nginx, /run/php/php8.2-fpm.sock socket’ine bağlanıyor; PHP-FPM ise /run/php/php8.3-fpm.sock oluşturuyor. Proxy logunda No such file or directory görülüyor ve alan adı beklenen sunucuya çözülüyor. Bu senaryoda DNS değişikliği yapılmaz. Önce etkin PHP-FPM listen değeri ile Nginx fastcgi_pass yolu karşılaştırılır, yalnızca yanlış yol düzeltilir, nginx -t ve sorunlu URL ile doğrulama yapılır.

İzleme uç noktası ile canlı durumu doğrulama

PHP-FPM status veya ping özelliği, havuzun canlı durumunu gözlemlemek için kullanılabilir. Ancak bu özelliği etkinleştirmek ile web sunucusunda güvenli erişim yolunu tanımlamak ayrı adımlardır.

Önce havuz yapılandırmasında status veya ping ayarının etkin olup olmadığını kontrol edin. Bu uç noktayı doğrudan internete açmayın. Nginx ya da Apache tarafında yalnızca yerel yönetim erişimine, VPN’e veya kimlik doğrulamalı güvenli bir yönetim yoluna izin verin. Uç noktada süreç sayısı ve istek durumu gibi operasyonel bilgiler bulunabileceğinden erişim kapsamı sınırlı olmalıdır.

Bu özellik mevcut değilse 502 teşhisi için zorunlu değildir. Proxy ve PHP-FPM logları, servis durumu ve socket/port kontrolleri çoğu sorunu ortaya çıkarır. İzleme etkinleştirilecekse havuz dosyasını yedekleyin, değişikliği test edin ve dış erişimi engelleyen web sunucusu kuralını ayrıca doğrulayın.

WordPress ve WooCommerce sitelerinde özel belirtiler

WordPress ana sayfası çalışırken yönetim paneli, ürün arama veya ödeme adımı 502 veriyorsa sorun tüm PHP isteklerinde olmayabilir. Bu yolların daha ağır sorgular, dış servis çağrıları veya uzun süren sepet işlemleri üretmesi mümkündür. Önce hatanın tüm URL’lerde mi, yoksa tek bir özellikte mi görüldüğünü belirleyin.

WooCommerce tarafında stok, kargo, ödeme veya vergi servisine yapılan dış çağrılar gecikirse PHP-FPM worker’ı yanıt bekler. Bu durum tek başına DNS hatası değildir; dış servise erişim, uygulama timeout’u ve havuz doluluğu birlikte incelenmelidir. İlgili eklentiyi hemen silmek yerine yedek alın, loglarda hangi çağrının uzadığını bulun ve gerekiyorsa staging ortamında değişiklik yapın.

Kalıcı 502 sonrasında önbellek temizlemek tek başına çözüm değildir. Önce proxy’nin PHP-FPM’e ulaştığını doğrulayın. Önbellek katmanı eski bir 502 yanıtını sunuyorsa proxy ve uygulama cache ayarlarını ayrıca inceleyin; fakat canlı hatanın kaynağını loglarla doğrulamadan cache silme işlemlerini çoğaltmayın.

Sık Sorulan Sorular

502 hatası her zaman PHP-FPM’in kapalı olduğu anlamına mı gelir?

Hayır. PHP-FPM çalışıyor olabilir; yanlış socket yolu, izin sorunu, dolu havuz veya uzun süren istek nedeniyle proxy geçerli yanıt alamıyor olabilir.

PHP sürümünü yükseltmek 502’yi çözer mi?

Yalnızca sorun sürümle uyumsuz bir PHP-FPM servisi veya yanlış socket yapılandırmasıysa yardımcı olabilir. Log ve etkin listen değerini kontrol etmeden sürüm değiştirmek yeni uyumluluk sorunları doğurabilir.

502 ile 504 arasındaki fark nedir?

502 genellikle proxy’nin upstream’den geçersiz yanıt alması veya bağlantı kuramamasıyla ilişkilidir. 504 ise upstream’in zamanında yanıt vermediğini daha doğrudan ifade eder. Bazı proxy ve uygulama yapılandırmalarında belirtiler örtüşebileceği için kesin ayrım log satırında yapılmalıdır.

CLI cron çalışırken PHP-FPM neden dolu görünür?

HTTP çağrısı yapmayan CLI cron doğrudan FPM worker tüketmez. Ancak aynı veritabanı, dosya veya harici servis üzerinde gecikme oluşturarak web isteklerinin daha uzun sürmesine ve FPM havuzunun dolmasına katkıda bulunabilir.

502 teşhisi için kısa kontrol listesi

  1. Hatanın başladığı zamanı ve etkilenen URL’leri not edin.
  2. Alan adının beklenen IP’ye çözümlendiğini kontrol edin.
  3. Proxy error logunda connection refused, socket, permission veya timeout ifadesini belirleyin.
  4. PHP-FPM servis adını ve durumunu doğrulayın.
  5. Unix socket kullanılıyorsa yol, sahiplik, grup ve üst dizin izinlerini karşılaştırın.
  6. TCP upstream kullanılıyorsa beklenen portun gerçekten dinlendiğini kontrol edin.
  7. FPM logunda havuz sınırı, worker çökmesi ve slow request uyarılarını arayın.
  8. Değişiklik yapacaksanız yapılandırmayı yedekleyin, en dar ayarı değiştirin ve geri dönüş yolunu saklayın.
  9. Yapılandırma testinden sonra aynı URL’yi çağırın; proxy ve PHP-FPM loglarında yeni hata oluşmadığını doğrulayın.

Bu kontrollerden sonra hâlâ 502 alıyorsanız son değişiklikleri geri alıp tek bir istek örneği üzerinden proxy logu, FPM logu ve uygulama logunu aynı zaman damgasında karşılaştırın. Böylece DNS, proxy, PHP-FPM ve WordPress katmanlarını yeniden karıştırmadan bir sonraki düzeltmeyi seçebilirsiniz.

↑