Múltiples directorios de archivos estáticos, único servidor PHP FPM

Múltiples directorios de archivos estáticos, único servidor PHP FPM

Tengo dos directorios desde los cuales necesito servir activos estáticos:

  1. /srv/web: Activos estáticos que incluyen imágenes, JavaScript, HTML, etc.
  2. /srv/php: scripts PHP dinámicos junto con algunos activos estáticos.

Estoy usando NGINX y lo configuré así:

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;
    }
}

Estoy en Ubuntu 14.04, la versión del paquete PHP FPM es 5.5.9, la versión del paquete NGINX es 1.4.6.

El objetivo simple aquí es servir archivos estáticos desde el /srv/webprincipio; en su /srv/phpdefecto, devolver 404. Todos los archivos que terminen en \.php$se solicitarán desde PHP FPM a través del socket Unix, y esto está funcionando.

El problema que tengo actualmente es que la indexdirectiva sobre el serverno está funcionando según lo previsto. Tengo un index.htmlarchivo en /srv/web, y cuando lo hago

curl -is http://localhost/

Obtengo un 404.

¿Es esta la forma más ideal de configurar un sitio NGINX con múltiples carpetas del sistema de archivos para servir junto con PHP? ¿Alguna idea de por qué mi índice estático no funciona?


Actualizar

Según la respuesta de AD7six a continuación, actualicé mi configuración para que se vea así:

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;
    }
}

La lista de mi directorio se ve así:

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

3 directories, 5 files

Obtener archivos estáticos y archivos PHP funciona según lo planeado y obtener /subdir/su índice funciona bien, pero si GET /, obtengo un 403 prohibido y nginx se queja del listado de directorios:

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"

No estoy seguro de por qué esto está fallando, pero al menos huele a progreso.

Respuesta1

Varias raíces no funcionarán así

Con esta configuración:

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

No hay ningún procesamiento de solicitudes que utilice la directiva de índice, tal como está escrita, la solicitud debe coincidir con un archivo. El uso del registro de depuración confirma esto:

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"

Usando una try_filesdirectiva que busca directorios como este:

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

tampoco funciona:

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"

Tenga en cuenta que la "raíz" está confundida,try_files espera una URL, no una ruta de archivo. Sugiero no seguir intentando utilizar una solución de este tipo, especialmentenoestableciendo la raíz como/ ypotencialmentepermitiendo el acceso a cualquier archivo del servidor.

Utilice dos bloques de ubicación

En lugar de eso, mantenga las cosas simples. Esta configuración servirá todo el contenido estático:

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

Esta configuración sirve todo el contenido php:

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

Simplemente júntelos:

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
}

Un problema es que con este tipo de configuración una solicitud que coincide con una carpeta en/srv/web la quenotener un index.htmlarchivo arrojará un error 403 (ya que la solicitud es para un directorio y no hay ningún archivo de índice de directorio). Para permitir que php también maneje estas solicitudes, es necesario redirigir los errores 403 al controlador de php.

información relacionada