Apache Virtual Host ile Çoklu Domain Yönetimi

Birden fazla web sitesini tek bir sunucuda yönetmek, sistem yöneticilerinin günlük hayatının vazgeçilmez bir parçası. Küçük bir VPS’ten kurumsal bir sunucuya kadar, Apache’nin Virtual Host özelliği bu işi hem esnek hem de yönetilebilir kılıyor. Bu yazıda gerçek dünya senaryolarıyla Apache Virtual Host yapılandırmasını en ince ayrıntısına kadar inceleyeceğiz.

Apache Virtual Host Nedir ve Neden Önemlidir?

Apache’de Virtual Host (sanal sunucu), tek bir fiziksel makine üzerinde birden fazla web sitesini barındırmanızı sağlayan mekanizmadır. Sunucunuzun tek bir IP adresi olsa bile, gelen HTTP isteğinin Host başlığına bakarak hangi sitenin içeriğini sunacağına karar verir.

İki tür Virtual Host yapılandırması vardır:

  • IP tabanlı Virtual Host: Her site için ayrı bir IP adresi gerektirir, günümüzde nadiren kullanılır
  • İsim tabanlı Virtual Host: Tek IP üzerinde birden fazla domain çalışır, modern kurulumların standartı budur

Bugün odaklanacağımız isim tabanlı yapılandırmadır. Bir ajans düşünün; müşterilerin sitelerini aynı sunucuda barındırıyor. Müşteri sayısı 20’ye çıktığında her biri için ayrı sunucu almak saçmalık olur. İşte Virtual Host tam burada devreye giriyor.

Ön Hazırlık ve Apache Kurulumu

Başlamadan önce sisteminizin hazır olduğundan emin olalım. Ubuntu/Debian tabanlı sistemlerde:

sudo apt update && sudo apt upgrade -y
sudo apt install apache2 -y
sudo systemctl enable apache2
sudo systemctl start apache2
sudo systemctl status apache2

CentOS/RHEL tabanlı sistemlerde ise:

sudo dnf install httpd -y
sudo systemctl enable httpd
sudo systemctl start httpd
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Apache kurulduktan sonra servis adının farklı olduğuna dikkat edin: Debian ailesinde apache2, Red Hat ailesinde httpd. Bu yazıda Ubuntu/Debian üzerinden ilerleyeceğiz ama Red Hat farkları için not düşeceğiz.

Dizin Yapısını Kurmak

Düzenli bir yapı, ileride başınızı ağrıtmaz. Her domain için kendi dizinini oluşturun:

# Site dizinlerini oluştur
sudo mkdir -p /var/www/sirket1.com/public_html
sudo mkdir -p /var/www/sirket2.com/public_html
sudo mkdir -p /var/www/blog.sirket1.com/public_html

# Log dizinlerini oluştur
sudo mkdir -p /var/www/sirket1.com/logs
sudo mkdir -p /var/www/sirket2.com/logs

# Sahipliği ayarla
sudo chown -R $USER:$USER /var/www/sirket1.com
sudo chown -R $USER:$USER /var/www/sirket2.com

# İzinleri düzenle
sudo chmod -R 755 /var/www

Şimdi test için basit HTML dosyaları oluşturalım:

echo "<h1>Sirket1.com'a Hosgeldiniz!</h1>" | sudo tee /var/www/sirket1.com/public_html/index.html
echo "<h1>Sirket2.com'a Hosgeldiniz!</h1>" | sudo tee /var/www/sirket2.com/public_html/index.html

İlk Virtual Host Yapılandırma Dosyasını Oluşturmak

Apache’de her site için ayrı bir .conf dosyası oluşturmak en iyi pratiktir. Bu dosyalar /etc/apache2/sites-available/ dizininde tutulur.

sudo nano /etc/apache2/sites-available/sirket1.com.conf

