Tek bir sunucuda yalnızca tek bir site yayınlamak, çoğu durumda kaynakların büyük kısmının boşa gitmesi anlamına gelir. Modern bir VPS ya da dedicated makine, onlarca hatta yüzlerce alan adını rahatlıkla taşıyabilir; bunu yapmanın Apache dünyasındaki yolu ise virtual host (sanal ana bilgisayar) tanımlamaktır. Virtual host, aynı Apache örneği üzerinde her alan adının kendi kök dizinine, kendi loglarına ve kendi ayarlarına sahip olmasını sağlayan yapı taşıdır.
Bu yazıda tek bir IP adresi üzerinde birden çok domaini nasıl barındıracağınızı baştan sona ele alacağız: VirtualHost bloğunun anatomisi, ServerName ve ServerAlias ile alan adı eşleme, DocumentRoot ve Directory izinleri, Debian/Ubuntu tarafında a2ensite ile siteyi etkinleştirme ve son olarak 443 portu için SSL virtual host tanımlama. Örnekler gerçekçi olacak; kopyalayıp kendi sunucunuzda uyarlayabileceğiniz komutlarla ilerleyeceğiz.
Virtual Host Nedir ve Ad Tabanlı Barındırma Nasıl Çalışır?#
Apache'nin bir isteği hangi siteye ait olduğunu anlaması gerekir. Sunucunuzun tek bir IP adresi olsa bile, aynı anda ornek.com, baskasite.com ve blog.ornek.com gibi farklı alan adlarına hizmet verebilmesinin nedeni ad tabanlı barındırma (name-based virtual hosting) yöntemidir.
Bunun sırrı HTTP protokolündeki Host başlığında saklıdır. Tarayıcı ornek.com adresine bağlandığında, kurduğu istekte Host: ornek.com bilgisini de gönderir. Apache gelen bu başlığa bakar, tanımlı virtual host'lar arasında ServerName veya ServerAlias değeri eşleşeni bulur ve isteği o siteye ait DocumentRoot dizinine yönlendirir. Böylece tek bir 80/443 portu, tek bir IP, sınırsız sayıda alan adına hizmet verebilir.
Eskiden her siteye ayrı bir IP gerektiren IP tabanlı barındırma da vardı, ancak IPv4 adresleri kıt ve pahalı olduğu için bugün neredeyse tamamen ad tabanlı yönteme geçilmiştir. Pratikte tek IP'li bir sunucuda onlarca site barındırmak tamamen normaldir; nitekim paylaşımlı hosting ve reseller hosting mimarilerinin temelinde de aynı mantık yatar.
Bir noktayı baştan netleştirelim: ad tabanlı barındırmanın çalışması için alan adlarının DNS'te sunucunuzun IP'sine yönlendirilmiş olması şarttır. ornek.com A kaydı sunucunuzu göstermiyorsa, virtual host tanımınız ne kadar doğru olursa olsun trafik hiç ulaşmaz. Domaininizi sunucuya bağlama adımlarını gözden geçirmek isterseniz alan adı tarafını ayrı ele almanız faydalı olur.
Temel VirtualHost Bloğunun Anatomisi#
Bir virtual host, <VirtualHost> ve </VirtualHost> etiketleri arasına yazılan bir yapılandırma bloğudur. En sade haliyle 80 portunu dinleyen bir site şöyle görünür:
<VirtualHost *:80>
ServerName ornek.com
ServerAlias www.ornek.com
DocumentRoot /var/www/ornek.com/public
ErrorLog ${APACHE_LOG_DIR}/ornek.com-error.log
CustomLog ${APACHE_LOG_DIR}/ornek.com-access.log combined
</VirtualHost>
Bu bloğun her satırının bir görevi vardır:
<VirtualHost *:80>— Bu virtual host'un tüm IP adreslerinde (*) 80 portundan gelen istekleri karşılayacağını söyler.*yerine belirli bir IP de yazabilirsiniz (<VirtualHost 192.0.2.10:80>), ama tek IP'li ad tabanlı kurulumlarda*yaygın kullanımdır.ServerName— Bu sitenin ana alan adı. Apache gelenHostbaşlığını bu değerle eşleştirir.ServerAlias— Aynı siteye ait ek adlar (örneğinwwwalt alan adı ya da eski bir domain).DocumentRoot— Sitenin dosyalarının bulunduğu kök dizin. Ziyaretçiornek.com/hakkimizdaisterse, Apache/var/www/ornek.com/public/hakkimizdayolunu arar.ErrorLog/CustomLog— Her siteye ayrı log tutmak, çoklu barındırmada sorun tespitini çok kolaylaştırır.${APACHE_LOG_DIR}Debian/Ubuntu'da/var/log/apache2dizinine karşılık gelir.
İkinci bir siteyi eklemek için tek yapmanız gereken, aynı yapıda ama farklı ServerName ve DocumentRoot değerleriyle yeni bir blok tanımlamaktır:
<VirtualHost *:80>
ServerName baskasite.com
ServerAlias www.baskasite.com
DocumentRoot /var/www/baskasite.com/public
ErrorLog ${APACHE_LOG_DIR}/baskasite.com-error.log
CustomLog ${APACHE_LOG_DIR}/baskasite.com-access.log combined
</VirtualHost>
İki blok aynı *:80 portunu dinlese de Apache, Host başlığına göre isteği doğru bloğa yönlendirir. İşte ad tabanlı barındırmanın tüm inceliği bu kadar basittir.
ServerName, ServerAlias ve Varsayılan Site Mantığı#
Alan adı eşlemesini doğru kurmak, çoklu barındırmada en sık hata yapılan yerdir. Birkaç kritik davranışı bilmek işinizi kolaylaştırır.
ServerName tam ve tekildir. Her virtual host'un yalnızca bir ServerName değeri olmalıdır. Sitenizin hem www'lu hem www'suz halinde çalışmasını istiyorsanız, www sürümünü ServerAlias olarak eklemeniz gerekir. Aksi halde www.ornek.com isteği eşleşecek bir blok bulamayabilir.
ServerAlias joker karakter kabul eder. Bir alt alan adı grubunu tek seferde yakalamak için * kullanabilirsiniz:
<VirtualHost *:80>
ServerName ornek.com
ServerAlias www.ornek.com *.ornek.com
DocumentRoot /var/www/ornek.com/public
</VirtualHost>
Buradaki *.ornek.com sayesinde blog.ornek.com, magaza.ornek.com gibi tüm alt alan adları aynı dizine düşer. Her alt alan adını ayrı bir siteye yönlendirmek isterseniz, her biri için ayrı virtual host bloğu yazarsınız.
İlk tanımlı virtual host varsayılandır. Apache, hiçbir ServerName eşleşmeyen bir istek aldığında (örneğin doğrudan IP'ye bağlanan biri ya da tanımsız bir domain) yapılandırmada ilk sırada yer alan virtual host'u kullanır. Bu davranış çoğu zaman istenmeyen sonuçlar doğurur: yanlış bir domainin içeriği başka bir sitede görünebilir. Bunu kontrol altına almak için genellikle özel bir "catch-all" varsayılan site tanımlanır:
<VirtualHost *:80>
ServerName varsayilan.ornek.com
DocumentRoot /var/www/default
# Eşleşmeyen tüm istekler buraya düşer
</VirtualHost>
Bu varsayılan bloğu yapılandırmanın en başında bırakırsanız, tanımsız istekler gerçek sitelerinizin içeriğini sızdırmak yerine nötr bir sayfaya yönlenir. Apache'nin hangi isteği hangi virtual host'a eşlediğini görmek için apachectl -S komutunu kullanabilirsiniz; bu komut, tanımlı tüm virtual host'ları ve hangisinin varsayılan olduğunu listeler.
DocumentRoot ve Directory İzinlerini Doğru Ayarlamak#
DocumentRoot yalnızca bir yol belirtir; ancak Apache'nin o dizindeki dosyalara gerçekten erişebilmesi için bir <Directory> bloğuyla izin vermeniz gerekir. Modern Apache 2.4 sürümlerinde erişim varsayılan olarak reddedilir; açıkça izin vermezseniz ziyaretçiler 403 Forbidden hatası alır.
Tam bir yapılandırma şöyle görünür:
<VirtualHost *:80>
ServerName ornek.com
ServerAlias www.ornek.com
DocumentRoot /var/www/ornek.com/public
<Directory /var/www/ornek.com/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/ornek.com-error.log
CustomLog ${APACHE_LOG_DIR}/ornek.com-access.log combined
</VirtualHost>
<Directory> bloğundaki her direktif önemlidir:
Options -Indexes— Dizin içindeindex.html/index.phpyoksa dosya listesinin gösterilmesini engeller. Bir güvenlik önlemidir; ziyaretçilerin klasör içeriğini görmesini istemezsiniz.Options +FollowSymLinks— Sembolik bağların takip edilmesine izin verir; birçok uygulama buna ihtiyaç duyar.AllowOverride All— Bu dizindeki.htaccessdosyalarının ana yapılandırmayı geçersiz kılmasına izin verir. WordPress gibi kalıcı bağlantı (permalink) ve yönlendirme kuralı yazan uygulamalar için gereklidir..htaccessile neler yapabileceğinizi htaccess yönlendirme rehberimizde ayrıntılı bulabilirsiniz.Require all granted— Erişimi açıkça izin verir. Apache 2.4'te eskiOrder allow,denysözdiziminin yerini alan direktif budur.
Dosya sistemi izinleri de en az bu yapılandırma kadar önemlidir. Dizinlerin Apache kullanıcısı (Debian/Ubuntu'da www-data) tarafından okunabilir olması gerekir:
sudo mkdir -p /var/www/ornek.com/public
sudo chown -R www-data:www-data /var/www/ornek.com
sudo chmod -R 755 /var/www/ornek.com
Genel kural şudur: dizinler 755, dosyalar 644 iznine sahip olmalı ve web sunucusunun yazması gereken yükleme klasörleri dışında hiçbir şey 777 olmamalıdır. İzin mantığını tazelemek isterseniz Linux dosya izinleri konusuna ayrı bir göz atmak faydalıdır.
Siteyi Etkinleştirme: a2ensite ve Dizin Yapısı#
Yapılandırmayı yazmak yeterli değildir; Apache'nin onu okuması için etkinleştirmeniz gerekir. Burada Debian/Ubuntu ile CentOS/RHEL ailesi arasında önemli bir fark vardır.
Debian ve Ubuntu'da virtual host dosyaları iki dizinle yönetilir:
/etc/apache2/sites-available/— Tanımladığınız tüm site dosyaları burada durur (etkin olsun olmasın)./etc/apache2/sites-enabled/— Yalnızca aktif siteler burada bir sembolik bağ olarak bulunur.
Yeni bir siteyi tipik olarak alan adıyla adlandırılan bir .conf dosyasında tanımlarsınız:
sudo nano /etc/apache2/sites-available/ornek.com.conf
İçine virtual host bloğunu yazıp kaydettikten sonra siteyi etkinleştirmek için a2ensite komutunu kullanırsınız. Bu komut, arka planda sites-enabled içine bir sembolik bağ oluşturur:
sudo a2ensite ornek.com.conf
sudo systemctl reload apache2
Bir siteyi geçici olarak devre dışı bırakmak isterseniz karşıt komut a2dissite'dir:
sudo a2dissite ornek.com.conf
sudo systemctl reload apache2
Değişikliği uygulamadan önce her zaman yapılandırmayı test edin. Küçük bir yazım hatası tüm Apache servisini başlatılamaz hale getirebilir; bu yüzden reload öncesi sözdizimi kontrolü hayat kurtarır:
sudo apache2ctl configtest
# Çıktı "Syntax OK" ise güvenle reload edebilirsiniz
CentOS, AlmaLinux ve Rocky Linux tarafında a2ensite/a2dissite komutları yoktur. Bunun yerine virtual host dosyalarını doğrudan /etc/httpd/conf.d/ dizinine .conf uzantısıyla koyarsınız; Apache bu dizindeki tüm .conf dosyalarını otomatik yükler. Test ve yeniden yükleme komutları da farklıdır:
sudo apachectl configtest
sudo systemctl reload httpd
Aşağıdaki tablo iki dağıtım ailesi arasındaki farkları özetler:
| Konu | Debian / Ubuntu | CentOS / AlmaLinux / Rocky |
|---|---|---|
| Servis adı | apache2 | httpd |
| Ana yapılandırma | /etc/apache2/apache2.conf | /etc/httpd/conf/httpd.conf |
| Site dosyaları | sites-available + sites-enabled | /etc/httpd/conf.d/ |
| Etkinleştirme | a2ensite | Dosyayı conf.d'ye koymak yeterli |
| Log dizini | /var/log/apache2 | /var/log/httpd |
| Apache kullanıcısı | www-data | apache |
Bu farkları bilmek, sunucu türleri arasında geçiş yaparken kafa karışıklığını önler. Kendi sunucunuzu sıfırdan kuruyorsanız Apache kurulumu ve yapılandırma rehberi temel adımları ayrıca gösterir.
443 için SSL Virtual Host Tanımlama#
Bugün her sitenin HTTPS üzerinden yayınlanması artık bir zorunluluk. HTTPS trafiği 443 portundan geldiği için, 80 portundaki virtual host'unuza ek olarak 443 için ayrı bir virtual host tanımlamanız gerekir. İki bloğu birlikte kullanmak en yaygın kalıptır: 80 portu tüm trafiği HTTPS'e yönlendirir, 443 portu ise asıl siteyi sertifikayla sunar.
# HTTP -> HTTPS yönlendirmesi
<VirtualHost *:80>
ServerName ornek.com
ServerAlias www.ornek.com
Redirect permanent / https://ornek.com/
</VirtualHost>
# Asıl SSL sitesi
<VirtualHost *:443>
ServerName ornek.com
ServerAlias www.ornek.com
DocumentRoot /var/www/ornek.com/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/ornek.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ornek.com/privkey.pem
<Directory /var/www/ornek.com/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/ornek.com-ssl-error.log
CustomLog ${APACHE_LOG_DIR}/ornek.com-ssl-access.log combined
</VirtualHost>
Bu yapılandırmanın çalışması için Apache'nin SSL modülünün etkin olması gerekir. Debian/Ubuntu'da tek komutla açarsınız:
sudo a2enmod ssl
sudo systemctl reload apache2
Sertifikayı elle yönetmek yerine Let's Encrypt kullanıyorsanız, certbot'un Apache eklentisi virtual host'ları otomatik okuyup 443 bloğunu ve yönlendirmeyi sizin yerinize oluşturabilir:
sudo certbot --apache -d ornek.com -d www.ornek.com
Certbot ayrıca sertifikanın 90 günlük geçerlilik süresi dolmadan otomatik yenilenmesi için bir zamanlanmış görev de kurar. Ücretsiz sertifika sürecinin ayrıntılarını Let's Encrypt ücretsiz SSL yazısında bulabilir, kurumsal ihtiyaçlar için ise farklı doğrulama seviyeli SSL çözümlerine bakabilirsiniz.
Birden çok siteyi SSL ile barındırırken her domain için ayrı bir 443 virtual host bloğu tanımlarsınız; her biri kendi sertifikasını gösterir. Apache 2.4 ve modern istemciler SNI (Server Name Indication) desteklediği için, tek IP üzerinde birden çok SSL sertifikasını sorunsuz sunabilirsiniz — her siteye ayrı IP gerekmez.
Çoklu Site Yönetiminde Sık Karşılaşılan Sorunlar#
Virtual host mantığını kavradıktan sonra karşınıza çıkabilecek tipik sorunları ve çözümlerini bilmek zaman kazandırır.
Yanlış site görünüyor. İki domainden biri ötekinin içeriğini gösteriyorsa, büyük olasılıkla bir ServerName eksik ya da hatalıdır ve istek varsayılan virtual host'a düşüyordur. apachectl -S ile eşlemeleri kontrol edin; hangi bloğun varsayılan olduğunu ve her domainin nereye eşlendiğini net görürsünüz.
403 Forbidden hatası. Neredeyse her zaman ya <Directory> bloğunda Require all granted eksiktir ya da dosya sistemi izinleri yanlıştır. Önce yapılandırmayı, sonra chown/chmod değerlerini kontrol edin.
Değişiklik uygulanmıyor. Yeni bir site ekleyip reload etmeyi unutmak ya da Debian/Ubuntu'da a2ensite çalıştırmamak en yaygın sebeptir. Sözdizimi hatası varsa reload sessizce başarısız olabilir; bu yüzden önce configtest çalıştırın.
Belirli bir siteyi izole etmek. Farklı müşterilere ait siteleri güvenlik açısından birbirinden ayırmak isterseniz, sadece ayrı log ve dizin yetmez; PHP tarafında php-fpm havuzlarını ayrı kullanıcılarla çalıştırmak ya da CloudLinux gibi bir çözümle hesapları kabuklamak gerekir. Bu tür bir izolasyonu hazır sunan yönetimli bir altyapı arıyorsanız, tüm bu virtual host ve izin ayarlarının panelden yapıldığı web hosting veya reseller hosting paketleri iş yükünüzü ciddi biçimde azaltır.
Apache'nin ad tabanlı barındırma mantığı ile Nginx'in aynı işi yapış biçimini karşılaştırmak isterseniz, mimari farkları ele aldığımız Apache mı Nginx mi yazısı iyi bir devam noktasıdır. Sunucu yönetimini kendiniz üstlenmek istemiyorsanız, kurulum ve bakımı bizim üstlendiğimiz sunucu yönetimi hizmetiyle bu konfigürasyonları uzman ellere bırakabilirsiniz.
Sıkça Sorulan Sorular#
Tek IP ile kaç farklı alan adı barındırabilirim?#
Pratikte belirgin bir üst sınır yoktur; ad tabanlı barındırma sayesinde tek bir IP üzerinde onlarca hatta yüzlerce domaini barındırabilirsiniz. Asıl sınırı IP değil, sunucunuzun CPU, RAM ve disk kaynakları belirler. Her site için ayrı bir virtual host bloğu tanımlamanız ve alan adlarının DNS'te aynı IP'yi göstermesi yeterlidir.
ServerName ile ServerAlias arasındaki fark nedir?#
ServerName sitenin ana ve tekil alan adıdır; her virtual host'ta yalnızca bir tane bulunur. ServerAlias ise aynı siteye ait ek adları tanımlar, örneğin www alt alan adını ya da joker *.ornek.com ile tüm alt alan adlarını. İkisini birlikte kullanarak hem www'lu hem www'suz erişimi tek bloğa yönlendirebilirsiniz.
a2ensite komutu CentOS'ta neden çalışmıyor?#
a2ensite ve a2dissite yalnızca Debian ve Ubuntu ailesine özgü yardımcı betiklerdir. CentOS, AlmaLinux ve Rocky Linux'ta bu komutlar yoktur; bunun yerine virtual host dosyanızı doğrudan /etc/httpd/conf.d/ dizinine .conf uzantısıyla koymanız yeterlidir. Apache o dizindeki tüm yapılandırmaları otomatik yükler, ardından systemctl reload httpd ile değişikliği uygularsınız.
Sitem 403 Forbidden hatası veriyor, neyi kaçırıyorum?#
Bu hatanın en yaygın iki nedeni vardır. Ya virtual host içindeki <Directory> bloğunda Require all granted direktifi eksiktir, ya da DocumentRoot dizininin dosya sistemi izinleri Apache kullanıcısının okumasına izin vermiyordur. Önce yapılandırmayı kontrol edin, sonra dizinlerin 755, dosyaların 644 iznine ve doğru sahipliğe (www-data veya apache) sahip olduğundan emin olun.
Aynı sunucuda birden çok SSL sertifikasını tek IP ile kullanabilir miyim?#
Evet, kesinlikle mümkündür. Modern Apache ve tarayıcılar SNI (Server Name Indication) teknolojisini desteklediği için, her domain kendi sertifikasını gösteren ayrı bir 443 virtual host bloğuyla tek IP üzerinde barındırılabilir. Eskiden her SSL sitesi için ayrı IP gerekirdi, ancak SNI bu kısıtı ortadan kaldırdı; bu yüzden bugün tek IP'li bir sunucuda düzinelerce HTTPS sitesi rahatlıkla çalışır.
Yeni virtual host ekledim ama değişiklik görünmüyor, ne yapmalıyım?#
Önce yapılandırmayı apache2ctl configtest (veya apachectl configtest) ile test edin; bir sözdizimi hatası varsa Apache değişikliği uygulamayı reddeder. Çıktı "Syntax OK" ise Debian/Ubuntu'da siteyi a2ensite ile etkinleştirdiğinizden ve ardından systemctl reload apache2 çalıştırdığınızdan emin olun. Tarayıcı önbelleği de yanıltabilir; kesin sonuç için gizli pencerede veya curl ile test etmek daha güvenlidir.
Kapanış#
Apache virtual host, tek bir sunucudan onlarca siteyi bağımsız biçimde yayınlamanın standart ve güçlü yoludur. Temelinde yatan mantık aslında sadedir: her alan adı için ServerName, DocumentRoot ve Directory izinlerini doğru tanımlayan bir blok yazmak, siteyi a2ensite ile etkinleştirmek ve 443 portu için ayrı bir SSL bloğuyla HTTPS'i devreye almak. Bu kalıbı bir kez kavradığınızda, ister iki site ister yüz site barındırın, süreç hep aynı adımlardan ibaret kalır.
Bu tür yapılandırmaları özgürce deneyebileceğiniz, kök erişimine sahip olduğunuz bir zemin arıyorsanız yüksek performanslı VDS sunucu ve sanal sunucu seçeneklerimize göz atabilirsiniz. Sunucu yönetimini kendiniz üstlenmek istemiyor, virtual host ve SSL ayarlarının panel üzerinden hazır geldiği bir çözüm istiyorsanız web hosting paketlerimiz ya da tüm bakımı bizim yürüttüğümüz sunucu yönetimi hizmetimiz işinizi baştan sona kolaylaştırır.