
I have two directories which I need to serve static assets out of:
/srv/web
: Static assets which include images, JavaScript, HTML, etc./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.