Ubuntu Apache配置:blog子域名301重定向至主站/blog目录
问题描述
我有一个部署在子域名blog.example.com的WordPress博客,现需迁移至主站www.example.com的/blog子目录;主站基于CodeIgniter4框架,服务器为Ubuntu系统的Apache。目前已实现子域名根路径重定向至www.example.com/blog,但无法将blog.example.com/123这类子路径重定向到www.example.com/blog/123。另外,能否为博客设置独立的ErrorLog?
主站.htaccess文件
# Turning on the rewrite engine is necessary for the following rules and features. # FollowSymLinks must be enabled for this to work. <IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On # If you installed CodeIgniter in a subfolder, you will need to # change the following line to match the subfolder you need. # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase # RewriteBase / # Redirect Trailing Slashes... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [L,R=301] # Rewrite "www.example.com -> example.com" RewriteCond %{HTTPS} !=on RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] # Checks to see if the user is attempting to access a valid file, # such as an image or css document, if this isn't true it sends the # request to the front controller, index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond $1 !^(index\.php|blog) RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA] # Ensure Authorization header is passed along RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] </IfModule>
博客.htaccess文件
# BEGIN WordPress # The directives (lines) between "BEGIN WordPress" and "END WordPress" are # dynamically generated, and should only be modified via WordPress filters. # Any changes to the directives between these markers will be overwritten. <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress RewriteCond %{HTTP_HOST} ^blog\.example\.com RewriteRule ^(.*)$ https://www.example.com/blog/$1 [R=301]
www.example.com Apache配置文件
<VirtualHost *:80> ServerAdmin me@example.com ServerName www.example.com ServerAlias www.example.com Protocols h2 http/1.1 DocumentRoot /var/www/example-website/public <Directory /var/www/example-website/public> SetEnv website Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> Alias /blog "/var/www/example-blog/public_html" <Directory "/var/www/example-blog/public_html"> SetEnv blog Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> ErrorLog /var/www/example-website/writable/logs/errors.log CustomLog /var/www/example-website/writable/logs/access.log combined env=website CustomLog /var/www/example-blog/public_html/wp-content/access.log combined env=blog RewriteEngine on RewriteCond %{SERVER_NAME} =www.example.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost>
Certbot生成的HTTPS配置文件
<IfModule mod_ssl.c> <VirtualHost *:443> ServerAdmin me@example.com ServerName www.example.com ServerAlias www.example.com Protocols h2 http/1.1 Alias /blog "/var/www/example-blog/public_html" <Directory "/var/www/example-blog/public_html"> SetEnv blog Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> DocumentRoot /var/www/example-website/public <Directory /var/www/example-website/public> Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> ErrorLog /var/www/example-website/writable/logs/errors.log CustomLog /var/www/example-website/writable/logs/access.log combined env=website CustomLog /var/www/example-blog/public_html/wp-content/access.log combined env=blog RewriteEngine on # Some rewrite rules in this file were disabled on your HTTPS site, # because they have the potential to create redirection loops. # RewriteCond %{SERVER_NAME} =www.example.com # RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/www.example.com-0001/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com-0001/privkey.pem </VirtualHost> </IfModule>
解决方案
一、修复子路径重定向问题
1. 调整博客.htaccess规则顺序
当前重定向规则放在WordPress内部规则之后,会被WordPress的路由规则拦截。需要将重定向规则移到# BEGIN WordPress之前:
# 优先处理子域名重定向 RewriteCond %{HTTP_HOST} ^blog\.example\.com RewriteRule ^(.*)$ https://www.example.com/blog/$1 [R=301,L] # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
L标记确保匹配到重定向规则后立即停止后续规则处理,避免被WordPress规则拦截。
2. 为blog.example.com配置独立虚拟主机
当前仅配置了www.example.com的虚拟主机,blog.example.com的请求可能未被正确捕获。需新增虚拟主机配置:
HTTP配置文件(/etc/apache2/sites-available/blog.example.com.conf)
<VirtualHost *:80> ServerName blog.example.com ServerAdmin me@example.com RewriteEngine On RewriteRule ^(.*)$ https://www.example.com/blog/$1 [R=301,L] </VirtualHost>
HTTPS配置(通过Certbot生成)
运行命令生成SSL证书及配置:
certbot --apache -d blog.example.com
在生成的HTTPS虚拟主机中添加重定向规则:
<IfModule mod_ssl.c> <VirtualHost *:443> ServerName blog.example.com ServerAdmin me@example.com RewriteEngine On RewriteRule ^(.*)$ https://www.example.com/blog/$1 [R=301,L] Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/blog.example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/blog.example.com/privkey.pem </VirtualHost> </IfModule>
生效配置
a2ensite blog.example.com.conf systemctl restart apache2
3. 主站.htaccess规则验证
你添加的RewriteCond $1 !^(index\.php|blog)规则正确,确保CodeIgniter不会处理/blog路径的请求,无需修改。
二、为博客设置独立ErrorLog
在www.example.com的HTTPS虚拟主机配置中,为/blog目录添加独立ErrorLog指令:
<IfModule mod_ssl.c> <VirtualHost *:443> ServerAdmin me@example.com ServerName www.example.com ServerAlias www.example.com Protocols h2 http/1.1 Alias /blog "/var/www/example-blog/public_html" <Directory "/var/www/example-blog/public_html"> SetEnv blog Options -Indexes +FollowSymLinks AllowOverride All Require all granted # 新增独立ErrorLog配置 ErrorLog /var/www/example-blog/public_html/wp-content/errors.log # 可选:自定义错误日志格式 LogFormat "%h %l %u %t \"%r\" %>s %b" blog_error CustomLog /var/www/example-blog/public_html/wp-content/errors.log blog_error </Directory> DocumentRoot /var/www/example-website/public <Directory /var/www/example-website/public> Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> ErrorLog /var/www/example-website/writable/logs/errors.log CustomLog /var/www/example-website/writable/logs/access.log combined env=website CustomLog /var/www/example-blog/public_html/wp-content/access.log combined env=blog RewriteEngine on Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/www.example.com-0001/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com-0001/privkey.pem </VirtualHost> </IfModule>
权限配置
确保Apache对日志目录有写入权限:
chown www-data:www-data /var/www/example-blog/public_html/wp-content
生效配置
systemctl restart apache2
内容的提问来源于stack exchange,提问作者Evan Appleby
相关产品推荐
相关产品推荐

