Web Hosting & cPanel

    Siteyi Alt Klasörden Yayınlama: Document Root Nasıl Değiştirilir

    Document root değiştirmenin iki yolunu ve .htaccess hilesinin bıraktığı güvenlik ile SEO yan etkilerini anlatan uygulamalı rehber.

    12 dk okuma Güncellendi: 18 Ağustos 2026

    Projeyi FTP ile yüklediniz, dosyalar yerinde, izinler doğru. Ama ornek.com adresine girdiğinizde ya boş bir dizin listesi ya da "Index of /" yazan çıplak bir sayfa karşılıyor sizi. Site sadece ornek.com/public/ yazdığınızda açılıyor. Aynı sorun bir React projesinde ornek.com/dist/, bir Laravel kurulumunda ornek.com/public/, elle yüklenmiş bir tema demosunda ornek.com/site/ biçiminde karşınıza çıkar.

    Bunun sebebi basit: web sunucusu bir alan adına istek geldiğinde diskte tek bir klasöre bakar. Bu klasöre document root (kök dizin) denir ve paylaşımlı hostingte genellikle /home/kullanici/public_html olur. Projenizin açılış dosyası bu klasörün bir alt seviyesindeyse sunucu onu göremez; siz de her adrese elle klasör adı eklemek zorunda kalırsınız.

    Çözümün iki yolu var ve ikisi birbirinin yerine geçmez. Birincisi kök dizini kalıcı olarak taşımak, ikincisi .htaccess ile isteği içeriden alt klasöre yönlendirmek. İkinci yöntem beş dakikada uygulanır ama arkasında iki ciddi yan etki bırakır: URL'lerde çift adres oluşur ve proje kök dizininizdeki gizli dosyalar internete açık kalır. Aşağıda her iki yolu, hangi senaryoda hangisinin doğru olduğunu ve değişiklik sonrası kontrol etmeniz gerekenleri anlatıyorum.

    Document Root Tam Olarak Nedir?#

    Document root, bir alan adına gelen isteğin diskte hangi klasörden karşılanacağını belirleyen tek ayardır. Apache'de DocumentRoot, Nginx'te root direktifiyle tanımlanır. Ziyaretçi ornek.com/urunler/kalem.html istediğinde sunucu bu yolu kök dizinin altına ekler ve /home/kullanici/public_html/urunler/kalem.html dosyasını arar.

    Kritik olan şu: kök dizinin üstünde kalan hiçbir dosyaya web üzerinden erişilemez. Bu bir kısıtlama değil, güvenlik özelliğidir. Veritabanı parolanızı tutan .env dosyasını, vendor/ klasörünü veya günlük kayıtlarınızı kök dizinin bir üstüne koyduğunuzda, biri adresi tahmin etse bile sunucu o dosyayı servis etmez. Modern çatıların (Laravel, Symfony, Slim) neden public/ diye ayrı bir klasör kullandığının cevabı budur: yalnızca o klasör dışarı açılır, gerisi diskte durur ama erişilemez.

    Kök dizinin nerede olduğunu görmek için cPanel'de Domains ekranındaki "Document Root" sütununa bakabilir ya da SSH erişiminiz varsa bir PHP dosyasıyla doğrudan sorabilirsiniz:

    <?php
    echo $_SERVER['DOCUMENT_ROOT'];
    

    Kendi sunucunuzu yönetiyorsanız yapılandırma dosyasından da okuyabilirsiniz:

    # Apache
    grep -R "DocumentRoot" /etc/apache2/sites-enabled/ /etc/httpd/conf.d/ 2>/dev/null
    
    # Nginx
    grep -R "root " /etc/nginx/sites-enabled/ /etc/nginx/conf.d/ 2>/dev/null
    

    Kalıcı Değişiklik mi, .htaccess Hilesi mi?#

    İki yöntem arasındaki farkı önden görmek, sonradan geri dönmekten çok daha ucuz:

    ÖlçütKalıcı kök dizin değişikliği.htaccess yönlendirme
    Uygulama süresiPanel değişikliği veya destek talebiBir dosya, birkaç dakika
    Kök üstündeki dosyalar korunur muEvetHayır, açıkta kalır
    Çift URL sorunuYok/ ve /public/ ikisi de açılır
    Ana alan adında uygulanabilir miGenelde yönetici erişimi gerekirEvet
    Sunucu yüküSıfırHer istekte ek kural işlemesi
    TaşınabilirlikSunucuya bağımlıProje ile birlikte taşınır
    Önerilen kullanımKalıcı kurulumlar, üretimGeçici test, yetki yoksa

    Özet kural şudur: kök dizinini değiştirebiliyorsanız değiştirin. .htaccess yöntemi, kök dizinine müdahale yetkiniz olmadığında başvurulan bir taviz çözümüdür ve bedelini güvenlik tarafında ödersiniz.

    Yöntem 1: Kök Dizini Kalıcı Olarak Değiştirmek#

    cPanel'de ek alan adı ve alt alan adı#

    cPanel'in Domains ekranında yeni bir alan adı veya alt alan adı oluştururken kök dizinini doğrudan siz belirlersiniz. "Create A New Domain" adımında varsayılan olarak /home/kullanici/ornek.com gibi bir yol önerilir; bu kutuyu /home/kullanici/projeler/laravel/public gibi istediğiniz yolla değiştirebilirsiniz.

    Var olan bir ek alan adının kök dizinini de aynı ekrandaki "Manage" bağlantısından güncelleyebilirsiniz. Ek alan adı ve park edilmiş alan adı kavramları karışıyorsa addon ve parked domain farkı yazısı ayrımı netleştirir; alt alan adı oluşturma adımları ise alt alan adı oluşturma yazısında.

    Sık yapılan bir hata: kök dizini public_html dışına, ev dizininin herhangi bir yerine taşıdığınızda dosya sahipliği ve izinler doğru olmazsa 403 alırsınız. Klasörün kullanıcıya ait ve 0755 olduğundan emin olun.

    Ana alan adının kök dizini#

    cPanel arayüzü hesabın birincil alan adının kök dizinini değiştirmenize izin vermez. Bu değişiklik sunucu tarafında, yönetici erişimiyle yapılır. WHM'de kullanıcının sanal host tanımı /var/cpanel/userdata/ altında tutulur:

    # İlgili dosyalar (SSL için ayrı bir kopya vardır)
    /var/cpanel/userdata/kullanici/ornek.com
    /var/cpanel/userdata/kullanici/ornek.com_SSL
    

    Bu dosyalardaki documentroot satırı düzenlendikten sonra yapılandırmanın yeniden üretilmesi gerekir:

    /usr/local/cpanel/scripts/rebuildhttpdconf
    /usr/local/cpanel/scripts/restartsrv_httpd
    

    Paylaşımlı hosting kullanıyorsanız bu adımları siz yapamazsınız; sağlayıcınıza "birincil alan adının kök dizinini /home/kullanici/proje/public yapar mısınız" diye açık bir talep açmanız yeterlidir. Talebi hangi klasörü istediğinizi tam yolla yazarak açın, gidip gelen mesaj sayısı yarıya iner.

    Plesk ve doğrudan sunucu yapılandırması#

    Plesk bu konuda daha esnektir: Websites & Domains → Hosting Settings ekranındaki "Document root" alanını doğrudan düzenleyip kaydedersiniz, ek bir işlem gerekmez.

    Kendi VDS veya fiziksel sunucunuzu yönetiyorsanız değişiklik sanal host dosyasında yapılır. Apache tarafında:

    <VirtualHost *:80>
        ServerName ornek.com
        ServerAlias www.ornek.com
        DocumentRoot /var/www/proje/public
    
        <Directory /var/www/proje/public>
            Options -Indexes +FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
    </VirtualHost>
    

    DocumentRoot satırını değiştirip ilgili <Directory> bloğunu güncellemeyi unutmayın; yalnızca birini değiştirmek 403 hatasının en yaygın sebebidir. Yapılandırmayı uygulamadan önce doğrulayın:

    apachectl configtest
    sudo systemctl reload apache2
    

    Sanal host bloklarının yapısını daha ayrıntılı görmek isterseniz Apache virtual host tanımlama yazısı adım adım ilerliyor.

    Nginx tarafında karşılığı root direktifidir:

    server {
        listen 80;
        server_name ornek.com www.ornek.com;
        root /var/www/proje/public;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    }
    
    sudo nginx -t
    sudo systemctl reload nginx
    

    Yöntem 2: .htaccess ile Alt Klasöre Yönlendirme#

    Kök dizinine dokunamıyorsanız, public_html içine bir .htaccess dosyası koyup gelen istekleri içeriden alt klasöre aktarabilirsiniz. Buradaki kritik nokta, yönlendirmenin dahili olmasıdır: tarayıcının adres çubuğu değişmez, ziyaretçi klasör adını görmez.

    RewriteEngine On
    
    # Zaten hedef klasörün içindeysek tekrar ekleme (sonsuz döngü koruması)
    RewriteCond %{REQUEST_URI} !^/public/
    
    # Her isteği public klasörünün altına taşı
    RewriteRule ^(.*)$ public/$1 [L]
    

    İkinci satır kritik. RewriteCond olmadan kural kendi çıktısını yeniden işler ve public/public/public/... biçiminde bir döngüye girip 500 hatası üretir.

    Alan adına göre ayrıştırmak isterseniz koşulu genişletebilirsiniz:

    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(www\.)?ornek\.com$ [NC]
    RewriteCond %{REQUEST_URI} !^/public/
    RewriteRule ^(.*)$ public/$1 [L]
    

    Bu satırların yazımı ve .htaccess dosyasının nasıl oluşturulacağı konusunda tereddüdünüz varsa htaccess yönlendirme ile htaccess dosyası oluşturma yazıları temel kalıpları içeriyor. Dosyayı sunucuda oluşturmanın en pratik yolu genellikle cPanel dosya yöneticisi üzerinden "gizli dosyaları göster" seçeneğini açmaktır.

    Sembolik bağlantı alternatifi#

    SSH erişiminiz varsa bazen daha temiz bir yol vardır: public_html klasörünü silip yerine hedef klasöre bakan bir sembolik bağlantı koymak.

    rm -rf ~/public_html
    ln -s ~/projeler/laravel/public ~/public_html
    

    Bu yöntem .htaccess kuralı gerektirmez ve URL'lerde iz bırakmaz. Ancak sunucuda SymLinksIfOwnerMatch gibi bir kısıt varsa veya hosting sağlayıcısı sembolik bağlantıları engelliyorsa çalışmaz; ayrıca bazı yedekleme araçları bağlantıyı takip etmeyip klasörü boş görebilir. Uygulamadan önce bir yedek alın.

    .htaccess Hilesinin Sessiz Yan Etkileri#

    Bu bölüm yazının en önemli kısmı, çünkü .htaccess yöntemini uygulayan çoğu kişi aşağıdakileri hiç fark etmez.

    1. Gizli dosyalarınız internete açık kalır. Kök dizini hâlâ public_html'dir. Projenizi public_html/laravel/ altına koyup public_html/laravel/public/ klasörüne yönlendirme yaptıysanız, ornek.com/laravel/.env adresi tarayıcıdan doğrudan indirilebilir. Aynı şey composer.json, storage/logs/laravel.log ve .git/ klasörü için de geçerlidir. Bu, veritabanı parolanızın ve uygulama anahtarınızın açıkta olması demektir.

    Yönlendirme yöntemini kullanmak zorundaysanız bu dosyaları ayrıca kapatın:

    # Hassas dosya ve klasörleri kapat
    RedirectMatch 404 /\.git
    RedirectMatch 404 /\.env
    RedirectMatch 404 /storage/logs
    
    <FilesMatch "^(\.env|composer\.(json|lock)|package-lock\.json)$">
        Require all denied
    </FilesMatch>
    

    Yine de bunun bir yama olduğunu unutmayın; gerçek çözüm dosyaları kök dizinin dışına almaktır.

    2. Aynı sayfa iki adresten açılır. Yönlendirme dahilidir ama ornek.com/public/sayfa adresi de çalışmaya devam eder. Arama motoru her iki adresi de bulursa aynı içeriği iki URL'de indeksleyebilir. Çözüm, her sayfada doğru kanonik etiketi yayımlamak ve /public/ ile başlayan istekleri temiz adrese kalıcı olarak yönlendirmektir:

    RewriteCond %{THE_REQUEST} \s/+public/([^\s]*) [NC]
    RewriteRule ^ /%1 [R=301,L]
    

    301 ile 302 arasındaki farkın neden burada önemli olduğunu 301 mi 302 mi yönlendirme yazısında bulabilirsiniz; kalıcı taşımada 301 kullanmak arama motorunun eski adresi bırakmasını sağlar.

    3. Uygulama kendi yolunu yanlış hesaplayabilir. Bazı betikler dosya yollarını $_SERVER['DOCUMENT_ROOT'] üzerinden kurar. Kök dizini değişmediği için bu değer hâlâ public_html'i gösterir ve uygulama beklediği dosyayı bulamaz. Bu tip kurulumlarda mutlak yol yerine __DIR__ tabanlı hesaplama yapan sürümü tercih edin.

    4. İç içe .htaccess çakışması. Hedef klasörün kendi .htaccess dosyası varsa (Laravel'in public/.htaccess dosyası gibi) iki kural kümesi arka arkaya işlenir. Beklenmedik davranışlarda önce dıştaki kuralı geçici olarak yorum satırına alıp sorunun hangi dosyadan geldiğini ayırın.

    Laravel'i Paylaşımlı Hostingte Doğru Yayınlamak#

    Laravel'de en yaygın hata, tüm proje klasörünü public_html içine kopyalayıp .htaccess ile public/ klasörüne yönlendirmektir. Bu, yukarıdaki birinci maddeyi tetikler: .env dosyanız erişilebilir hale gelir.

    Doğru kurulum şu şekildedir. Proje dosyalarını public_html'in dışına, örneğin /home/kullanici/laravel altına yükleyin. Sonra yalnızca public/ klasörünün içeriğini public_html içine taşıyın ve public_html/index.php dosyasındaki iki yolu güncelleyin:

    require __DIR__.'/../laravel/vendor/autoload.php';
    
    $app = require_once __DIR__.'/../laravel/bootstrap/app.php';
    

    Ardından depolama bağlantısını yeniden kurmanız gerekir, çünkü php artisan storage:link varsayılan yolu artık geçerli değildir:

    cd ~/laravel
    rm -f ~/public_html/storage
    ln -s ~/laravel/storage/app/public ~/public_html/storage
    

    Klasör izinlerini de kontrol edin; storage ve bootstrap/cache yazılabilir olmalıdır:

    chmod -R 775 ~/laravel/storage ~/laravel/bootstrap/cache
    

    Bu düzende kök dizini public_html olarak kalır ama proje dosyaları zaten dışarıdadır; yani hem yetkiye ihtiyaç duymazsınız hem de güvenlik açığı oluşmaz. Kök dizinini değiştirebiliyorsanız daha da temizi, hiçbir dosyayı taşımadan kök dizini doğrudan /home/kullanici/laravel/public yapmaktır.

    React, Vue ve Build Çıktısını Yayınlamak#

    Vite veya benzeri bir araçla derlenen projelerde çıktı dist/, Create React App tabanlı projelerde build/ klasörüne düşer. Burada üç seçeneğiniz var:

    1. Kök dizini dist yapın. En temiz yöntem. Ek alan adı veya alt alan adı oluştururken kök dizinini doğrudan dist klasörüne verirsiniz.
    2. Build çıktısını public_html içine kopyalayın. Yayınlama adımınıza tek satır ekleyerek çözülür ve yetki gerektirmez.
    3. Alt dizin altında yayınlayın. Site gerçekten ornek.com/uygulama/ altında duracaksa, derleme yapılandırmasında temel yolu belirtmeniz gerekir; aksi halde varlıklar /assets/... isteyip 404 alır.
    # Vite: alt dizinde yayın için temel yol
    npm run build -- --base=/uygulama/
    

    Tek sayfalık uygulamalarda ikinci bir ayrıntı daha var: istemci tarafı yönlendirme kullanıyorsanız, ornek.com/hakkimizda adresini yenilediğinizde sunucu diskte böyle bir dosya bulamaz ve 404 döner. Tüm istekleri index.html dosyasına yönlendirmeniz gerekir:

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ index.html [L]
    

    Node.js tarafında çalışan bir uygulama yayınlıyorsanız durum farklıdır; orada kök dizini değil uygulama kökü ve başlangıç dosyası tanımlanır. Ayrıntılar için Node.js uygulamasını cPanel'de yayınlama yazısına bakabilirsiniz.

    Tek Hesapta Birden Fazla Proje Barındırmak#

    Aynı hosting hesabında birkaç projeyi ayrı ayrı yayınlamak istiyorsanız, .htaccess hileleri üst üste bindirmek yerine her projeye kendi alan adını veya alt alan adını verin. Önerilen düzen şudur:

    /home/kullanici/
    ├── public_html/              → ornek.com          (ana site)
    ├── projeler/
    │   ├── panel/public/         → panel.ornek.com    (alt alan adı)
    │   ├── api/public/           → api.ornek.com      (alt alan adı)
    │   └── magaza/dist/          → magaza.com.tr      (ek alan adı)
    

    Her alt alan adı oluştururken kök dizinini ilgili public veya dist klasörüne verirsiniz. Bu düzenin üç avantajı var: projeler birbirinin .htaccess kurallarını etkilemez, her biri kendi SSL sertifikasını alır ve bir projeyi silmek diğerlerine dokunmaz.

    Var olan bir WordPress kurulumunu alt dizinden köke taşıma senaryosu ise ayrı bir konudur, çünkü orada veritabanındaki adreslerin de güncellenmesi gerekir; bunun için WordPress'i alt dizinden taşıma yazısı adım adım ilerliyor.

    Değişiklik Sonrası Kontrol Listesi ve Sık Hatalar#

    Kök dizinini değiştirdikten sonra beş dakikada aşağıdakileri doğrulayın:

    1. Ana sayfa açılıyor mu, adres çubuğunda klasör adı görünüyor mu?
    2. Bir alt sayfayı yenilediğinizde 404 alıyor musunuz?
    3. ornek.com/.env ve ornek.com/.git/config adresleri 403 ya da 404 dönüyor mu?
    4. SSL sertifikası hâlâ geçerli mi? Bazı panellerde kök dizin değişikliği sonrası doğrulama dosyasının yolu değiştiği için sertifika yenilemesi başarısız olabilir.
    5. Yükleme klasörleri (görseller, ekler) hâlâ erişilebilir mi?

    Sık karşılaşılan üç hata ve sebepleri:

    BelirtiMuhtemel sebepÇözüm
    500 Internal Server ErrorYeniden yazma kuralı sonsuz döngüye girdiRewriteCond %{REQUEST_URI} !^/klasor/ koşulunu ekleyin
    403 ForbiddenKlasör izni yanlış veya <Directory> bloğu güncellenmediKlasörü 0755 yapın, sanal host bloğunu kontrol edin
    Dizin listesi görünüyorKök dizinde index.php/index.html yokDoğru klasörü hedeflediğinizden emin olun, Options -Indexes ekleyin

    Son bir uyarı: .htaccess üzerinde çalışırken her zaman dosyanın bir kopyasını alın. Yanlış tek bir satır tüm siteyi 500 hatasına düşürür ve bu durumda sitenin kendisinden geri dönemezsiniz; dosyaya FTP veya panel üzerinden erişmeniz gerekir. Değişikliği canlıya almadan önce mümkünse bir alt alan adında deneyin.

    Sıkça Sorulan Sorular#

    Ana alan adımın kök dizinini cPanel'den neden değiştiremiyorum?#

    Birincil alan adının kök dizini hesap oluşturulurken sunucu tarafında sabitlenir ve cPanel arayüzü bu değeri düzenlemeye izin vermez. Değişiklik WHM veya sunucu yapılandırması üzerinden, yönetici yetkisiyle yapılır. Paylaşımlı hosting kullanıyorsanız sağlayıcınıza istediğiniz tam klasör yolunu yazarak bir destek talebi açmanız en hızlı yoldur. Ek alan adları ve alt alan adları için ise bu kısıt yoktur.

    .htaccess ile yönlendirme yaparsam SEO'm zarar görür mü?#

    Dahili yönlendirme adres çubuğunu değiştirmediği için tek başına zarar vermez. Asıl risk, aynı içeriğin hem /sayfa hem /public/sayfa adresinden açılabilir kalmasıdır. Bunu her sayfada doğru kanonik etiketi yayımlayarak ve /public/ ile başlayan istekleri 301 ile temiz adrese yönlendirerek çözersiniz. Bu iki önlemi almazsanız arama motoru hangi adresi tercih edeceğine kendi karar verir.

    Kök dizinini değiştirdikten sonra SSL sertifikam bozuldu, ne yapmalıyım?#

    Otomatik sertifika yenilemesi genellikle kök dizin altında bir doğrulama dosyası oluşturur. Kök dizin değişince bu yol geçersiz kalır ve yenileme başarısız olur. Panelinizden sertifikayı elle yeniden düzenleyin; cPanel kullanıyorsanız AutoSSL'i tekrar çalıştırmak çoğu durumda yeterlidir. Yeni kök dizinin altında .well-known klasörünün oluşturulabildiğinden ve bir yeniden yazma kuralıyla engellenmediğinden emin olun.

    Sembolik bağlantı yöntemi paylaşımlı hostingte çalışır mı?#

    Bazı sunucularda çalışır, bazılarında engellenir. Apache'nin SymLinksIfOwnerMatch ayarı açıksa bağlantı ile hedefin aynı kullanıcıya ait olması gerekir; bazı sağlayıcılar güvenlik gerekçesiyle sembolik bağlantıları tamamen kapatır. Denemeden önce mevcut public_html klasörünüzün yedeğini alın, çünkü yöntem klasörü silmenizi gerektirir. Çalışmazsa bağlantıyı kaldırıp klasörü geri koymanız yeterlidir.

    Laravel projemi olduğu gibi public_html içine yüklersem ne olur?#

    Site çalışır ama .env dosyanız, composer.json dosyanız ve storage/logs altındaki kayıt dosyalarınız tarayıcıdan doğrudan indirilebilir hale gelir. Bu, veritabanı parolanızın ve uygulama anahtarınızın açıkta olması demektir. Doğru yol, proje dosyalarını public_html dışına koyup yalnızca public klasörünün içeriğini web'e açmak ve index.php içindeki iki yolu güncellemektir.

    Alt dizinde çalışan siteyi köke taşıdıktan sonra eski adresler ne olacak?#

    Eski adresleri kalıcı yönlendirmeyle yeni adreslere bağlamanız gerekir; aksi halde arama sonuçlarındaki ve dış sitelerdeki bağlantılar 404 döner. .htaccess içinde /eski-klasor/ ile başlayan istekleri 301 ile karşılığına yönlendiren bir kural yazın. WordPress gibi veritabanında adres tutan sistemlerde ayrıca içerik içindeki bağlantıların da güncellenmesi gerekir.

    HostingApachecPanel

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.