Цикл перезаписи или внутреннего перенаправления при внутреннем перенаправлении в nginx

Я пытаюсь заставить правило перезаписи работать на nginx и Wordpress. После перезагрузки nginx я пробую сайт и получаю страницу с ошибкой IS 500. Файл журнала говорит:

*1 rewrite or internal redirection cycle while internally redirecting to "/index.php"

Я в замешательстве, так как они советуют вам делать это во всех руководствах (и даже в документации Wordpress для настройки правил перезаписи с помощью nginx):

    try_files $uri $uri/ /index.php?$args ;

Вот весь блок сервера:

server {
    listen      178.79.134.35:443 http2;
    listen      [::]:443 http2;
    server_name foo.co.uk www.foo.co.uk cdn.foo.co.uk;
    ssl         on;
    ssl_certificate      /home/test/conf/web/ssl.foo.co.uk.pem;
    ssl_certificate_key  /home/test/conf/web/ssl.foo.co.uk.key;
    error_log  /var/log/apache2/domains/foo.co.uk.error.log error;

    location / {

        # This is cool because no php is touched for static content.
        # include the "?$args" part so non-default permalinks doesn't break when using query string
        try_files $uri $uri/ /index.php?$args ;

        proxy_pass      https://178.79.134.35:8443;
        location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
            root           /home/test/web/foo.co.uk/public_html;
            access_log     /var/log/apache2/domains/foo.co.uk.log combined;
            access_log     /var/log/apache2/domains/foo.co.uk.bytes bytes;
            expires        max;
            try_files      $uri @fallback;
        }
    }

    location /error/ {
        alias   /home/test/web/foo.co.uk/document_errors/;
    }

    location @fallback {
        proxy_pass      https://178.79.134.35:8443;
    }

    location ~ /\.ht    {return 404;}
    location ~ /\.svn/  {return 404;}
    location ~ /\.git/  {return 404;}
    location ~ /\.hg/   {return 404;}
    location ~ /\.bzr/  {return 404;}

    include /home/test/conf/web/snginx.foo.co.uk.conf*;
}

У кого-нибудь есть предложения? Я даже попробовал что-то более грязное, но получаю ту же ошибку:

    if (!-e $request_filename){
        rewrite ^(.*)$ /index.php?q=$1 last;
        break;
    }

Я немного подправил, так что это делает пропуск

location / {

    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /home/test/web/foo.co.uk/public_shtml$fastcgi_script_name;
    include fastcgi_params;

    try_files $uri $uri/ /index.php?$args ;

    proxy_pass      https://178.79.134.35:8443;

    location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
        root           /home/test/web/foo.co.uk/public_shtml;
        access_log     /var/log/apache2/domains/foo.co.uk.log combined;
        access_log     /var/log/apache2/domains/foo.co.uk.bytes bytes;
        expires        max;
        try_files      $uri @fallback;
    }
}

ОБНОВЛЕНИЕ 2: Как и предполагалось, я знаю, как location ~ \.php$ { } блок обернут вокруг него. Так это выглядит так:

location / {

    proxy_pass      https://178.79.134.35:8443;

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME home/test/web/foo.co.uk/public_shtml$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
        root           /home/test/web/foo.co.uk/public_shtml;
        access_log     /var/log/apache2/domains/foo.co.uk.log combined;
        access_log     /var/log/apache2/domains/foo.co.uk.bytes bytes;
        expires        max;
        try_files      $uri @fallback;
    }

    try_files $uri $uri/ /index.php?$args ;
}

но теперь я получаю ошибку:

111: соединение отклонено) при подключении к восходящему каналу, клиент: 81.174.134.133, сервер: foo.co.uk, запрос: "GET /wp-admin/ HTTP/2.0", восходящий поток: "fastcgi://127.0.0.1:9000"

Глядя на Google, и люди предлагают протестировать порт 9000:

root@com:/home/# telnet localhost 9000
Trying ::1...
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

Так что, похоже, он не может получить к нему доступ. Я немного сбит с толку, так как брандмауэр настроен на использование порта 9000:

ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:9000

ОБНОВЛЕНИЕ 2: Как предложено, я попытался:

netstat -nltp|grep 9000

... но это не дает результата. Если я посмотрю, я увижу, что php-7.0-fpm установлен и работает (насколько я могу судить);

