以 wordpress 作为子目录的 Nginx 在帖子中返回 404

Nginx with worpress as sub-directory returning 404 in posts

在Wordpress子目录下添加各种配置后,WP首页可以正常访问,但是还是进不了帖子,返回404。

www.test.com/blog - WP homepage, works perfectly fine

www.test.com/blog/test-post-for-blog - WP Post, 404

配置如下:

server {
  listen 80;
  listen [::]:80;

  server_name www.test.com;

  location ^~ /media {
    alias /var/local/test/static/media;
  }

  location ^~ /icons {
    alias /var/local/test/static/icons;
  }

  location /blog {
    alias /var/www/html;
    index  index.html index.htm index.php;
    try_files $uri $uri/ /blog/index.php?$args /blog/index.php?q=$uri&$args;
    # try_files $uri $uri/ /blog/index.php?q=$uri$args;

    location ~ \.php$ {
      try_files $uri =404;
      include fastcgi_params;
      fastcgi_intercept_errors on;
      fastcgi_index index.php;
      fastcgi_pass blog-test:9000;
      fastcgi_split_path_info ^(/blog)(/.*)$;
      fastcgi_param SCRIPT_FILENAME $request_filename;
      fastcgi_param PATH_INFO $fastcgi_path_info;
    }
  }
}

和日志:

2022/02/09 14:47:25 [error] 32#32: *45 open() "/etc/nginx/html/index.php" failed (2: No such file or directory), client: 10.10.10.10, server: www.test.com, request: "GET /blog/test-post-for-blog/ HTTP/1.1", host: "www.test.com", referrer: "https://www.test.com/blog/"
10.10.10.10 - admin [09/Feb/2022:14:47:25 +0000] "GET /blog/test-post-for-blog/ HTTP/1.1" 404 187 "https://www.test.com/blog/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36"

查看日志,好像查错了地方,就是/etc/nginx/html/index.php,但如果我在 php 位置块中添加别名,那么主页也会停止工作,这让我有点困惑。

目前不太确定是不是博客块中的alias问题(nginx建议不要同时使用alias try_files,显然是由于错误)或其他原因。如果确实是别名指令,我会尝试添加root,以及一些重写规则以避免修改文件结构。

我真的花了很多时间才弄明白,但仍然无法真正理解这里可能存在的问题。

更新 1:

这非常奇怪。使用以下博客配置,将 php 位置与博客分开,可以访问 WP 帖子,但不能访问主页和管理,返回 404:

  location /blog {
    alias /var/www/html;
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ \.php$ {
    alias /var/www/html;
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_pass blog-test:9000;
    fastcgi_split_path_info ^(/blog)(/.*)$;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }

更新 2:

现在可以使用了(可以访问博客和帖子),但管理员似乎进入了重定向循环:

  location /blog {
    alias /var/www/html;
    index index.php;
    try_files $uri $uri/ /blog/index.php?q=$uri&$args;
  }

  location ~ \.php$ {
    alias /var/www/html;
    try_files $uri $uri/ /index.php?$args;
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_pass blog-test:9000;
    fastcgi_param SCRIPT_FILENAME $request_filename;
  }

更新 3 和修复:

这显然有效,但配置似乎真的很不愉快且未优化。如果我尝试将 php 位置嵌套到博客块中,那么 php 文件将下载而不是呈现。如果我尝试使用别名而不是 root,某些页面将不会显示,导致 404。无论如何,这似乎是有效的:

  root /var/www/html; 
  index index.php;

  location /blog {
    rewrite ^/blog(.*)$ / break;
    try_files $uri $uri/ /blog/index.php?$args;
  }
          
  location ~ \.php$ {
    rewrite ^/blog(.*)$  break;
    fastcgi_pass blog-test:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_split_path_info ^(/blog)(/.*)$;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }

在 /blog 目录之外,您可能还有 php 个文件。应该有一个单独的块用于具有相同设置的 wordpress 安装,但是用于博客目录。

这可能是 wordpress 的块(在 Docker 中测试)

  location /blog {
    try_files $uri $uri/ /blog/index.php?$args;
    
    location ~ \.php$ {
      fastcgi_split_path_info ^/blog/(.+\.php)(/.+)$;
      fastcgi_pass wp:9000;
      fastcgi_index index.php;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    }
  }

所以你完整的 nginx 配置应该是这样的:

server {
  listen 80;
  listen [::]:80;

  server_name www.test.com;
  root /var/www/html; 
  index index.php; 

  location ^~ /media {
    alias /var/local/test/static/media;
  }

  location ^~ /icons {
    alias /var/local/test/static/icons;
  }

  # This is for Wordpress
  location /blog {
    try_files $uri $uri/ /blog/index.php?$args;
    
    location ~ \.php$ {
      fastcgi_split_path_info ^/blog/(.+\.php)(/.+)$;
      fastcgi_pass wp:9000;
      fastcgi_index index.php;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    }
  }

  # This is for php files in the root. If there is no php to be parsed there you could leave these blocks out.
  location / {
    try_files $uri $uri/ /index.php?$args;
  }
  
  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass wp:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
  }
}

更新:我在 nginx 服务器配置中添加了 rootindex 属性。

更新 3 和修复:

这显然有效,但配置似乎真的很不愉快且未优化。如果我尝试将 php 位置嵌套到博客块中,那么 php 文件将下载而不是呈现。如果我尝试使用别名而不是 root,某些页面将不会显示,从而导致 404。无论如何,这似乎是有效的:

  root /var/www/html; 
  index index.php;

  location /blog {
    rewrite ^/blog(.*)$ / break;
    try_files $uri $uri/ /blog/index.php?$args;
  }
          
  location ~ \.php$ {
    rewrite ^/blog(.*)$  break;
    fastcgi_pass blog-test:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_split_path_info ^(/blog)(/.*)$;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }