Несколько каталогов статических файлов, один сервер PHP FPM

Несколько каталогов статических файлов, один сервер PHP FPM

I have two directories which I need to serve static assets out of:

  1. /srv/web: Static assets which include images, JavaScript, HTML, etc.
  2. /srv/php: Dynamic PHP scripts alongside some static assets.

I'm using NGINX and have configured it like so:

server {
    listen 80;
    server_name _;

    # root /;
    index index.php index.html index.htm;
    try_files /srv/web/$uri /srv/php/$uri =404;

    location ~ \.php$ {
        root /srv/php;
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
#       fastcgi_param SCRIPT_FILENAME /srv/php$fastcgi_script_name;
        include fastcgi_params;
    }
}

I'm on Ubuntu 14.04, PHP FPM package version is 5.5.9, NGINX package version is 1.4.6.

The simple goal here is to serve static files out of /srv/web first, failing that /srv/php, failing that, return 404. All files ending in \.php$ will be requested from PHP FPM over the Unix socket, and this is working.

The problem I'm currently having is that the index directive on the server isn't working as planned. I have an index.html file in /srv/web, and when I do

curl -is http://localhost/

I get a 404.

Is this the most ideal way of setting up an NGINX site with multiple filesystem folders to serve from alongside PHP? Any ideas as to why my static index isn't working?


Update

As per AD7six's answer below, I've updated my configuration to look like this:

server {
    listen 80;
    server_name _; # listen at all host names

    # serve static files first from /srv/web, then from /srv/php, and any dynamic PHP files from
    # FastCGI/FPM at the Unix socket.
    location / {
        root /srv/web;
        index index.html index.htm;
        try_files $uri $uri/ @php;
    }

    location @php {
        root /srv/php;
        index index.php;
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        root /srv/php;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /srv/php/$fastcgi_script_name;
        include fastcgi_params;
    }
}

My directory listing looks like this:

/srv/
|-- php
|   |-- demo.php
|   |-- index.php
|   `-- phpstatic.txt
`-- web
    |-- static.html
    `-- subdir
        `-- index.html

3 directories, 5 files

Getting static files and PHP files works as planned and getting /subdir/ with its index works fine, but if I GET /, I get a 403 forbidden, and nginx complains of directory listing:

2015/08/24 21:50:59 [error] 9159#0: *7 directory index of "/srv/web/" is forbidden, client: 127.0.0.1, server: _, request: "GET / HTTP/1.1", host: "localhost"

Not sure why this is failing, but it smells like progress at least.

решение1

Multiple roots won't work like that

With this config:

server {
    # root /;
    index index.php index.html index.htm;
    try_files /srv/web/$uri /srv/php/$uri =404;

There is no request processing that would use the index directive, as written the request must match a file. Using the debug log confirms this:

2015/08/24 08:12:11 [debug] 17173#0: *26 try files phase: 13
2015/08/24 08:12:11 [debug] 17173#0: *26 http script copy: "/srv/web/"
2015/08/24 08:12:11 [debug] 17173#0: *26 http script var: "/"
2015/08/24 08:12:11 [debug] 17173#0: *26 trying to use file: "/srv/web//" "/srv/web//"
2015/08/24 08:12:11 [debug] 17173#0: *26 http script copy: "/srv/php/"
2015/08/24 08:12:11 [debug] 17173#0: *26 http script var: "/"
2015/08/24 08:12:11 [debug] 17173#0: *26 trying to use file: "/srv/php//" "/srv/php//"
2015/08/24 08:12:11 [debug] 17173#0: *26 trying to use file: "=404" "=404"

Using a try_files directive that does look for directories like this:

try_files /srv/web/$uri /srv/web/uri/ /srv/php/$uri /srv/php/$uri/ =404;

также не работает:

2015/08/24 08:16:17 [debug] 17651#0: *33 http script copy: "/srv/web/"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script var: "/srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use file: "/srv/web//srv/web//index.html" "/srv/web//srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script copy: "/srv/web/"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script var: "/srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use dir: "/srv/web//srv/web//index.html" "/srv/web//srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script copy: "/srv/php/"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script var: "/srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use file: "/srv/php//srv/web//index.html" "/srv/php//srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script copy: "/srv/php/"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script var: "/srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use dir: "/srv/php//srv/web//index.html" "/srv/php//srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use file: "=404" "=404"

Обратите внимание, что "корень" сбит с толку, try_filesожидает URL, а не путь к файлу. Я предлагаю не продолжать попытки использовать решение такого рода - особеннонетустановка корня как /ипотенциальноразрешение доступа к любому файлу на сервере.

Используйте два блока локаций

Вместо этого сохраняйте простоту. Эта конфигурация будет обслуживать весь статический контент:

    root /srv/web;
    index index.html;
    try_files $uri $uri/;

Эта конфигурация обслуживает весь PHP-контент:

    root /srv/php;
    index index.php;
    try_files $uri $uri/;

Просто сложите их вместе:

location / {
    root /srv/web;
    index index.html;
    try_files $uri $uri/ @php;
    error_page 403 = @php; # see note below
}

location @php {
    root /srv/php;
    index index.php;
    try_files $uri $uri/ =404;
}

location ~ \.php$ {
    # as before
}

Одна загвоздка в том, что при такой настройке запрос, который соответствует папке, в /srv/webкоторой находитсяне делаетесть index.htmlфайл, выдаст ошибку 403 (так как запрос относится к каталогу, а индексного файла каталога нет). Чтобы разрешить обработку этих запросов php - необходимо перенаправить ошибки 403 в обработчик php.

Связанный контент