2026年11月12日
2026年11月12日
Apache Subdirectory Setup: Run example.com/blog/ with Alias
This article is a localized edition of the Japanese original. Read the Japanese original
To run a separate site or app in a subdirectory under one domain, such as example.com/blog/, you decide which directory Apache maps that URL to and grant permissions with <Directory>. If you put WordPress there, you also need to make the .htaccess rewrite rules fit the subdirectory. This article explains how to place it inside the document root, how to assign a location outside it with Alias, the .htaccess for running WordPress in a subdirectory, what to do when it collides with a WordPress in the parent directory, and how to verify the result. Splitting by subdomain (blog.example.com) is a different matter, so if you are unsure which to choose, start from the first section.
Subdirectory vs. subdomain
There are two ways to run another site on the same domain: a subdirectory (example.com/blog/) and a subdomain (blog.example.com).
A subdirectory can be started without adding DNS or certificates and stays within a single VirtualHost. On the other hand, the settings of the parent site (.htaccess rewrite rules, PHP settings, access restrictions) easily affect it, and you need the adjustments covered in this article. A subdomain uses a separate VirtualHost, so its settings are independent, but you need to add a DNS record and a certificate.
There is no rule that one is better for search engines. A realistic way to choose is: subdomain if you value operational independence, subdirectory if you want it to appear as part of one site.
Method 1: Place it inside the document root
The simplest way is to create a directory under the document root and put the files there. If the document root is /var/www/html, files placed in /var/www/html/blog/ are published as they are at https://example.com/blog/. You do not need to change the Apache configuration.
If you put WordPress there, AllowOverride must be permitted in the document root's <Directory> so that .htaccess can be used.
<Directory /var/www/html>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
If it stays at AllowOverride None, .htaccess is not read, and individual posts return 404 even though the home page opens. If the only goal is permalink rewriting, AllowOverride FileInfo also works, but depending on the kinds of settings plugins write to .htaccess, it may not be enough.
Method 2: Assign a location outside the document root with Alias
To put the app's files in a separate location such as /srv/blog and map only the URL /blog to it, use Alias. Write it inside the 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>
Match the presence or absence of a trailing slash on the URL side and the directory side of Alias. If you put a trailing slash on the URL side, as in Alias /blog/ /srv/blog/, a request for /blog (without the slash) is not mapped. If you write it without the slash, access to /blog is redirected to /blog/ by mod_dir.
If you forget to write <Directory>, you get a 403, because Apache 2.4's default configuration denies access outside the document root, and the error log records a message saying "client denied by server configuration".
The advantage of Alias is that the parent site's files and the app's files are physically separated. Because .htaccess is looked up based on the actual location of the files, /var/www/html/.htaccess (the parent site's settings) does not apply to /srv/blog. This avoids the collisions that tend to occur when the parent site is WordPress.
Take a backup before changing configuration files, and check the syntax before applying.
sudo apachectl configtest
sudo systemctl reload apache2 # httpd on RHEL family
The .htaccess for running WordPress in a subdirectory
If you put WordPress at /blog/, saving the permalink settings makes WordPress write rewrite rules for a subdirectory to /blog/.htaccess. The content looks like this.
# 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
The key points are RewriteBase /blog/ and that the destination on the last line is /blog/index.php. If you copy the .htaccess of a WordPress in the root as it is, the destination becomes /index.php and the request is handed to the parent site. When you assign the location with Alias, rewriting does not work correctly unless you specify the position in the URL with RewriteBase, so do not omit this line.
In the WordPress "Settings" → "General" (Settings > General) screen, set both the WordPress Address (URL) and the Site Address (URL) to https://example.com/blog (as of October 2026). The labels on the screen may change by version.
When there is also a WordPress in the parent directory
A setup where the parent site's WordPress is in the document root and another WordPress is placed in its blog/ directory is common. With mod_rewrite in .htaccess, if the subdirectory's .htaccess has RewriteEngine On and rewrite rules, those take priority and the parent's rewrite rules are not inherited. So if /blog/.htaccess is in place correctly, it works without problems in most cases.
Problems tend to occur when what you put in the subdirectory is not WordPress and has no .htaccess. In that case, the parent WordPress's rewrite rules apply, requests for URLs that do not exist inside /blog/ are handed to the parent WordPress, and the parent site's 404 page is displayed. As a countermeasure, add a line before # BEGIN WordPress in the parent's .htaccess that excludes that directory from rewriting.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^blog/ - [L]
</IfModule>
Alternatively, separating the file locations with the Alias described earlier prevents this collision from happening at all.
Common symptoms and the order to check
Only post pages return 404
It is highly likely that .htaccess is not being read. Check whether AllowOverride in the <Directory> is None and whether mod_rewrite is enabled (apachectl -M | grep rewrite).
You get 403 Forbidden
Check the error log. If it says "client denied by server configuration," the Require in the <Directory> is missing. If it says Options FollowSymLinks or SymLinksIfOwnerMatch is off, add FollowSymLinks to Options. Also check that the file owner and permissions allow the Apache user to read the files.
The parent site’s page is displayed
Check whether the destination in /blog/.htaccess is still /index.php, and whether RewriteBase is /blog/.
Checking with curl is not affected by the browser cache.
curl -sI https://example.com/blog | grep -i -E "^(HTTP|location)"
curl -sI https://example.com/blog/sample-post/ | grep -i "^HTTP"
If the first returns a 301 to /blog/ and the second returns 200 for the post page, the configuration is working correctly.
Moving an existing site into a subdirectory
Moving a WordPress that ran at the root to /blog/ changes all URLs. You need to replace URLs in the database and set up 301 redirects from the old URLs to the new ones. If you can use WP-CLI, first check the number of replacements with --dry-run and then run it. Before the work, take backups of both files and database, and if possible try it in a test environment.
wp search-replace 'https://example.com' 'https://example.com/blog' --skip-columns=guid --dry-run
There is also a different use: "put the WordPress core files in a subdirectory and keep the site URL at the root." This is a separate procedure that the official WordPress documentation describes as "giving WordPress its own directory," and its purpose differs from the settings in this article.
Summary
- There are two ways to publish in a subdirectory: place it inside the document root, or assign a location outside it with
Alias - Either way, you need
Require all grantedin<Directory>, and for WordPress,AllowOverridepermitted - When you put WordPress in a subdirectory, check
RewriteBase /blog/and the destination/blog/index.phpin .htaccess - If it collides with a WordPress in the parent directory, exclude it in the parent's .htaccess or separate the locations with Alias
- Check by symptom with the error log and curl, and when moving an existing site, do not forget the URL replacement and 301 redirects
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)