Kullanıcılar bir web sitesinde hatayla karşılaştığında, o anın nasıl yönetildiği hem kullanıcı deneyimi hem de profesyonellik açısından kritik öneme sahip. Apache’nin varsayılan hata sayfaları çirkin, bilgi verici değil ve marka kimliğinizle hiç uyuşmuyor. “Not Found” yazan beyaz bir sayfa, ziyaretçinizi anında kaçırabilir. Bu yazıda Apache hata sayfalarını nasıl özelleştireceğinizi, hata yönetimini nasıl düzgün kurgulamanız gerektiğini ve gerçek dünya senaryolarında ne gibi sorunlarla karşılaşabileceğinizi ele alıyoruz.
Apache Hata Sayfası Yönetiminin Temelleri
Apache, HTTP hata kodlarını ErrorDocument direktifi ile yönetir. Bu direktif son derece esnektir; bir metin mesajı, dahili bir URL ya da harici bir URL gösterebilirsiniz.
Temel sözdizimi şöyledir:
ErrorDocument hata_kodu hedef
En sık kullanılan HTTP hata kodları şunlardır:
- 400: Bad Request – Hatalı istek
- 401: Unauthorized – Kimlik doğrulama gerekiyor
- 403: Forbidden – Erişim yasak
- 404: Not Found – Sayfa bulunamadı
- 500: Internal Server Error – Sunucu iç hatası
- 502: Bad Gateway – Arka uç bağlantı hatası
- 503: Service Unavailable – Servis geçici olarak kullanım dışı
Yapılandırmayı httpd.conf dosyasına, sanal host bloğuna ya da .htaccess dosyasına ekleyebilirsiniz. Hangi yolu seçeceğiniz kurumsal politikanıza ve projenin kapsamına bağlıdır.
Basit Metin Tabanlı Hata Mesajları
Hızlı bir test ortamı için ya da geçici bir çözüm olarak doğrudan metin kullanabilirsiniz:
ErrorDocument 404 "Bu sayfa mevcut değil. Lütfen ana sayfaya dönün."
ErrorDocument 403 "Bu kaynağa erişim yetkiniz bulunmuyor."
ErrorDocument 500 "Sunucumuzda bir sorun yaşandı. Ekibimiz bilgilendirildi."
Ancak bu yöntem üretim ortamları için yeterli değildir. Ne marka kimliği taşır ne de kullanıcıyı yönlendirme konusunda yeterince yardımcı olur.
Özel HTML Hata Sayfaları Oluşturma
Dizin Yapısını Hazırlamak
Önce hata sayfalarınızı tutacak bir dizin yapısı oluşturun:
mkdir -p /var/www/html/errors
touch /var/www/html/errors/404.html
touch /var/www/html/errors/403.html
touch /var/www/html/errors/500.html
touch /var/www/html/errors/503.html
Örnek 404 Hata Sayfası
Aşağıda basit ama işlevsel bir 404 sayfası örneği var:
cat > /var/www/html/errors/404.html << 'EOF'
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 - Sayfa Bulunamadı</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
text-align: center;
background: white;
padding: 50px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 { color: #e74c3c; font-size: 72px; margin: 0; }
h2 { color: #333; }
p { color: #666; }
a {
display: inline-block;
margin-top: 20px;
padding: 10px 25px;
background: #3498db;
color: white;
text-decoration: none;
border-radius: 5px;
}
a:hover { background: #2980b9; }
</style>
</head>
<body>
<div class="container">
<h1>404</h1>
<h2>Aradığınız Sayfa Bulunamadı</h2>
<p>Aradığınız sayfa taşınmış, silinmiş veya hiç var olmamış olabilir.</p>
<a href="/">Ana Sayfaya Dön</a>
</div>
</body>
</html>
EOF
Apache Yapılandırmasına Entegre Etmek
Sanal host bloğunuza veya ana yapılandırma dosyanıza şunları ekleyin:
# /etc/apache2/sites-available/siteadiniz.conf veya httpd.conf
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
# Hata sayfaları
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
ErrorDocument 502 /errors/502.html
ErrorDocument 503 /errors/503.html
# Hata sayfaları dizinine erişim izni
Alias /errors /var/www/html/errors
<Directory /var/www/html/errors>
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
Yapılandırmayı kontrol edip Apache’yi yeniden yükleyin:
# Syntax kontrolü
apachectl configtest
# Yapılandırmayı uygula
systemctl reload apache2
# veya RHEL/CentOS için:
systemctl reload httpd
.htaccess ile Hata Yönetimi
Sunucu yapılandırmasına erişiminiz yoksa ya da dizin bazında özelleştirme istiyorsanız .htaccess kullanabilirsiniz. Önce AllowOverride direktifinin etkin olduğundan emin olun:
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
Ardından .htaccess dosyasına ekleyin:
# /var/www/html/.htaccess
Options -Indexes
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
# Eski URL'leri yenilerine yönlendirme
RewriteEngine On
RewriteRule ^eski-sayfa$ /yeni-sayfa [R=301,L]
Önemli Not: .htaccess kullanımı performans açısından maliyetlidir. Her istek için Apache, dizin ağacındaki tüm .htaccess dosyalarını okur. Üretim ortamlarında mümkün olduğunca ana yapılandırmayı tercih edin.
PHP veya Dinamik Hata Sayfaları
Statik HTML yerine dinamik içerik sunan hata sayfaları da oluşturabilirsiniz. Bu özellikle büyük uygulamalarda işe yarar:
# PHP tabanlı hata sayfası örneği
cat > /var/www/html/errors/404.php << 'EOF'
<?php
// Hata bilgilerini loglayabilirsiniz
$request_uri = $_SERVER['REQUEST_URI'] ?? 'Bilinmiyor';
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Bilinmiyor';
$timestamp = date('Y-m-d H:i:s');
// Log dosyasına yaz
file_put_contents(
'/var/log/apache2/custom_404.log',
"[$timestamp] 404: $request_uri | UA: $user_agentn",
FILE_APPEND
);
// HTTP durum kodunu doğru gönder
http_response_code(404);
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>404 - Sayfa Bulunamadı</title>
</head>
<body>
<h1>404 - Sayfa Bulunamadı</h1>
<p>Aradığınız sayfa: <strong><?= htmlspecialchars($request_uri) ?></strong></p>
<p><a href="/">Ana sayfaya dönmek için tıklayın</a></p>
</body>
</html>
EOF
Yapılandırmada PHP dosyasını işaret edin:
ErrorDocument 404 /errors/404.php
Hata Günlüklerini Doğru Yapılandırmak
Hata sayfaları özelleştirmenin yarısı; diğer yarısı bu hataları düzgün kayıt altına almak. Apache’nin loglama direktiflerini doğru kurmak, sorunları tespit etmek açısından kritiktir:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
# Erişim logu
LogFormat "%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
CustomLog /var/log/apache2/example_access.log combined
# Hata logu
ErrorLog /var/log/apache2/example_error.log
LogLevel warn
# Sadece 4xx ve 5xx hatalarını ayrı loga yaz
CustomLog /var/log/apache2/example_errors_only.log combined env=!no_log
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
</VirtualHost>
Hata loglarını gerçek zamanlı takip etmek için:
# Hata logunu takip et
tail -f /var/log/apache2/example_error.log
# Sadece 404 hatalarını filtrele
grep " 404 " /var/log/apache2/example_access.log | tail -20
# En çok 404 alan URL'leri listele
awk '$9 == 404 {print $7}' /var/log/apache2/example_access.log | sort | uniq -c | sort -rn | head -10
Gerçek Dünya Senaryosu: Bakım Modu
Üretim ortamında güncelleme ya da bakım yaparken kullanıcılara düzgün bir bildirim sayfası göstermek önemli. İşte bunu Apache ile nasıl yapacağınız:
# Bakım sayfasını oluştur
cat > /var/www/html/maintenance.html << 'EOF'
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>Bakım Çalışması</title>
<meta http-equiv="refresh" content="60">
</head>
<body style="font-family:Arial;text-align:center;padding:50px;">
<h1>Bakım Çalışması</h1>
<p>Sitemizde kısa süreli bakım çalışması yapılmaktadır.</p>
<p>En kısa sürede geri döneceğiz. Anlayışınız için teşekkürler.</p>
<p><small>Sayfa 60 saniyede otomatik yenilenecektir.</small></p>
</body>
</html>
EOF
# Bakım modunu devreye al
cat >> /var/www/html/.htaccess << 'EOF'
# Bakım Modu
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^192.168.1.100$
RewriteCond %{REQUEST_URI} !/maintenance.html$
RewriteRule ^(.*)$ /maintenance.html [R=503,L]
ErrorDocument 503 /maintenance.html
EOF
Bu yapılandırmada 192.168.1.100 IP adresinden gelen istekler (yani sizin IP’niz) siteni normal görürken diğer ziyaretçiler 503 sayfasını görür.
Bakım modundan çıkmak için sadece .htaccess‘ten ilgili satırları silin ve Apache’yi yeniden yükleyin.
Güvenlik Açısından Hata Sayfaları
Hata sayfaları bazen istemeden bilgi sızdırabilir. Özellikle 500 hatalarında sunucu altyapınız, framework sürümünüz veya veritabanı yapınız hakkında ipucu verebilir. Bunu önlemek için:
# httpd.conf veya apache2.conf
# Sunucu imzasını gizle
ServerSignature Off
ServerTokens Prod
# Hata mesajlarında detay gösterme
# (PHP için ayrıca php.ini'de display_errors = Off yapılmalı)
Ayrıca 403 sayfaları için dikkatli olun. Kullanıcıya “bu dizin mevcut ama erişemezsiniz” yerine “sayfa bulunamadı” göstermek güvenlik açısından daha akıllıca olabilir:
# Dizin listelemeyi devre dışı bırak, 403 yerine 404 göster
<Directory /var/www/html/private>
Options -Indexes
Require all denied
</Directory>
ErrorDocument 403 /errors/404.html
Özel Hata Sayfalarında Sık Yapılan Hatalar
HTTP durum kodunun kaybolması problemi: Özellikle harici URL yönlendirmelerinde Apache 302 kodu döndürür, orijinal hata kodunu değil. Bu SEO ve uygulama mantığı açısından sorun yaratır. Her zaman dahili URL veya yerel dosya kullanın:
# YANLIS - Harici yönlendirme, 302 döner
ErrorDocument 404 http://example.com/errors/404.html
# DOGRU - Dahili yol, 404 korunur
ErrorDocument 404 /errors/404.html
CSS ve JS kaynaklarının yüklenmemesi: Hata sayfanızdaki CSS veya JavaScript dosyaları da 404 alıyorsa döngüsel sorun çıkabilir. Inline CSS kullanmak ya da mutlak yollarla kaynak çağırmak bu sorunu önler.
Hata sayfasının kendisinin hata vermesi: 404 sayfanız bir PHP dosyasıysa ve PHP hata veriyorsa, Apache varsayılan hata sayfasına dönebilir. Bu yüzden hata sayfalarınızı minimal ve bağımsız tutun.
Birden Fazla Sanal Host İçin Merkezi Yönetim
Onlarca sanal hostu olan bir sunucuda her birine ayrı ayrı hata sayfası eklemek zaman kaybıdır. Bunu merkezi bir yapıyla yönetebilirsiniz:
# /etc/apache2/conf-available/custom-errors.conf
# Global hata sayfaları
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
ErrorDocument 502 /errors/502.html
ErrorDocument 503 /errors/503.html
ErrorDocument 504 /errors/504.html
# Hata sayfaları için alias
Alias /errors /var/www/common/errors
<Directory /var/www/common/errors>
AllowOverride None
Require all granted
Options -Indexes
</Directory>
Bu dosyayı etkinleştirin:
# Debian/Ubuntu
a2enconf custom-errors
systemctl reload apache2
# RHEL/CentOS için dosyayı conf.d dizinine kopyalayın
cp /etc/httpd/conf/custom-errors.conf /etc/httpd/conf.d/
systemctl reload httpd
Sanal hostlar bu merkezi ayarları miras alır, isterlerse kendi ErrorDocument direktifleriyle üstüne yazabilirler.
mod_proxy Arkasında Hata Yönetimi
Apache’yi reverse proxy olarak kullanıyorsanız ve arka uç servis (Node.js, Tomcat, vb.) cevap vermiyorsa, özel hata sayfalarının çalışması için ek ayar gerekir:
<VirtualHost *:80>
ServerName app.example.com
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
# Proxy hataları için custom sayfalar
ProxyErrorOverride On
ErrorDocument 502 /errors/502.html
ErrorDocument 503 /errors/503.html
ErrorDocument 504 /errors/504.html
# Hata sayfalarına doğrudan erişim için
<Location /errors>
ProxyPass !
</Location>
Alias /errors /var/www/html/errors
<Directory /var/www/html/errors>
Require all granted
</Directory>
</VirtualHost>
ProxyErrorOverride On direktifi olmadan Apache, arka uç uygulamanın hata sayfasını doğrudan iletir. Bu direktifle kendi özel sayfalarınızı gösterebilirsiniz.
Logrotate ile Hata Loglarını Yönetmek
Özelleştirilmiş hata loglarınız zamanla büyüyebilir. Logrotate konfigürasyonu:
cat > /etc/logrotate.d/apache2-custom << 'EOF'
/var/log/apache2/example_error.log
/var/log/apache2/example_errors_only.log
/var/log/apache2/custom_404.log
{
daily
rotate 30
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
if /etc/init.d/apache2 status > /dev/null 2>&1; then
/etc/init.d/apache2 reload > /dev/null 2>&1
fi
endscript
}
EOF
Hata İzleme ve Alarm Sistemi
Üretim ortamında 500 hatalarının artışını fark etmek için basit bir izleme scripti:
#!/bin/bash
# /usr/local/bin/check_500_errors.sh
LOG_FILE="/var/log/apache2/example_access.log"
THRESHOLD=10
EMAIL="[email protected]"
WINDOW=5 # Dakika
# Son 5 dakikadaki 500 hatalarını say
COUNT=$(awk -v d="$(date -d "$WINDOW minutes ago" "+%d/%b/%Y:%H:%M")"
'$4 > "["d && $9 == 500' "$LOG_FILE" | wc -l)
if [ "$COUNT" -gt "$THRESHOLD" ]; then
echo "UYARI: Son $WINDOW dakikada $COUNT adet 500 hatası tespit edildi!" |
mail -s "Apache 500 Hata Alarmı - $(hostname)" "$EMAIL"
fi
Bunu cron’a ekleyin:
# Her 5 dakikada bir çalıştır
*/5 * * * * /usr/local/bin/check_500_errors.sh
Yapılandırma Değişikliklerini Test Etmek
Hata sayfalarınızın doğru çalıştığını test etmek için:
# curl ile HTTP durum kodunu kontrol et
curl -o /dev/null -s -w "%{http_code}n" http://example.com/olmayan-sayfa
# Yanıt başlıklarını da gör
curl -I http://example.com/olmayan-sayfa
# Hata sayfasının içeriğini doğrula
curl -s http://example.com/olmayan-sayfa | grep -i "404"
# Apache yapılandırmasını yeniden kontrol et
apachectl -t
Sonuç
Apache hata sayfası özelleştirmesi görünürde küçük bir detay gibi dursa da doğru uygulandığında hem kullanıcı deneyimini hem de sistem yönetimini ciddi şekilde iyileştirir. Ziyaretçinin karşılaştığı ilk hata sayfası, sitenizin profesyonelliğini yansıtır. Öte yandan iyi yapılandırılmış loglama ve izleme sistemi, sorunları erken tespit etmenizi sağlar.
Özetlemek gerekirse:
- Statik hata sayfaları basit siteler için yeterlidir, dinamik siteler için PHP tabanlı sayfaları tercih edin
- Her zaman dahili URL kullanın, harici yönlendirmeden kaçının
ServerSignature OffveServerTokens Prodile sunucu bilgilerini gizleyin- Reverse proxy kullanıyorsanız
ProxyErrorOverride Ondirektifini eklemeyi unutmayın - Hata loglarını düzenli takip edin ve anlamlı alarm mekanizmaları kurun
- Çok sayıda sanal host varsa merkezi yapılandırmayı tercih edin
Bunları bir kez doğru kurduğunuzda hem kullanıcılarınız hem de gece 2’de telefonu kapatıp uyuyan kendiniz teşekkür edecek.