Назад | Перейти на главную страницу

бесконечное перенаправление конфигурации подкаталога nginx

Я запускаю nginx для обслуживания статического сайта (angular) с proxy_pass на сервере node js на /api подкаталог. Это нормально работает.

Сейчас я пытаюсь добавить аналогичный proxy_pass на /blog подкаталог, который перенаправляет на локально работающий экземпляр wordpress (работающий в контейнере докера). Однако, когда я пытаюсь достичь /blog извне он сразу перенаправляет меня на <same-domain>/blog/wp-admin/install.php и это делается в цикле, пока браузер не откажется. Если я сделаю curl -I localhost:8000/wp-admin/install.php на самом сервере он возвращает фактический ответ, а не перенаправляет на тот же URL, поэтому я почти уверен, что проблема в конфигурации nginx.

Через docker-compose.yml для wordpress я устанавливаю 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. В proxy_pass должен иметь косую черту в конце, иначе он пройдет /blog часть к серверу wordpress (или так кажется), и он не знает, что с ней делать:

    proxy_pass              http://localhost:8000/;
    
  2. Поскольку я использую https, wordpress необходимо передать заголовок X-Forwarded-Proto с правильным протоколом. Это заставляет его использовать https и действительно можно увидеть в 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. В противном случае он будет удален при запуске контейнера.

Теперь вроде нормально работает.

Вам нужно отредактировать свой wp-config.php файл и добавьте следующие строки:

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

WordPress пытается автоматически определить ваш домен на основе полученного запроса. Однако, когда он выполняется за обратным прокси, запрос не содержит правильной информации для автоматического определения. Это заставляет WordPress войти в бесконечный цикл перенаправления.