Dosyanın içeriği şöyle olsun:

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName sirket1.com
    ServerAlias www.sirket1.com
    DocumentRoot /var/www/sirket1.com/public_html

    ErrorLog /var/www/sirket1.com/logs/error.log
    CustomLog /var/www/sirket1.com/logs/access.log combined

    <Directory /var/www/sirket1.com/public_html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Buradaki direktifleri açıklayalım:

  • ServerAdmin: Hata sayfalarında görünecek yönetici e-posta adresi
  • ServerName: Birincil domain adı, Apache bu değere göre eşleşme yapar
  • ServerAlias: Aynı siteye yönlendirilecek ek domain isimleri, birden fazla yazabilirsiniz
  • DocumentRoot: Sitenin dosyalarının bulunduğu kök dizin
  • ErrorLog / CustomLog: Site özelinde log dosyaları, sorun gidermede hayat kurtarır
  • AllowOverride All: .htaccess dosyalarının çalışmasına izin verir, WordPress gibi CMS’ler için şart
  • Options Indexes: Dizin listesi gösterimi, genellikle kapatmak istersiniz

Virtual Host’u Aktif Etmek

Apache’de siteleri aktif etmek için a2ensite komutunu kullanıyoruz:

# Siteleri aktif et
sudo a2ensite sirket1.com.conf
sudo a2ensite sirket2.com.conf

# Varsayılan siteyi kapat (isteğe bağlı ama tavsiye edilir)
sudo a2dissite 000-default.conf

# Yapılandırmayı test et
sudo apache2ctl configtest

# Apache'yi yeniden yükle
sudo systemctl reload apache2

apache2ctl configtest komutu kritik öneme sahip. Syntax hatası varsa bunu söyler ve servisi bozmadan önce fırsatınız olur. Her değişiklikten sonra bu komutu çalıştırın, bu alışkanlık sizi ciddi downtime’lardan kurtarır.

Red Hat sistemlerinde a2ensite yoktur, doğrudan /etc/httpd/conf.d/ dizinine .conf dosyası oluşturursunuz ve otomatik yüklenir.

İkinci Senaryo: Subdomain Yönetimi

Gerçek dünyada sadece farklı domainler değil, alt domainler de sık karşılaşılan ihtiyaçtır. Bir şirketin hem www.sirket.com hem api.sirket.com hem de blog.sirket.com adresleri olabilir.

sudo nano /etc/apache2/sites-available/api.sirket1.com.conf
<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName api.sirket1.com
    DocumentRoot /var/www/api.sirket1.com/public_html

    ErrorLog /var/www/api.sirket1.com/logs/error.log
    CustomLog /var/www/api.sirket1.com/logs/access.log combined

    # API sunucusu icin ozel ayarlar
    <Directory /var/www/api.sirket1.com/public_html>
        Options -Indexes
        AllowOverride All
        Require all granted
    </Directory>

    # CORS basliklarini ekle
    Header always set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
</VirtualHost>

Burada Options -Indexes kullandık. Eksi işareti, dizin listelemeyi kapattığımız anlamına gelir. API endpointi için dosya listeleme kesinlikle istemezsiniz.

HTTPS ile Virtual Host Yapılandırması

2024 yılında HTTPS olmadan web sitesi olmaz. Let’s Encrypt ile ücretsiz SSL sertifikası alıp Virtual Host’a entegre edelim:

# Certbot kurulumu
sudo apt install certbot python3-certbot-apache -y

# Sertifika al ve Apache'yi otomatik yapılandır
sudo certbot --apache -d sirket1.com -d www.sirket1.com

# Tum siteler icin toplu sertifika
sudo certbot --apache -d sirket2.com -d www.sirket2.com

Certbot Apache yapılandırmanızı otomatik günceller ama manuel yapmak da isterseniz:

sudo nano /etc/apache2/sites-available/sirket1.com-ssl.conf
<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName sirket1.com
    ServerAlias www.sirket1.com
    DocumentRoot /var/www/sirket1.com/public_html

    # SSL Ayarlari
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/sirket1.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/sirket1.com/privkey.pem

    # Guvenli SSL Protokolleri
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
    SSLHonorCipherOrder off
    SSLSessionTickets off

    # Guvenlik Basliklar
    Header always set Strict-Transport-Security "max-age=63072000"
    Header always set X-Frame-Options DENY
    Header always set X-Content-Type-Options nosniff

    ErrorLog /var/www/sirket1.com/logs/error.log
    CustomLog /var/www/sirket1.com/logs/access.log combined

    <Directory /var/www/sirket1.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

# HTTP'den HTTPS'e yonlendirme
<VirtualHost *:80>
    ServerName sirket1.com
    ServerAlias www.sirket1.com
    Redirect permanent / https://sirket1.com/
</VirtualHost>

SSL yapılandırması için gerekli modülleri aktif etmeyi unutmayın:

sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod rewrite
sudo systemctl restart apache2

