Next.js主域名/wp子目录集成WordPress的Nginx配置问题
解决Next.js主域名/wp子目录反向代理WordPress的问题
问题背景
- Next.js应用托管在Vercel,域名
example.com - WordPress博客部署在DigitalOcean云服务器,域名
wp.example.com - DNS由Vercel管理,已配置
wp子域名A记录指向DigitalOcean服务器IP
目标
将WordPress博客通过主域名的/wp子目录对外提供服务,实现以下URL访问:
example.com/wp/blog-post-1 example.com/wp/blog-post-2 example.com/wp/blog-post-3
当前配置
- Next.js:
example.com(Vercel) - WordPress:
wp.example.com(DigitalOcean) - DNS:Vercel管理
尝试过的方案
- vercel.json重定向:配置后浏览器直接跳转到
wp.example.com,不符合需求 - next.config.js重写(首选方案):已配置重写规则,但WordPress的Nginx配置中的
return 301指令导致异常,相关配置如下:
Next.js重写配置(next.config.js)
// v0-user-next.config.js module.exports = { rewrites: async () => { return [ { source: '/wp/:path*', destination: 'https://wp.example.com/:path*', }, ]; }, experimental: { turbo: { loaders: { '.mdx': ['@mdx-js/loader', { providerImportSource: '@mdx-js/react' }], }, }, }, };
WordPress的Nginx配置
server { server_name wp.example.com; root /var/www/wp.example.com; index index.php index.html index.htm; # WordPress permalinks location / { try_files $uri $uri/ /index.php?$args; } # PHP-FPM configuration (adjust based on version) location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Allow access to static files in wp-includes, wp-admin, wp-content location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|otf|eot|mp4|webm|ogg|mp3|wav|zip|tar|gz|bz2|7z|rar|xml|json)$ { allow all; expires max; log_not_found off; } # Disable .htaccess and other hidden files location ~ /\. { deny all; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/wp.mydomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/wp.mydomain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot add_header Strict-Transport-Security "max-age=31536000" always; # managed by Certbot ssl_trusted_certificate /etc/letsencrypt/live/wp.mydomain.com/chain.pem; # managed by Certbot ssl_stapling on; # managed by Certbot ssl_stapling_verify on; # managed by Certbot return 301 https://example.com/wp$request_uri; } server { if ($host = wp.example.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name wp.example.com; root /var/www/wp.example.com; index index.php index.html index.htm; # WordPress permalinks location / { try_files $uri $uri/ /index.php?$args; } # PHP-FPM configuration (adjust based on version) location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Disable .htaccess and other hidden files location ~ /.(?!well-known).* { deny all; } }
解决步骤
1. 移除Nginx中的强制301跳转
Nginx配置里的return 301 https://example.com/wp$request_uri;会破坏Next.js的反向代理逻辑,直接删除该行。同时在PHP-FPM配置块中添加反向代理相关的头信息,让WordPress识别正确的访问上下文:
修改后的443端口server块:
server { server_name wp.example.com; root /var/www/wp.example.com; index index.php index.html index.htm; # WordPress permalinks location / { try_files $uri $uri/ /index.php?$args; } # PHP-FPM configuration (adjust based on version) location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 传递反向代理的主机头和协议信息 fastcgi_param HTTP_HOST example.com; fastcgi_param X-Forwarded-Host example.com; fastcgi_param X-Forwarded-Proto $scheme; } # Allow access to static files in wp-includes, wp-admin, wp-content location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|otf|eot|mp4|webm|ogg|mp3|wav|zip|tar|gz|bz2|7z|rar|xml|json)$ { allow all; expires max; log_not_found off; } # Disable .htaccess and other hidden files location ~ /\. { deny all; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/wp.mydomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/wp.mydomain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot add_header Strict-Transport-Security "max-age=31536000" always; # managed by Certbot ssl_trusted_certificate /etc/letsencrypt/live/wp.mydomain.com/chain.pem; # managed by Certbot ssl_stapling on; # managed by Certbot ssl_stapling_verify on; # managed by Certbot }
修改后重启Nginx服务:
sudo systemctl restart nginx
2. 配置WordPress站点URL
登录WordPress后台,进入设置 > 常规,修改:
- 站点地址(URL):
https://example.com/wp - WordPress地址(URL):
https://wp.example.com
如果后台修改后出现跳转异常,直接修改wp-config.php文件添加以下代码:
define('WP_HOME', 'https://example.com/wp'); define('WP_SITEURL', 'https://wp.example.com'); define('FORCE_SSL_ADMIN', true); // 处理反向代理下的HTTPS检测 if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on'; }
3. 验证Next.js重写配置
确保next.config.js中的重写规则正确,重新部署Next.js应用到Vercel。
4. 测试访问
访问example.com/wp及example.com/wp/blog-post-1,确认页面正常加载且无跳转。
内容的提问来源于stack exchange,提问作者Ben Jonson
相关产品推荐
相关产品推荐

