foaly
foaly

Reputation: 352

nginx rewrite rules by subdirectory

I am trying to achieve the following result with an nginx configuration:

A PHP app is running in a subdirectory of a server, lets say server.com/app/. Files in images/ and styles/ (for example) should be accessible, php files in api/ should be executed, and in all other cases nginx should pass the whole string after app/ to PHP as a GET variable, say path.

I really have no clue what I am doing here, and I can not seem to find anything useful for this on the web, so if you can chip in, thank you.

I am running php5-fpm currently like this:

location /app {
    index index.html index.php;

    access_log /{...}/access.log;
    error_log /{...}/error.log;

    location ~ \.php {
        try_files $uri = 404;
        fastcgi_pass php5-fpm-sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Please ask if you need any more details.

EDIT

For now I found that this works

location /{path}/ {    
        index index.php;

        access_log /{path}/access.log;
        error_log /{path}/error.log;

        location ~\.php {
            try_files $uri = 404;
            fastcgi_pass php5-fpm-sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }   

        location ~ { 
            try_files $uri $uri/ /{path}/index.php?path=$uri;
        }

    }   

However I am worried that this might allow unwanted file access. Any comments?

Upvotes: 2

Views: 391

Answers (1)

Kyle
Kyle

Reputation: 4445

You can probably simplify it by moving the try_files directive out of the location sub-block so that your config file ends up looking like:

location /app {    
    index index.php;
    try_files $uri $uri/ /app/index.php?path=$uri;

    access_log /{path}/access.log;
    error_log /{path}/error.log;

    location ~\.php {
        try_files $uri =404;
        fastcgi_pass php5-fpm-sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

}

The key thing is the try_files directive - nginx will try each location in the order specified. $uri looks for a file matching the exact path specified (so /api/random.php loads correctly because it's a file), $uri/ looks for a folder matching the path, and attempts to load the index from the folder, and finally /app/index.php?path=$uri loads the page /app/index.php. This is then picked up by the location ~\.php block and passed to php-fpm.

The main thing I'd be concerned about is that your access and error.log files would be publicly accessible by virtue of being stored in the web directory. If possible, shift them somewhere else (like /var/log maybe?)

Upvotes: 1

Related Questions