Nginx: cambiar la carpeta raíz para una URL específica genera un error 404

Nginx: cambiar la carpeta raíz para una URL específica genera un error 404

Estoy tratando de organizar un bloque de ubicación para que cualquiera pueda acceder a mydomain.com/game/adminla URL, asegurarme de que el servidor nginx para extraer el contenido exista en /var/www/html/my-cakephp-app/el directorio. Mi aplicación está construida utilizando el marco cakephp y su estructura de directorios se muestra a continuación:

  • /var/www/html/my-cakephp-app/
    • administración
      • configuración
      • Consola
      • Controlador
      • Vista
      • webroot (el archivo index.php del punto de entrada de la aplicación existe en este directorio)

También tengo un sitio web estático html/css ubicado en el /var/www/htmldirectorio. Entonces, cualquiera que tenga mydomain.comuna URL también podrá ver ese sitio web.

Aquí está mi bloque de servidor nginx actual:

server {
    listen 80;
    listen [::]:80;

    root /var/www/html;

    index index.html index.htm index.php;

    server_name mydomain.com;

    location / {
        try_files $uri $uri/ =404;
    }
    
    location /game/admin {
            return 301 /game/admin/;
    }

    location /game/admin/ {

                root /var/www/html/my-cakephp-app/admin/webroot;
                try_files $uri $uri/ /game/admin/index.php$is_args$args;
  
                location ~* \.php(/|$) {
                  include snippets/fastcgi-php.conf;
                  fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
                  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
               } 

    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Con esta configuración, mi sitio web estático funciona bien. Pero la aplicación cakephp muestra el error 404 no encontrado en el navegador. No hay errores en nginx/error.log.

Pero cuando ejecuto con la siguiente configuración de nginx, mi aplicación funciona bien. Pero tengo que deshacerme de mi sitio html/css. Estoy planeando actualizar la aplicación html/css con un sitio de wordpress. Por lo tanto, debería poder ejecutar el sitio de WordPress como padre.

server {
    listen 80;
    server_name mydomain.com;
    root /var/www/html/my-cakephp-app/admin/webroot;
    
    index index.html index.htm index.php;
 
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
        autoindex on;
    }
    
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }
    
    location ~ /\.ht {
        deny all;
    }
}

No podía pensar en qué hice mal con el primer bloque del servidor. Cualquier sugerencia sería realmente útil.

Respuesta1

Los dos problemas principales son:

  • el bloque exterior location ~ \.php$tiene prioridad sobre el location /game/admin/bloque a menos que use el ^~modificador (vereste documentopara detalles)
  • la rootdirectiva genera una ruta al archivo mediante concatenación simple, por lo que se espera que su controlador esté ubicado en /var/www/html/my-cakephp-app/admin/webroot/game/admin/index.php(consulteeste documentopara detalles)

Una opción es mover el proyecto para que la estructura del directorio coincida con la estructura del URI. Esto podría lograrse utilizando un enlace simbólico que apunte /var/www/html/game/admina, /var/www/html/my-cakephp-app/admin/webrooten cuyo caso, el bloque externo location ~ \.php$podrá ejecutar ambos proyectos.


Otra opción es la aliasdirectiva. Vereste documentopara detalles.

location ^~ /game/admin {
    alias /var/www/html/my-cakephp-app/admin/webroot;

    if (!-e $request_filename) { rewrite ^ /game/admin/index.php last; }

    location ~ \.php$ {
        if (!-f $request_filename) { return 404; }

        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $request_filename;
    }
}

Tenga en cuenta que $document_root$fastcgi_script_nameno funcionará aliasy $request_filenamedebería usarse en su lugar.

Evito usar aliasy try_filesjuntos debido aeste problema. Veresta precauciónsobre el uso de la ifdirectiva.

información relacionada