Nginx декілька проблем з розташуванням


15

На даний момент я намагаюся розділити 3 програми з одного сховища на 3, але зберігаючи структуру URL, тому в основному різні місця в одному домені повинні доставлятися різними програмами.

З чим я борюся, це те, що одне з додатків має бути резервним для неіснуючих URL-адрес, тому якщо перший не відповідає, а другий не відповідає, третій повинен обробляти запит

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

/ etc / nginx / enable-sites / main_site, тут, окрім імені_сервера та журналів include /etc/nginx/subsites-enabled/*, у яких є 3 файли конфігурації, по одному для кожної програми.

Кожен з 3 конфігураційних файлів містить блок розташування.

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

Отже, підсумовуючи:

/ та / спільноту слід доставляти /etc/nginx/subsites-enabled/example.org/home (кілька сценаріїв perl)

/ новини слід доставляти /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 / subites-enable / news

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 / subites-enable / 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;
  }
}

а) опублікуйте свою конфігурацію разом із деякими прикладами того, куди повинні йти різні переадресації (у тому числі для неіснуючих URL-адрес). b) використовувати try_files з іменованим блоком розташування (за допомогою @префікса), який відображається у вашій програмі за замовчуванням. Ви також можете встановити сторінку помилки, яка відображає 404 у вказане місце.
cyberx86

@ cyberx86 Я додав більше деталей і мій конфігуратор
Андрій Серделюк

Швидкий огляд пропонує декілька речей: а) відповідність регулярних виразів має перевагу над звичайними рядками, тож ваш додаток буде відповідати замість блоку новин - спробуйте location ^~ /news. б) для вашого блоку додатків ви повинні мати можливість location /(це не те саме location = /, але повинно відповідати всьому, що вже не збігається. в) у деяких випадках (зокрема, регулярні вирази), замовлення має значення - ви, можливо, захочете комбінувати 3 файли в єдиний файл з блоками в потрібному порядку. Також використовуйте try_files замість !-e. Нарешті дивіться wiki.nginx.org/HttpCoreModule#location .
cyberx86

Я намагався майже всі варіанти цих варіантів, включаючи комбінування їх в один файл (навіть якщо вони повинні бути окремими, оскільки вони розгорнуті окремо), жоден з них не працює. Новини просто обробляються додатком.
Андрій Серделюк

Ну, я думаю, що вирішили це - трохи складніше, ніж я спочатку очікував - але, безумовно, приємно поєднувати дотепність проти. Дякую за головоломку.
cyberx86

Відповіді:


47

У вашому конфігурації є кілька помилок, серед яких два:

  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.

Проблема, згадана вище, з кореневою директивою, ускладнюється, коли ви переходите до блоку розташування програми. На відміну від блоку "новини", де ви могли б просто видалити "новини" зі шляху (оскільки він буде доданий ще), ви не можете зробити це для шляху програми, який закінчується "веб-корінням".

Рішення лежить в 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 - відповідатиме кожному шляху, починаючи з / спільноти
  • location ~ \.pl - відповідатиме всім файлам, що містять .pl
  • location ^~ /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замість цього використовував вище.

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


2
Чувак, я хотів би, щоб я міг висилити тебе 100 разів. Ти чистий дивовижний. Спасибі!
Андрій Серделюк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.