2026年6月30日
2026年6月30日
Apacheのサブディレクトリ設定方法|Aliasと.htaccessでexample.com/blog/を動かす
example.com/blog/ のように、1つのドメインの下の階層(サブディレクトリ)で別のサイトやアプリを動かすには、Apache でその URL をどのディレクトリに対応させるかを決め、<Directory> で権限を与えます。WordPress を置く場合は、さらに .htaccess の書き換えルールをサブディレクトリ用にする必要があります。この記事では、ドキュメントルートの中に置く方法と Alias で外の場所を割り当てる方法、WordPress をサブディレクトリで動かすときの .htaccess、親ディレクトリの WordPress と衝突したときの対処、確認方法を説明します。サブドメイン(blog.example.com)で分ける方法とは別の話なので、どちらにするか迷っている場合は最初の節から読んでください。
サブディレクトリとサブドメインの違い
同じドメインで別のサイトを動かす方法には、サブディレクトリ(example.com/blog/)とサブドメイン(blog.example.com)があります。
サブディレクトリは、DNS や証明書を追加せずに始められ、1つの VirtualHost の中で完結します。その反面、親のサイトと設定(.htaccess の書き換えルール、PHP の設定、アクセス制限)が影響し合いやすく、この記事で扱う調整が必要になります。サブドメインは VirtualHost を分けるため設定は独立しますが、DNS レコードと証明書の追加が必要です。
検索エンジンにとってどちらが有利という決まりはありません。運用の独立性を重視するならサブドメイン、1つのサイトの一部として見せたいならサブディレクトリ、という考え方で選ぶのが現実的です。
方法1:ドキュメントルートの中に置く
最も単純なのは、ドキュメントルートの下にディレクトリを作ってファイルを置く方法です。ドキュメントルートが /var/www/html なら、/var/www/html/blog/ に置いたファイルがそのまま https://example.com/blog/ で公開されます。Apache の設定を変える必要はありません。
WordPress を置く場合は、.htaccess を使えるよう、ドキュメントルートの <Directory> で AllowOverride が許可されている必要があります。
<Directory /var/www/html>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
AllowOverride None のままだと .htaccess が読まれず、トップページは開けても個別の投稿が 404 になります。パーマリンクの書き換えだけが目的なら AllowOverride FileInfo でも動きますが、プラグインが .htaccess に書き込む設定の種類によっては足りないことがあります。
方法2:Alias でドキュメントルートの外を割り当てる
アプリのファイルを /srv/blog のような別の場所に置き、URL の /blog だけをそこに対応させるには Alias を使います。VirtualHost の中に書きます。
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html
Alias /blog /srv/blog
<Directory /srv/blog>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Alias の URL 側とディレクトリ側は、末尾のスラッシュの有無を揃えます。Alias /blog/ /srv/blog/ のように URL 側に末尾のスラッシュを付けると、/blog(スラッシュなし)のリクエストは対応付けられません。スラッシュなしで書いておけば、/blog へのアクセスは mod_dir によって /blog/ へ転送されます。
<Directory> を書き忘れると、Apache 2.4 の標準設定ではドキュメントルート外へのアクセスが拒否されているため 403 になり、エラーログに「client denied by server configuration」という内容が記録されます。
Alias の利点は、親サイトのファイルとアプリのファイルが物理的に分かれることです。.htaccess はファイルの実際の置き場所をもとに探されるため、/var/www/html/.htaccess(親サイトの設定)は /srv/blog には適用されません。親サイトが WordPress の場合に起きやすい衝突を避けられます。
設定ファイルを変更する前にはバックアップを取り、構文を確認してから反映します。
sudo apachectl configtest
sudo systemctl reload apache2 # RHEL系は httpd
WordPress をサブディレクトリで動かす .htaccess
WordPress を /blog/ に置いた場合、パーマリンク設定を保存すると、WordPress はサブディレクトリ用の書き換えルールを /blog/.htaccess に書き込みます。中身は次のような形です。
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
ポイントは RewriteBase /blog/ と、最後の行の転送先が /blog/index.php になっていることです。ルートに置いた WordPress の .htaccess をそのままコピーすると転送先が /index.php になり、親サイト側にリクエストが渡ってしまいます。Alias で割り当てた場合は、RewriteBase で URL 上の位置を指定しないと書き換えが正しく働かないため、この行は省略しないでください。
WordPress の「設定」→「一般」の WordPress アドレス(URL)とサイトアドレス(URL)は、両方とも https://example.com/blog にします(2026年10月現在)。画面の項目名はバージョンによって変わる可能性があります。
親ディレクトリにも WordPress がある場合
ドキュメントルートに親サイトの WordPress があり、その中の blog/ ディレクトリに別の WordPress を置く構成はよくあります。mod_rewrite の .htaccess では、サブディレクトリの .htaccess に RewriteEngine On と書き換えルールがあれば、そちらが優先され、親の書き換えルールは引き継がれません。そのため、/blog/.htaccess が正しく置かれていれば、多くの場合は問題なく動きます。
問題が起きやすいのは、サブディレクトリに置いたものが WordPress 以外で、.htaccess を持たない場合です。この場合は親の WordPress の書き換えルールが適用され、/blog/ の中の存在しない URL へのリクエストが親の WordPress に渡されて、親サイトの 404 ページが表示されます。対策として、親の .htaccess の # BEGIN WordPress より前に、そのディレクトリを書き換えの対象から外す行を加えます。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^blog/ - [L]
</IfModule>
あるいは、前述の Alias を使ってファイルの置き場所を分けると、この衝突自体が起きなくなります。
よくある症状と確認する順番
投稿ページだけ 404 になる
.htaccess が読まれていない可能性が高い状態です。<Directory> の AllowOverride が None になっていないか、mod_rewrite が有効か(apachectl -M | grep rewrite)を確認します。
403 Forbidden になる
エラーログを確認します。「client denied by server configuration」なら <Directory> の Require が足りません。Options FollowSymLinks or SymLinksIfOwnerMatch is off という内容なら、Options に FollowSymLinks を加えます。ファイルの所有者や権限も、Apache の実行ユーザーが読める状態かを確認します。
親サイトのページが表示される
/blog/.htaccess の転送先が /index.php のままになっていないか、RewriteBase が /blog/ になっているかを確認します。
確認は curl で行うと、ブラウザのキャッシュに左右されません。
curl -sI https://example.com/blog | grep -i -E "^(HTTP|location)"
curl -sI https://example.com/blog/sample-post/ | grep -i "^HTTP"
1つ目で /blog/ への 301 が返り、2つ目で投稿ページが 200 になれば設定は正しく動いています。
既存のサイトをサブディレクトリへ移す場合
ルートで動いていた WordPress を /blog/ に移すと、すべての URL が変わります。データベース内の URL の置き換えと、旧 URL から新 URL への 301 リダイレクトが必要です。WP-CLI を使える場合は、まず --dry-run で置き換え件数を確認してから実行します。作業の前には、ファイルとデータベースの両方のバックアップを取り、可能であれば検証環境で試してください。
wp search-replace 'https://example.com' 'https://example.com/blog' --skip-columns=guid --dry-run
なお、「WordPress 本体のファイルはサブディレクトリに置き、サイトの URL はルートのままにする」という使い方もあります。これは WordPress の公式ドキュメントで「WordPress に専用ディレクトリを与える」方法として説明されている別の手順で、本記事の設定とは目的が異なります。
まとめ
- サブディレクトリでの公開は、ドキュメントルートの中に置くか、
Aliasで外の場所を割り当てるかの2通り - どちらも
<Directory>でRequire all grantedと、WordPress ならAllowOverrideの許可が必要 - WordPress をサブディレクトリに置くときは、.htaccess の
RewriteBase /blog/と転送先/blog/index.phpを確認する - 親ディレクトリの WordPress と衝突する場合は、親の .htaccess で対象外にするか、Alias で置き場所を分ける
- 症状ごとにエラーログと curl で確認し、既存サイトを移すときは URL の置き換えと 301 を忘れずに行う