NGINX try_files + alias directives

2020-02-16 07:49发布

I'm trying to serve request to /blog subdirectory of a site with the php code, located in a folder outside document root directory. Here's my host config:

server {
    server_name  local.test.ru;
    root   /home/alex/www/test2;

    location /blog {
        alias   /home/alex/www/test1;
        try_files $uri $uri/ /index.php$is_args$args;

        location ~ \.php$ {
            fastcgi_split_path_info ^(/blog)(/.*)$;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            include fastcgi_params;
        }
    }
}

And I get for requests like

wget -O - http://local.test.ru/blog/nonExisting

just a code of index.php file from /home/alex/www/test2/ folder.

However, this config:

server {
    server_name  local.test.ru;
    root   /home/alex/www/test2;

    location /blog {
        alias   /home/alex/www/test1;
        try_files $uri $uri/ /blog$is_args$args;
        index index.php;

        location ~ \.php$ {
            fastcgi_split_path_info ^(/blog)(/.*)$;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            include fastcgi_params;
        }
    }
}

gives me index.html file from /home/alex/www/test2/. Please give me a clue - why? And how can I force NGINX to process /home/alex/www/test1/index.php instead?

标签: nginx
3条回答
疯言疯语
2楼-- · 2020-02-16 08:21

This is a long standing bug in nginx. But you can work around by using the root directive again. Kind of a hack, but at least it works.

server {
    index       index.php;
    root        /home/alex/www/test2;
    server_name local.test.ru;

    location /blog {
        root      /home/alex/www/test1;
        try_files $uri $uri/ /blog$is_args$args;
    }
}
查看更多
叼着烟拽天下
3楼-- · 2020-02-16 08:22

We could not get it to work by specifying root within the location block. The solution for us was to use alias instead. Note that it is necessary repeat the location's path twice in the try_files directive, and then also in the .php configuration block:

server {
    server_name localhost;
    root /app/frontend/www;

    location /backend/ {

        alias /app/backend/www/;

        # serve static files direct + allow friendly urls
        # Note: The seemingly weird syntax is due to a long-standing bug in nginx: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /backend//backend/index.php?$args;

        location ~ /backend/.+\.php$ {
            include fastcgi_params;
            fastcgi_buffers 256 4k;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_param HTTPS $proxied_https;
            fastcgi_pass phpfiles;
        }

    } # / location

}

Source: nginx/conf.d/app.conf from the debian-php-nginx stack in the docker-stack project

查看更多
▲ chillily
4楼-- · 2020-02-16 08:41

There is another workaround which gives more flexibility. It consists of a proxy_pass directive which points on 127.0.0.1 and another server block.

In your case it should looks like this:

upstream blog.fake {
    server 127.0.0.1;
}
server {
    server_name local.test.ru;
    root /home/alex/www/test2;
    index index.html;

    location /blog {
        proxy_pass http://blog.fake/;
    }
}
server {
    server_name blog.fake;
    root /home/alex/www/test1;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php(/|$) {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
    }
}
查看更多
登录 后发表回答