You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 22:11:04