root@com:~# service php7.0-fpm status
â php7.0-fpm.service - The PHP 7.0 FastCGI Process Manager
   Loaded: loaded (/lib/systemd/system/php7.0-fpm.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2017-04-12 12:06:48 UTC; 18h ago
  Process: 3560 ExecStartPre=/usr/lib/php/php7.0-fpm-checkconf (code=exited, status=0/SUCCESS)
 Main PID: 3800 (php-fpm7.0)
   Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
   CGroup: /system.slice/php7.0-fpm.service
           ââ3800 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
           ââ3872 php-fpm: pool www
           ââ3882 php-fpm: pool www

Apr 12 12:06:43 com.x.com systemd[1]: Starting The PHP 7.0 FastCGI Process Manager...
Apr 12 12:06:48 com.x.com systemd[1]: Started The PHP 7.0 FastCGI Process Manager.

Я заглянул в /etc/php/7.0/fpm/php-fpm.conf, но не вижу никакой ссылки на порт прослушивания

ОБНОВЛЕНИЕ 3: я нашел пост, где они сказали о редактировании www.conf файл: https://github.com/serghey-rodin/vesta/issues/1025

Ища это на моем сервере, я нашел:

/etc/php/7.0/fpm/pool.d/www.conf

Затем я прокомментировал:

listen = /run/php/php7.0-fpm.sock

...и добавил:

listen = 9000

... и затем перезагрузился с:

service php7.0-fpm restart

И теперь я вижу это на netstat

Затем я убедился, что у меня есть это в моей конфигурации:

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /home/test/web/foo.co.uk/public_shtml$fastcgi_script_name;
        include fastcgi_params;
    }

перезагрузил nginx, и вуаля:) живёт!

1 ответ

Решение

Существует два распространенных способа использования Nginx в проектах PHP:

Nginx обслуживает статические файлы, обработка PHP выполняется демоном PHP-FPM и проксируется Nginx с использованием FastCGI.

Это распространенный сценарий настройки выделенного сервера для достижения максимальной производительности, и вы должны использовать его, если ваше приложение не сильно зависит от некоторых функций Apache, таких как .htaccess и вы не можете написать это раз и навсегда в конфигурации Nginx.

server {
    ...
    root /home/test/web/foo.co.uk/public_html;
    fastcgi_index index.php;

    location / { try_files $uri $uri/ /index.php?$args; }
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass 127.0.0.1:9000;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
        access_log     /var/log/apache2/domains/foo.co.uk.log combined;
        access_log     /var/log/apache2/domains/foo.co.uk.bytes bytes;
        expires        max;
    }
}

Nginx обслуживает статические файлы, все остальное передается внутреннему демону Apache

В этом случае обработка PHP выполняется модулем Apaches mod_php. Настройка примерно такая:

server {
    ...
    root /home/test/web/foo.co.uk/public_html;
    location / { proxy_pass https://178.79.134.35:8443; }
    location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|exe|pdf|doc|xls|ppt|txt|odt|ods|odp|odf|tar|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
        access_log     /var/log/apache2/domains/foo.co.uk.log combined;
        access_log     /var/log/apache2/domains/foo.co.uk.bytes bytes;
        expires        max;
    }
}

Нет необходимости в резервном коде для статических файлов, если вы не хотите, чтобы ваш apache генерировал тяжелую страницу 404. Это также можно настроить в nginx с помощью error_page директивы.

Кроме того, в этом случае, пожалуйста, рассмотрите возможность подключения к Apache через петлевой интерфейс через простой HTTP-порт для повышения производительности. HTTPS должен быть установлен только на интерфейсном веб-сервере. Проксирование к порту с поддержкой HTTPS на том же хосте на самом деле не дает никакой выгоды.

ОБНОВЛЕНИЕ: я использовал соединение сокетов TCP с PHP-FPM в своих примерах просто для примера. Однако в Интернете есть много тестов, которые показали лучшую производительность для локальных сокетов UNIX, чем для сокетов TCP. Для Nginx также довольно просто использовать сокет UNIX:

fastcgi_pass unix:/run/php/php7.0-fpm.sock;

Обязательно проверьте права доступа к этому файлу и соответствующий путь.

Другие вопросы по тегам