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

Nginx множественные проблемы с расположением

В настоящее время я пытаюсь разбить 3 приложения из одного репозитория на 3, но сохраняя структуру URL-адресов, поэтому в основном разные места в одном домене должны доставляться разными приложениями.

Я борюсь с тем, что одно из приложений должно быть резервным для несуществующих URL-адресов, поэтому, если первое не совпадает, а второе - нет, тогда третье должно обрабатывать запрос.

У меня есть такая структура:

/ etc / nginx / sites-enabled / main_site, здесь, кроме server_name и журналов, которые у меня есть include /etc/nginx/subsites-enabled/*, где у меня есть 3 файла конфигурации, по одному для каждого приложения.

Каждый из 3 файлов конфигурации содержит блок местоположения.

Я пробовал отрицательный просмотр в регулярном выражении (в основном пытаясь жестко закодировать URL-адреса, которые обрабатывают другие приложения), но не удалось.

Итак, подведем итог:

/ и / community должны быть доставлены с помощью /etc/nginx/subsites-enabled/example.org/home (несколько скриптов Perl)

/ news должен быть доставлен /etc/nginx/subsites-enabled/example.org/news (wordpress)

все остальное должно быть доставлено /etc/nginx/subsites-enabled/example.org/app (приложение для тортов)

Бит perl работает нормально. Проблема, с которой я столкнулся, заключается в том, что приложение принимает новости (вероятно, потому, что оно соответствует. *), Я пробовал разные варианты (я был в этом 2 дня), но ни один из них не решил все проблемы (иногда статические ресурсы не работают и т. д.).

Моя конфигурация:

/etc/nginx/sites-enabled/example.org:

server {
    listen   80;
    server_name example.org;
    error_log /var/log/nginx/example.org.log;

    include /etc/nginx/subsites-enabled/example.org/*;
}

/etc/nginx/subsites-enabled/example.org/home:

location = / {
  rewrite ^.*$ /index.pl last;
}

location ~* /community(.*) {
  rewrite ^.*$ /index.pl last;
}

location ~ \.pl {
  root   /var/www/vhosts/home;
  access_log /var/log/nginx/home/access.log;
  error_log /var/log/nginx/home/error.log;

  include /etc/nginx/fastcgi_params;
  fastcgi_index index.pl;
  fastcgi_param SCRIPT_FILENAME /var/www/vhosts/home$fastcgi_script_name;
  fastcgi_pass  unix:/var/run/fcgiwrap.socket;
}

/ etc / ngins / с поддержкой подсайтов / новости

location /news {
  access_log /var/log/nginx/news/access.log;
  error_log /var/log/nginx/news/error.log debug;

  error_page 404 = /news/index.php;

  root /var/www/vhosts/news;

  index index.php;

  if (!-e $request_filename) {
      rewrite ^.*$ /index.php last;
  }

  location ~ \.php {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www/vhosts/news$fastcgi_script_name;
  }
}

/ etc / nginx / subsites-enabled / app:

location ~ .* {
  access_log /var/log/nginx/app/access.log;
  error_log /var/log/nginx/app/error.log;

  rewrite_log on;

  index index.php;
  root /var/www/vhosts/app/app/webroot;

  if (-f $request_filename) {
    expires 30d;
    break;
  }

  if (!-e $request_filename) {
    rewrite ^.*$ /index.php last;
  }

  location ~ \.php {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www/vhosts/app/app/webroot$fastcgi_script_name;
  }
}

В вашей конфигурации есть несколько ошибок, две из которых:

  1. Пути внутри блока местоположения по-прежнему включают согласованный путь.
  2. Переписывание с «последним» продолжается, просматривая все доступные локации для матча (они выходят за пределы текущего блока локаций).

Например, возьмите URL example.org/news/test.htm

  • В location /news блок будет соответствовать этому
  • Используемый путь тогда /news/test.htm - это не меняется только потому, что находится в блоке локации
  • Добавив путь к document_root, вы получите: /var/www/vhosts/news/news/test.htm
  • Ваш if (!-e $request_filename) оператор должен захватить этот несуществующий файл
  • Вы переписываете путь к /index.php
  • Поскольку вы используете last процессы начинаются заново (выход из блока местоположения)
  • /index.php теперь захвачен location /app block.

Упомянутая выше проблема с корневой директивой усугубляется, когда вы переходите к блоку местоположения своего приложения. В отличие от блока «новости», где вы, вероятно, можете просто удалить «новости» из пути (поскольку они будут добавлены обратно), вы не можете сделать это для пути приложения, который заканчивается на «webroot».

Решение заключается в alias директива. Это не меняет document_root, но меняет путь к файлу, который используется для обслуживания запроса. К сожалению, rewrite и try_files склонны вести себя немного неожиданно с alias.

Начнем с простого примера - без PHP - только HTML и ваш Perl-блок - но со структурой папок, соответствующей вашей (проверено на Nginx 1.0.12, CentOS 6):

server {
    server_name example.org;
    error_log /var/log/nginx/example.org.error.log notice;
    access_log /var/log/nginx/example.org.access.log;
    rewrite_log on;

    location = / {
        rewrite ^ /index.pl last;
    }

    location ^~ /community {
        rewrite ^ /index.pl last;
    }

    location ~ \.pl {
        root   /var/www/vhosts/home;

        [fastcgi_stuff...]
    }


    location ^~ /news {
        alias /var/www/vhosts/news;
        index index.htm;

        try_files $uri $uri/ /news/index.htm;
    }

    location ^~ /app {
        alias /var/www/vhosts/app/app/webroot;
        index index.htm;

        try_files $uri $uri/ /app/index.htm;
    }

    location / {
        rewrite ^/(.*) /app/$1 last;
    }
}
  • location = / - будет соответствовать только корневому пути
  • location ^~ /community - будет соответствовать каждому пути, начинающемуся с / community
  • location ~ \.pl - будет соответствовать всем файлам, содержащим .pl
  • location ^~ /news - будет соответствовать каждому пути, начинающемуся с / news
  • location ^~ /app - будет соответствовать каждому пути, начинающемуся с / app
  • location / - будет соответствовать всем путям, не указанным выше

Вы сможете удалить ^~ - но он может предложить небольшое улучшение производительности, так как он прекращает поиск после нахождения соответствия.

Хотя добавление блоков PHP должно быть несложным делом, есть, к сожалению, небольшая трудность - try_files (и ваша перезапись) не передают желаемый путь к вложенному блоку местоположения - и используют alias когда в блоке местоположения указано только расширение, не работает.

Одним из решений является использование отдельных блоков местоположения, которые выполняют захват вместе с директивой псевдонима - это не совсем элегантно, но, насколько я могу судить, работает (опять же, протестировано на Nginx 1.0.12, CentOS 6 - из Конечно, я не настраивал CakePHP, Wordpress и Perl - я просто использовал пару файлов PHP и HTML в каждой папке)

server {
    server_name example.org;
    error_log /var/log/nginx/example.org.error.log notice;
    access_log /var/log/nginx/example.org.access.log;
    rewrite_log on;

    location = / {
        rewrite ^ /index.pl last;
    }

    location ^~ /community {
        rewrite ^ /index.pl last;
    }

    location ~ \.pl {
        root   /var/www/vhosts/home;
        access_log /var/log/nginx/home.access.log;
        error_log /var/log/nginx/home.error.log;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.pl;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass  unix:/var/run/fcgiwrap.socket;
    }

    location /news {
        access_log /var/log/nginx/news.access.log;
        error_log /var/log/nginx/news.error.log notice;
        alias /var/www/vhosts/news;
        index index.php;
        try_files $uri $uri/ /news/index.php;
    }

    location ~* ^/news/(.*\.php)$ {
        access_log /var/log/nginx/news.php.access.log;
        error_log /var/log/nginx/news.php.error.log notice;
        alias /var/www/vhosts/news/$1;
        try_files "" /news/index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_NAME $1;
        fastcgi_param SCRIPT_FILENAME /var/www/vhosts/news/$1;
        fastcgi_pass  127.0.0.1:9000;
    }

    location /app {
        alias /var/www/vhosts/app/app/webroot;
        access_log /var/log/nginx/app.access.log;
        error_log /var/log/nginx/app.error.log notice;
        index index.php;
        try_files $uri $uri/ /app/index.php;
    }

    location ~* ^/app/(.*\.php)$ {
        access_log /var/log/nginx/news.access.log;
        error_log /var/log/nginx/news.error.log notice;
        alias /var/www/vhosts/app/app/webroot/$1;
        try_files "" /app/index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_NAME $1;
        fastcgi_param SCRIPT_FILENAME /var/www/vhosts/app/app/webroot/$1;
        fastcgi_pass  127.0.0.1:9000;
    }

    location / {
        rewrite ^/(.*) /app/$1 last;
    }
}

Приведенная выше конфигурация берет простую, описанную выше, и вносит два изменения:

  • Добавьте два блока местоположения:
    • location ~* ^/news/(.*\.php)$ - будет соответствовать всем файлам, заканчивающимся на .php, с путями, начинающимися с / news /
    • location ~* ^/app/(.*\.php)$ - будет соответствовать всем файлам, заканчивающимся на .php, с путями, начинающимися с / app /
  • Удалить ^~ сопоставление - это необходимо, чтобы два добавленных блока местоположения могли соответствовать путям (в противном случае сопоставление остановилось бы на блоках / news или / app).

Следует отметить, что здесь очень важен порядок сопоставления местоположений:

  • Сначала точные совпадения (с использованием =)
  • Матчи с ^~ второй
  • Соответствующие блоки регулярных выражений
  • Обычные строки - только если подходящее регулярное выражение не найдено

Соответствующее регулярное выражение заменит прямую строку!

Важно отметить, что при использовании захватов с псевдонимом заменяется весь URL-адрес, а не только начальная папка. К сожалению, это означает, что $fastcgi_script_name остается пустым - я использовал $1 выше вместо этого.

Я уверен, что вам нужно будет внести несколько изменений, но основная предпосылка должна быть функциональной. Вы должны иметь возможность разделять блоки на несколько файлов по мере необходимости - порядок не должен влиять на конфигурацию.