nginx 子目录配置无限重定向

nginx 子目录配置无限重定向

我正在运行 nginx 来为静态站点 (angular) 提供服务,并使用 proxy_pass 将内容发送到/api子目录中的 node js 服务器。一切正常。

我现在还尝试在/blog子目录上添加类似的 proxy_pass,以重定向到本地运行的 wordpress 实例(在 docker 容器中运行)。但是,当我尝试/blog从外部访问时,它会立即将我重定向到<same-domain>/blog/wp-admin/install.php,并且此过程会循环进行,直到浏览器放弃。如果我curl -I localhost:8000/wp-admin/install.php在服务器本身上执行此操作,它会返回实际响应,而不是重定向到相同的 URL,因此我很确定 nginx 配置是问题所在。

通过docker-compose.ymlwordpress,我正在设置WP_HOME并根据需要WP_SITEURL正确包含/blog在 URL 中。

我到处找,尝试了所有能找到的方法,但还是无法解决这个问题。由于我对 nginx 的经验很少,因此如果能帮助我修复或诊断这个问题,我将不胜感激。以下是 nginx 配置文件(域名已替换为<some-domain>):

...

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

    server_name <some-domain>;

    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ssl_certificate /etc/letsencrypt/live/<some-domain>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<some-domain>/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    expires $expires;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name <some-domain>;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass_header       Server;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Scheme $scheme;
        proxy_set_header        Host $http_host;
        proxy_set_header        X-NginX-Proxy true;
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  on;

        proxy_pass              http://localhost:3000;
    }

    location /blog/ {
        proxy_pass_header       Server;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Scheme $scheme;
        proxy_set_header        Host $http_host;
        proxy_set_header        X-NginX-Proxy true;
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  on;
        proxy_redirect          off;

        proxy_pass              http://localhost:8000;
    }
}

答案1

我已成功修复该问题。实际上,存在几个问题:

  1. proxy_pass末尾必须有一个斜杠,否则它会将该部分传递给/blogwordpress 服务器(或看起来是这样)并且它不知道如何处理它:

    proxy_pass              http://localhost:8000/;
    
  2. 由于我使用的是https,因此需要向 wordpress 传递X-Forwarded-Proto具有正确协议的标头。这使得它可以使用https,并且可以在 docker 容器自动创建的 中看到wp-config.php。所以我也将其添加到配置中:

    proxy_set_header        X-Forwarded-Proto $scheme;
    

到目前为止,博客已经可以正常运行。但是,还有一个问题。

  1. Wordpress 仍然认为它自己占用了一台服务器,因此管理区域内的链接没有以 开头/blog。我在 中找到了解决方案这个答案回答 StackOverflow 上的另一个问题。但是,为了避免在容器内部进行手动更改(这些更改可能会在以后被覆盖,并使后续部署容易出错),我设法将该代码docker-container.yml与和WP_HOME变量一起添加到了容器中WP_SITEURL,因此它看起来像这样:
    ...
    environment:
      WORDPRESS_DB_USER: <some-user>
      <other-stuff>
      WORDPRESS_CONFIG_EXTRA: |
       define('WP_HOME','https://fitganizer.com/blog');
       define('WP_SITEURL','https://fitganizer.com/blog');
       $$_SERVER['REQUEST_URI'] = str_replace("/wp-admin/", "/blog/wp-admin/",  $$_SERVER['REQUEST_URI']);
    
    注意双重- 显然这是在 中$$退出的方式。否则,它会在容器启动时被删除。$docker-compose.yml

现在它看起来运行良好。

答案2

您需要编辑wp-config.php文件并添加以下行:

define('WP_SITEURL', 'http://yourdomain.com/blog');
define('WP_HOME', 'http://yourdomain.com/blog');

WordPress 会尝试根据收到的请求自动检测您的域名。但是,当它在反向代理后面运行时,请求不包含用于自动检测的正确信息。这会导致 WordPress 进入无限重定向循环。

相关内容