Bir production sunucusunda PHP sürümünü değiştirmek kulağa basit gelebilir, ama yanlış yapıldığında tüm web uygulamalarını çökertebilir. Bu yazıda Apache üzerinde PHP sürümlerini nasıl yöneteceğinizi, birden fazla PHP versiyonunu aynı anda nasıl çalıştıracağınızı ve bu işlemi yaparken nelere dikkat etmeniz gerektiğini gerçek dünya senaryolarıyla ele alacağım.
Neden Çoklu PHP Sürümü Gerekir?
Şöyle bir senaryo düşünün: Sunucunuzda hem eski bir kurumsal uygulama çalışıyor hem de yeni geliştirdiğiniz bir Laravel projesi var. Eski uygulama PHP 7.4 istiyor, Laravel projeniz ise PHP 8.2 gerektiriyor. İşte burada çoklu PHP yönetimi devreye giriyor.
Bu durum özellikle paylaşımlı hosting ortamları, ajans sunucuları ve legacy sistemlerin modernize edildiği geçiş dönemlerinde çok sık karşılaşılan bir problemdir. Doğru yapılandırılmış bir Apache sunucusunda farklı sanal hostlar farklı PHP sürümleriyle çalışabilir ve bu sayede hem eski hem yeni uygulamalarınız aynı anda sorunsuz hizmet verebilir.
Ön Gereksinimler ve Ortam Hazırlığı
Bu rehberde Ubuntu/Debian tabanlı sistemleri baz alacağım, ancak CentOS/RHEL için de notlar ekleyeceğim. Başlamadan önce sisteminizin güncel olduğundan emin olun.
sudo apt update && sudo apt upgrade -y
sudo apt install apache2 -y
# Apache sürümünü kontrol et
apache2 -v
# Mevcut PHP sürümünü kontrol et
php -v
Ondrej Sury’nin PPA deposu, Ubuntu üzerinde birden fazla PHP sürümünü kolayca kurmanın en güvenilir yoludur. Bu depo sayesinde PHP 7.4, 8.0, 8.1, 8.2 ve 8.3’ü aynı anda kurabilirsiniz.
# Gerekli araçları kur
sudo apt install software-properties-common -y
# Ondrej PPA deposunu ekle
sudo add-apt-repository ppa:ondrej/php -y
sudo add-apt-repository ppa:ondrej/apache2 -y
sudo apt update
CentOS/RHEL kullananlar için Remi deposunu kullanabilirsiniz:
# RHEL/CentOS için
sudo dnf install epel-release -y
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm -y
PHP Sürümlerini Kurma
Birden fazla PHP sürümünü kuralım. Ben burada PHP 7.4, 8.1 ve 8.2’yi örnek olarak kullanacağım.
# PHP 7.4 ve yaygın eklentileri kur
sudo apt install php7.4 php7.4-fpm php7.4-cli php7.4-common
php7.4-mysql php7.4-xml php7.4-mbstring php7.4-curl
php7.4-zip php7.4-gd php7.4-bcmath php7.4-json -y
# PHP 8.1 ve eklentileri kur
sudo apt install php8.1 php8.1-fpm php8.1-cli php8.1-common
php8.1-mysql php8.1-xml php8.1-mbstring php8.1-curl
php8.1-zip php8.1-gd php8.1-bcmath -y
# PHP 8.2 ve eklentileri kur
sudo apt install php8.2 php8.2-fpm php8.2-cli php8.2-common
php8.2-mysql php8.2-xml php8.2-mbstring php8.2-curl
php8.2-zip php8.2-gd php8.2-bcmath -y
Kurulumların başarılı olup olmadığını doğrulayalım:
# Kurulu PHP sürümlerini listele
ls /etc/php/
# Her sürümün durumunu kontrol et
php7.4 -v
php8.1 -v
php8.2 -v
# FPM servislerinin durumuna bak
systemctl status php7.4-fpm
systemctl status php8.1-fpm
systemctl status php8.2-fpm
Apache ile PHP Entegrasyon Yöntemleri
Apache’de PHP’yi çalıştırmanın iki temel yöntemi var: mod_php ve PHP-FPM (FastCGI Process Manager). Modern kurulumlar için PHP-FPM kesinlikle tercih edilmesi gereken yöntemdir.
mod_php vs PHP-FPM Farkı
mod_php Apache’nin içine gömülü çalışır, basit kurulum sunar ama her Apache worker process’i PHP’yi hafızaya yükler. Bu kaynak israfına yol açar ve çoklu sürüm yönetimini zorlaştırır.
PHP-FPM ise ayrı bir process olarak çalışır, her sanal host için farklı sürüm kullanılabilir, kaynak yönetimi çok daha verimlidir ve performans açısından belirgin biçimde üstündür.
Apache Modüllerini Etkinleştirme
# Mevcut aktif modülleri kontrol et
apache2ctl -M | grep php
# Eğer mod_php aktifse devre dışı bırak
sudo a2dismod php7.4
sudo a2dismod php8.1
sudo a2dismod php8.2
# Proxy ve FastCGI modüllerini etkinleştir
sudo a2enmod proxy_fcgi setenvif
# Apache'yi yeniden başlat
sudo systemctl restart apache2
PHP-FPM Pool Yapılandırması
Her PHP sürümü kendi FPM pool dosyasıyla gelir. Bu dosyaları projenize göre özelleştirebilirsiniz.
PHP 8.2 için örnek bir pool yapılandırması:
sudo nano /etc/php/8.2/fpm/pool.d/www.conf
Önemli parametreler şunlardır:
- listen: FPM’in dinleyeceği socket veya port adresi
- pm: Process manager tipi (static, dynamic, ondemand)
- pm.max_children: Maksimum child process sayısı
- pm.start_servers: Başlangıçta açılacak process sayısı
- pm.min_spare_servers: Minimum boşta bekleyen process
- pm.max_spare_servers: Maksimum boşta bekleyen process
- pm.max_requests: Her child process’in kaç istek sonrası yeniden başlatılacağı
Yüksek trafikli bir uygulama için production ortamında şu değerler makul bir başlangıç noktası olabilir:
# /etc/php/8.2/fpm/pool.d/laravel-app.conf
[laravel-app]
user = www-data
group = www-data
listen = /run/php/php8.2-laravel.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
; Uygulama özelinde çevre değişkenleri
env[APP_ENV] = production
env[DB_HOST] = localhost
; PHP ayarlarını pool seviyesinde override et
php_admin_value[error_log] = /var/log/php/laravel-error.log
php_admin_flag[log_errors] = on
php_value[memory_limit] = 256M
php_value[max_execution_time] = 60
Sanal Hostlarda PHP Sürümü Atama
İşte asıl konu burası. Apache sanal hostlarınızı farklı PHP-FPM socket’larına yönlendirerek her site için farklı PHP sürümü kullanabilirsiniz.
Örnek 1: Eski Uygulama PHP 7.4 ile
sudo nano /etc/apache2/sites-available/eski-uygulama.conf
<VirtualHost *:80>
ServerName eski-uygulama.sirket.com
DocumentRoot /var/www/eski-uygulama/public
<Directory /var/www/eski-uygulama/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# PHP 7.4 FPM socket'ını kullan
<FilesMatch .php$>
SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/eski-uygulama-error.log
CustomLog ${APACHE_LOG_DIR}/eski-uygulama-access.log combined
</VirtualHost>
Örnek 2: Yeni Laravel Projesi PHP 8.2 ile
sudo nano /etc/apache2/sites-available/laravel-proje.conf
<VirtualHost *:80>
ServerName laravel.sirket.com
DocumentRoot /var/www/laravel-proje/public
<Directory /var/www/laravel-proje/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# PHP 8.2 FPM socket'ını kullan
<FilesMatch .php$>
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
# Güvenlik başlıkları
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
ErrorLog ${APACHE_LOG_DIR}/laravel-error.log
CustomLog ${APACHE_LOG_DIR}/laravel-access.log combined
</VirtualHost>
Yapılandırmaları aktif hale getirelim:
# Siteleri etkinleştir
sudo a2ensite eski-uygulama.conf
sudo a2ensite laravel-proje.conf
# Headers modülünü etkinleştir
sudo a2enmod headers
# Apache yapılandırmasını test et
sudo apache2ctl configtest
# Her şey tamam ise yeniden yükle
sudo systemctl reload apache2
# FPM servislerini de yeniden başlat
sudo systemctl restart php7.4-fpm
sudo systemctl restart php8.2-fpm
Sistem Genelinde Default PHP Sürümünü Değiştirme
Bazen komut satırı için varsayılan PHP sürümünü değiştirmeniz gerekebilir. Bu durum özellikle Composer veya Artisan komutlarını çalıştırırken önem kazanır.
# Mevcut varsayılan PHP'yi göster
php -v
# update-alternatives ile yönet
sudo update-alternatives --config php
# Belirli bir sürümü doğrudan set et
sudo update-alternatives --set php /usr/bin/php8.2
# CLI için de ayrıca yapılandır
sudo update-alternatives --set phar /usr/bin/phar8.2
sudo update-alternatives --set phar.phar /usr/bin/phar.phar8.2
# Değişikliği doğrula
php -v
PHP Sürümü Doğrulama
Her şeyin doğru çalışıp çalışmadığını test etmek için her sanal host dizinine küçük bir test dosyası bırakabilirsiniz:
# Geçici test dosyası oluştur (production'da kesinlikle silmeli)
sudo bash -c 'echo "<?php echo PHP_VERSION; phpinfo();" > /var/www/laravel-proje/public/phptest.php'
# Curl ile test et
curl -s http://laravel.sirket.com/phptest.php | head -5
# Test dosyasını sil!
sudo rm /var/www/laravel-proje/public/phptest.php
Daha güvenli bir doğrulama yöntemi FPM socket’larını direkt kontrol etmektir:
# Socket dosyalarının varlığını kontrol et
ls -la /run/php/
# FPM process'lerini kontrol et
ps aux | grep php-fpm
# Apache error log'unu izle
sudo tail -f /var/log/apache2/error.log
Gerçek Dünya Senaryosu: Ajans Sunucusu Yapılandırması
Bir dijital ajansın sunucusunu yönettiğinizi düşünün. Sunucunuzda 5 farklı müşteriye ait site var ve her birinin PHP gereksinimleri farklı. İşte bu senaryoyu nasıl çözeceğinize dair pratik bir yaklaşım:
Her müşteri için ayrı FPM pool oluşturun:
# Müşteri A için PHP 8.1 pool
sudo cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/musteri-a.conf
sudo nano /etc/php/8.1/fpm/pool.d/musteri-a.conf
# Pool adını değiştir: [www] yerine [musteri-a]
# Listen değerini değiştir: /run/php/php8.1-musteri-a.sock
# www.conf'u devre dışı bırak (isteğe bağlı)
sudo mv /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/www.conf.disabled
Bu yaklaşımın avantajları şunlardır:
- Her müşterinin PHP sürümü birbirinden bağımsız
- Bir müşterinin sorunlu scripti diğerlerini etkilemiyor
- Her pool için ayrı resource limit tanımlanabiliyor
- Log dosyaları müşteri bazında ayrılabiliyor
- Güvenlik izolasyonu sağlanıyor
PHP-FPM Performans Ayarları
Production ortamında FPM ayarlarını doğru yapılandırmak kritik önem taşır. Sunucunuzun RAM miktarına göre şu formülü kullanabilirsiniz:
Maksimum child process sayısı = (Toplam RAM – İşletim sistemi ve diğer servisler için ayrılan RAM) / Ortalama PHP process RAM kullanımı
Ortalama bir PHP process’i yaklaşık 30-50MB RAM tüketir. 4GB RAM’li bir sunucuda, 1GB’ı sistem için ayırırsanız, geriye 3GB kalır ve bu da yaklaşık 60-100 child process anlamına gelir.
# PHP process'lerinin ortalama RAM kullanımını ölç
ps aux | grep php-fpm | awk '{print $6}' | sort -n | tail -10
# FPM'in durum sayfasını etkinleştir (pool.conf içinde)
# pm.status_path = /fpm-status
# Durum bilgisini görüntüle
curl http://localhost/fpm-status?full
Sorun Giderme
Çoklu PHP yönetiminde karşılaşılan yaygın sorunlar ve çözümleri:
Socket bulunamadı hatası: Apache log’unda “No such file or directory” hatasını görüyorsanız, FPM servisinin çalışıp çalışmadığını ve socket dosyasının var olup olmadığını kontrol edin.
systemctl status php8.2-fpm
ls -la /run/php/php8.2-fpm.sock
Permission denied hatası: Socket dosyasının sahibi ve izinleri yanlış olabilir. FPM pool.conf dosyasında listen.owner ve listen.group değerlerinin www-data olduğunu doğrulayın.
Yanlış PHP sürümü çalışıyor: Apache modül öncelik sorunu olabilir. Tüm mod_php modüllerinin devre dışı olduğunu kontrol edin:
apache2ctl -M | grep php
# Hiçbir php modülü görünmemeli
PHP-FPM başlamıyor: Yapılandırma dosyasında hata olabilir. FPM syntax’ını kontrol edin:
sudo php-fpm8.2 --test
# veya
sudo /usr/sbin/php-fpm8.2 --test
Güvenlik Önerileri
Çoklu PHP ortamlarında güvenliği ihmal etmemek gerekir:
- Kullanılmayan PHP sürümlerini tamamen kaldırın
- Her PHP sürümünü düzenli olarak güncelleyin
open_basedirdirektifini kullanarak her uygulamanın erişebileceği dizinleri sınırlayındisable_functionsile tehlikeli PHP fonksiyonlarını devre dışı bırakın- Production ortamında
expose_php = Offayarını yapın - PHP error’ları ekrana değil log dosyasına yazın
# Her PHP sürümünün php.ini'sini güvenli hale getir
sudo nano /etc/php/8.2/fpm/php.ini
# Değiştirilmesi gereken kritik ayarlar:
# expose_php = Off
# display_errors = Off
# log_errors = On
# error_log = /var/log/php/php8.2-errors.log
Sonuç
Apache üzerinde çoklu PHP yönetimi ilk bakışta karmaşık görünse de sistematik bir yaklaşımla oldukça yönetilebilir bir yapı ortaya çıkıyor. Önemli olan noktalara bir bakalım:
PHP-FPM kullanmak, mod_php’ye kıyasla hem esneklik hem de performans açısından çok daha iyi bir seçim. Her uygulama için ayrı FPM pool oluşturmak, izolasyon ve kaynak yönetimi konusunda size büyük avantaj sağlıyor. Sanal host yapılandırmalarında doğru socket atamasını yapmak, hangi uygulamanın hangi PHP sürümüyle çalışacağını belirlemenin en temiz yolu.
Yeni bir PHP sürümüne geçiş yaparken önce staging ortamında test edin, uygulamanızın deprecated fonksiyonlar kullanıp kullanmadığını kontrol edin ve mümkünse düşük trafikli saatlerde geçişi yapın. Bir şeyler ters giderse hızlıca eski sürüme dönebilmek için FPM socket adresini değiştirmek yeterli olacaktır, bu da çoklu PHP yönetiminin en büyük avantajlarından biri.
Sonuç olarak bu yapıyı bir kez doğru kurduğunuzda, farklı PHP sürümü gerektiren projeleri aynı sunucuda sorunsuzca çalıştırabilir, müşteri taleplerine ya da proje gereksinimlerine göre esnek bir şekilde hareket edebilirsiniz.