Reverse Proxy ile Virtual Host Kullanımı

Modern altyapılarda Apache sadece statik dosya sunmaz; arka planda çalışan Node.js, Python veya Java uygulamalarına trafiği iletmek için de kullanılır. Bu senaryo ajans ortamlarında çok yaygındır.

Diyelim ki app.sirket1.com adresine gelen istekleri 3000 portunda çalışan bir Node.js uygulamasına iletmek istiyorsunuz:

# Gerekli modulleri aktif et
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests

sudo nano /etc/apache2/sites-available/app.sirket1.com.conf
<VirtualHost *:80>
    ServerName app.sirket1.com

    ProxyPreserveHost On
    ProxyRequests Off

    # Tum istekleri Node.js uygulamasina ilet
    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/

    # WebSocket destegi (gerekirse)
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule ^/?(.*) "ws://127.0.0.1:3000/$1" [P,L]

    ErrorLog /var/log/apache2/app.sirket1.com-error.log
    CustomLog /var/log/apache2/app.sirket1.com-access.log combined
</VirtualHost>

Erişim Kontrolü ve Güvenlik Ayarları

Bazı Virtual Host’lar herkese açık olmamalı. Örneğin şirket içi bir yönetim paneli veya staging ortamı sadece belirli IP’lerden erişilebilir olsun:

<VirtualHost *:80>
    ServerName staging.sirket1.com
    DocumentRoot /var/www/staging.sirket1.com/public_html

    <Directory /var/www/staging.sirket1.com/public_html>
        Options -Indexes
        AllowOverride All

        # Sadece ofis IP'si ve VPN'den erisim
        Require ip 203.0.113.50
        Require ip 10.0.0.0/8
    </Directory>

    # Temel kimlik dogrulama ekle
    <Location "/">
        AuthType Basic
        AuthName "Staging Ortami - Yetkili Giris"
        AuthUserFile /etc/apache2/.htpasswd
        Require valid-user
    </Location>

    ErrorLog /var/log/apache2/staging-error.log
    CustomLog /var/log/apache2/staging-access.log combined
</VirtualHost>

Kullanıcı oluşturmak için:

# Ilk kullanici (dosyayi olusturur)
sudo htpasswd -c /etc/apache2/.htpasswd testkullanici

# Ek kullanici ekle
sudo htpasswd /etc/apache2/.htpasswd ikincikisi

Sorun Giderme: Sık Karşılaşılan Hatalar

403 Forbidden Hatası

Bu hata genellikle dizin izinlerinden kaynaklanır:

# Hata logunu kontrol et
sudo tail -f /var/log/apache2/error.log

# Dizin izinlerini kontrol et
ls -la /var/www/sirket1.com/

# Sahiplik sorunu varsa duzelt
sudo chown -R www-data:www-data /var/www/sirket1.com/public_html
sudo chmod -R 755 /var/www/sirket1.com/

404 Not Found Hatası

Virtual Host yapılandırması doğru ama site gelmiyor:

# Aktif siteleri listele
sudo apache2ctl -S

# DNS cozumlemesini test et (yerel test icin hosts dosyasini kullan)
echo "127.0.0.1 sirket1.com www.sirket1.com" | sudo tee -a /etc/hosts

# Curl ile test et
curl -H "Host: sirket1.com" http://localhost/

ServerName Uyarısı

Apache başlarken Could not reliably determine the server's fully qualified domain name uyarısı alıyorsanız:

echo "ServerName localhost" | sudo tee /etc/apache2/conf-available/servername.conf
sudo a2enconf servername
sudo systemctl reload apache2

Performans Optimizasyonu için Virtual Host Ayarları

Çok sayıda Virtual Host çalışıyorsa performans ayarlarına dikkat etmek gerekir:

sudo nano /etc/apache2/sites-available/sirket1.com.conf

Mevcut yapılandırmaya şunları ekleyin:

<VirtualHost *:443>
    ServerName sirket1.com
    DocumentRoot /var/www/sirket1.com/public_html

    # Gzip sikistirma
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/html text/css application/javascript
        AddOutputFilterByType DEFLATE application/json application/xml
    </IfModule>

    # Tarayici onbellekleme
    <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresByType image/jpg "access plus 1 year"
        ExpiresByType image/jpeg "access plus 1 year"
        ExpiresByType image/png "access plus 1 year"
        ExpiresByType text/css "access plus 1 month"
        ExpiresByType application/javascript "access plus 1 month"
    </IfModule>

    # Keep-Alive
    KeepAlive On
    KeepAliveTimeout 5
    MaxKeepAliveRequests 100
