Як обслуговувати всі існуючі статичні файли безпосередньо за допомогою NGINX, але решту проксі-серверу подавати на внутрішній сервер.


87
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

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

    if (!-f $request_filename) {
        proxy_pass http://127.0.0.1:8080; # backend server listening
        break;
        }
    }

Вище будуть обслуговуватися всі існуючі файли безпосередньо за допомогою Nginx (наприклад, Nginx просто відображає вихідний код PHP), інакше пересилає запит до Apache. Мені потрібно виключити файли * .php із правила, щоб запити на * .php також передавалися в Apache та оброблялись.

Я хочу, щоб Nginx обробляв усі статичні файли, а Apache - обробляв усі динамічні матеріали.

EDIT: Існує підхід до білого списку, але він не дуже елегантний. Перегляньте всі ці розширення, я цього не хочу.

location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
    access_log off;
    expires 30d;
    }
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
    }

РЕДАГУВАТИ 2: У нових версіях Nginx try_filesзамість цього використовуйте http://wiki.nginx.org/HttpCoreModule#try_files


Просто для очищення речей: наведений вище код буде служити статичним файлом, якщо він існує на диску, якщо файл не існує, запит передається Apache. Це працює більшу частину часу, оскільки всі URL-адреси в моїх програмах використовують mod_rewrite (або маршрутизацію) і насправді не існують на диску. Виняток становить лише прямий доступ до імені файлу * .php, який Apache повинен проаналізувати.
fmalina

Відповіді:


152

Використовуйте try_files та іменований блок розташування ('@apachesite'). Це видалить непотрібні збіги регулярних виразів і if. Більш ефективний.

location / {
    root /path/to/root/of/static/files;
    try_files $uri $uri/ @apachesite;

    expires max;
    access_log off;
}

location @apachesite {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

Оновлення: Припущення цієї конфігурації полягає в тому, що не існує жодного сценарію php /path/to/root/of/static/files. Це характерно для більшості сучасних фреймворків. Якщо у вашій застарілій php-програмі в одній папці змішані як php-сценарії, так і статичні файли, можливо, вам доведеться додати до білого списку всі типи файлів, які ви хочете обслуговувати nginx.


я використовую wordpress, тож чи потрібно розміщувати папку для завантаження на сервері nginx?
Chameron

7
Моя проблема з цим рішенням: nginx не використовує інше місце (проксі) і намагається показати список каталогів. Тож він видає 403, оскільки список каталогів не активований. Редагувати: Добре, якщо видалити, $uri/це працює.
ChristophLSA

1
Це буде проксі / приклад для apache, але дозволить завантажити /example.php.
Теренс Джонсон,

1
@TerenceJohnson Не безпечно розміщувати свої php-файли в папці зі статичними файлами. Зверніть увагу, що я встановив root /path/to/root/of/*static*/files;. php-файли слід зберігати в іншій папці, до якої не можна безпосередньо отримати доступ з Інтернету.
Чуан Ма

2
Я знаю, що так повинно бути, але якщо хтось ставить Nginx перед будь-яким із багатьох поширених готових PHP-додатків, які мають все під веб-коренем і покладаються на файли .htaccess, вони не повинні копіювати та вставте свою конфігурацію.
Terence Johnson

18

Спробуйте це:

location / {
    root /path/to/root;
    expires 30d;
    access_log off;
}

location ~* ^.*\.php$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

Сподіваюся, це працює. Регулярні вирази мають вищий пріоритет, ніж звичайні рядки, тому всі запити, що закінчуються на.php повинні пересилатися в Apache, якщо існує лише відповідний .phpфайл. Відпочинок буде оброблятися як статичний файл. Фактичний алгоритм оцінки місцезнаходження тут .


6

Якщо ви використовуєте mod_rewrite, щоб приховати розширення своїх сценаріїв, або якщо вам просто подобаються гарні URL-адреси, які закінчуються на /, то, можливо, ви захочете підійти до цього з іншого боку. Скажіть nginx дозволити будь-що з нестатичним розширенням перейти до apache. Наприклад:

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$
{
    root   /path/to/static-content;
}

location ~* ^!.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

Я знайшов першу частину цього фрагмента за адресою: http://code.google.com/p/scalr/wiki/NginxStatic


Це працювало чудово, хоча я все ще отримую помилки для зменшених файлів (наприклад, site.min.css та main.min.js тощо). Як я можу зловити тих, хто знаходиться в регулярному виразі? @lo_fye
Гарт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.