</VirtualHost>

Bu modülleri aktif edin:

sudo a2enmod deflate
sudo a2enmod expires
sudo apache2ctl configtest && sudo systemctl reload apache2

Virtual Host Durumunu İzlemek

Sunucunuzda kaç Virtual Host çalıştığını ve hangisinin hangi isteğe cevap verdiğini görmek için:

# Tum aktif Virtual Host'lari listele
sudo apache2ctl -S

# Hangi portlar dinleniyor
sudo ss -tlnp | grep apache

# Baglanti sayisini izle
sudo apache2ctl status

# Gercek zamanli log takibi
sudo tail -f /var/www/sirket1.com/logs/access.log | grep -v "bot|crawler"

apache2ctl -S komutunun çıktısı gerçekten işe yarıyor. Hangi domain’in hangi yapılandırma dosyasına bağlandığını, port çakışmaları olup olmadığını net gösteriyor. Sorun gidermede ilk başvurulacak komut bu olmalı.

Yapılandırma Yönetimi İçin Pratik İpuçları

Onlarca müşteri sitesi yönetiyorsanız bazı küçük alışkanlıklar büyük fark yaratır:

  • Şablon kullanın: Standart bir .conf dosyası şablonu oluşturup sed ile domain adını değiştirerek yeni site ekleyin
  • Sürüm kontrolü: /etc/apache2/ dizinini Git ile takip edin, her değişiklik kayıt altında olsun
  • Log rotasyonu: /etc/logrotate.d/apache2 dosyasını kontrol edin, log dosyaları disk doldurmaz
  • Düzenli test: Her Pazar gece certbot renew --dry-run ile SSL sertifika yenileme testini yapın
  • Yedekleme: Yeni site eklemeden önce mevcut .conf dosyalarını yedekleyin

Özellikle şablon konusunu biraz açalım. Bash scripti ile yeni site eklemeyi otomatikleştirmek mümkün:

#!/bin/bash
DOMAIN=$1
sudo mkdir -p /var/www/$DOMAIN/{public_html,logs}
sudo chown -R www-data:www-data /var/www/$DOMAIN
cat > /etc/apache2/sites-available/$DOMAIN.conf << EOF
<VirtualHost *:80>
    ServerName $DOMAIN
    ServerAlias www.$DOMAIN
    DocumentRoot /var/www/$DOMAIN/public_html
    ErrorLog /var/www/$DOMAIN/logs/error.log
    CustomLog /var/www/$DOMAIN/logs/access.log combined
    <Directory /var/www/$DOMAIN/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
EOF
sudo a2ensite $DOMAIN.conf
sudo apache2ctl configtest && sudo systemctl reload apache2
echo "$DOMAIN basariyla eklendi!"

Bu scripti /usr/local/bin/add-vhost.sh olarak kaydedin ve chmod +x ile çalıştırılabilir yapın. Artık yeni site eklemek tek komutla olur: sudo add-vhost.sh musteri3.com

Sonuç

Apache Virtual Host yapılandırması ilk bakışta karmaşık görünse de mantığı kavradıktan sonra son derece yönetilebilir bir sistem haline geliyor. Önemli olan tutarlı bir dosya yapısı kurmak, her değişiklik öncesi configtest yapmak ve log dosyalarını aktif olarak takip etmek.

Gerçek ortamlarda en çok zaman alan şey yapılandırmayı yazmak değil, DNS yayılmasını beklemek ve SSL sertifika sorunlarını çözmektir. Bunun için curl -H "Host: domain.com" komutu ve yerel hosts dosyası günlük araçlarınız arasına girsin.

Ajans veya hosting ortamında bu altyapıyı otomatize etmek için yazıda paylaştığımız bash scriptini ihtiyaçlarınıza göre genişletin. Birkaç düzine müşteri sitesini tek bir sunucuda sağlıklı yönetmek tamamen mümkün; önemli olan düzenli yapı ve iyi dokümantasyon. Sunucunuzu bir kaos yerine iyi organize edilmiş bir kitaplık gibi düşünün, her şeyin bir yeri olsun ve herkes o yeri bilsin.

Yorum yapın